Appearance
我们在RabbitMQConfig中将交换机名称以及队列名称都定死了,那么我们此时如果有多个业务都需要用到MQ,例如用户下单时需要超时关单,用户退款时需要回退优惠券,这些业务该怎样处理呢?
核心就是我们需要让监听器能够判断出当前是什么消息,已知交换机名称以及队列名称在当前配置下是无法更改的,那么我们需要一个“动态参数”来标明传递过来的是什么参数,我想到的有两种方案。
- 消息体携带信息,判断当前是超时关单的消息还是回退优惠券的消息,然后再来处理业务逻辑
- 交换机名称以及队列名称是不变的,但是“路由键”是变化的,我们可以根据路由键来判断消息类型
- 投递到新的队列中去,把不同的消息投递到不同的队列,点击查看详细配置
消息体携带信息判断当前消息类型
创建消息类,用于发送和接收消息,注意要实现Serializable
接口,不实现会报错哦。
java
@Data
public class CommonMQMsg implements Serializable {
private String type;
private String msg;
}
先来看发送消息,发送CommonMQMsg
对象构成的数据。
java
@SpringBootTest
class RabbitmqDemoApplicationTests {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
void send() {
CommonMQMsg msg = new CommonMQMsg();
msg.setType("order.refund");
msg.setMsg("新订单来啦!!");
rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME, "order.new", msg);
}
}
再来看接收消息,使用 CommonMQMsg
接收消息,框架会自动帮我们转换消息格式。
java
@Component
@RabbitListener(queues = "order_queue") // 监听的队列名称
public class OrderMQListener {
@RabbitHandler
public void releaseCouponRecord(CommonMQMsg commonMQMsg, Message message) throws IOException {
if ("order.new".equals(commonMQMsg.getType())) {
log.info("处理新订单逻辑");
} else if ("order.refund".equals(commonMQMsg.getType())){
log.info("处理退款逻辑");
}
}
}
根据routingKey判断当前消息类型
先来看消息的发送,order.new
就是我们这里的路由Key
java
@Test
void send() {
rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME, "order.new", "新订单来啦!!");
}
再来看消息消费者的监听,是如何判断的
java
@Component
@RabbitListener(queues = "order_queue") // 监听的队列名称
public class OrderMQListener {
@RabbitHandler
public void releaseCouponRecord(String msg, Message message) throws IOException {
// 获取路由Key
final String routingKey = message.getMessageProperties().getReceivedRoutingKey();
if ("order.new".equals(routingKey)) {
// TODO 处理新订单逻辑
} else if ("order.refund".equals(routingKey)){
// TODO 处理退款逻辑
}
}
}
说明:这个路由键例如order.new
,这些数据建议再项目中使用常量去提前定义,我这里为了讲解清晰就没写了。