在MQ的使用中我遇到了一个奇怪的BUG,在之前的MQ消费消息可靠性中我说,如果队列中的消息被监听者消费出异常,在你自己未配置的情况下,生产者会不断地向消费者发消息,这就会导致出现类似死循环一样地BUG,而我遇到了一个在MQ数据传输间的BUG。
首先我们确保生产者消费者间的数据传输有格式化:配置如下:
@Configuration
public class MesaageConfig {
@Bean
public MessageConverter messageConverter() {// 定义消息转换器Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();//设置消息id,自动生成一个id,可用于消息幂等性处理jackson2JsonMessageConverter.setCreateMessageIds(true);return jackson2JsonMessageConverter;
}
}
并且确保有以下依赖
接下来我大概描述我的业务,我的一个生产者需要传输一个Long类型的数据和Set类型的数据,而我选择的方法是将俩种封装到Map<String,Object>中,这样可以保证数据的一次性传输,然后我在消费者那边接到了数据并且正确得打印了出来,但是在接收时确猛报BUG,经过我打一遍遍DEBUG与断点调试,最好发现,传输过来得Long类型变成了Integer类型,你拿Map.get接收时只能能Integer去接收,而Set在传过来时也只能拿List去接不然就报错,有需求只能在接收后强转,以下是我的BUG代码,大家注意注意这个小坑!
生产者:
Map<String ,Object> map=new HashMap<>();
Long orderId =UserContext.getUser();
map.put("orderId",orderId);
map.put("itemIds",itemIds);
System.out.println(map);
rabbitTemplate.convertAndSend("trade.topic","order.create",map);
监听者:
@Autowired
private ICartService cartService;
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "cart.clear.queue"),
exchange = @Exchange(name = "trade.topic", type = ExchangeTypes.TOPIC),
key = {"order.create"}
)
)
public void handleTradePaySuccessQueue(Map<String,Object> map){
log.warn("收到订单创建成功消息,订单号为{}",map);
Integer orderId = (Integer) map.get("orderId");
log.warn("orderId={}",orderId);
List
log.warn("itemIds={}",itemIds);
cartService.removeByItemIdsAndUserId(Long.valueOf(orderId), itemIds);
}