上面文章说到,SpringBoot集成RabbitMQ后手动签收失败无法保证重试3次之后进入死信队列,这种情况就可以自己实现一个。大致的思路如下
类似于做一个计数器的功能,首先要为每个消息设置一个id,然后放入到Map结构中(java的Map或者Redis等都可以),结构是
private MapcounterMap=new ConcurrentHashMap<>(); @RabbitListener(queues = RabbitMQStudentCourseTopicConfig.QUEUE) public void doChooseCourse(Message message, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel)throws IOException{ MqMessage mqMessage = MessageHelper.msgToObj(message, MqMessage.class); //选择studentId作为msg的id,为value赋值 Integer integer = counterMap.get(mqMessage.getStudentId()); if (integer==null){ counterMap.put(mqMessage.getStudentId(), 1); }else{ counterMap.put(mqMessage.getStudentId(),integer.intValue() + 1); } log.info("重试次数:{}",counterMap.get(mqMessage.getStudentId())); try{ int i = 5/0; }catch (Exception e){ if (counterMap.get(mqMessage.getStudentId())>=3){ //第三个false:失败不重回队列 channel.basicNack(deliveryTag,false,false); counterMap.remove(mqMessage.getStudentId()); } channel.basicNack(deliveryTag,false,true); return; } log.info("消费成功"); }
测试结果如下



