RabbitMQ(五)消息发送失败后的处理

前一篇文章,写了消息发送确认的一些内容.

就是消息发送成功或失败的时候,都会调用confirmListener 或者returnListener.

如果消息发送成功,就不考虑了.当消息发送失败时,怎么处理这个消息呢.

1.自动重发

2.系统预警人工处理等


以上操作,都需要知道是哪条消息,具体什么内容发送失败了,才能进行后续处理.

在returnListener中,参数是有消息内容,exchange,routingKey 这些内容的.

但是在confirmListener中,却是什么都没有,只有个correlationData,而我们打印出的correlationData都是null


看来问题的关键就在这个correlationData上了, CorrelationData类只有一个属性ID, 很明显,我们在发送消息时,将消息和correlationData的ID做一个绑定,就可以根据id拿到消息. 然后进行重发,报警等操作了.


到发送消息的类里面, 发现AmqpTemplate 里面竟然没有和CorrelationData相关的方法,没办法把CorrelationData.id和消息进行绑定..

原来需要使用RabbitTemplate 而不是 AmqpTemplate 类偷笑



找到方法后,下面就非常简单了.

@Service("rabbitTemplatePublishService")
public class RabbitTemplatePublishService {
	@Autowired
	private RabbitTemplate rmqpTemplate;

	public void send(String exchange, String routingKey, Object obj) {
		String msgId = UUID.randomUUID().toString();
		Message message = MessageBuilder.withBody(obj.toString().getBytes())
				.setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN)
				.setCorrelationId(msgId.getBytes()).build();
		CorrelationData date = new CorrelationData(msgId);
		// TODO 将 msgId 与 message 的关系保存起来,例如放到缓存中
		rmqpTemplate.send(exchange, routingKey, message, date);
	}
}



上面的代码,message中,也可以setCorrelationId为自己指定的id,这样方便confirm和return一起处理.


上面将msgId和message关系保存后, 在confirmListener或者returnListener中,就可以根据msgId获取message进行对于操作.



上面的思路看起来解决了失败后消息处理的问题.但是实际上却是不可靠的尴尬


3.如果进行confirm的时候,或者return的时候, 失败了怎么办?  

4.msgId和message的关系要保存多久?


但是上面的思路已经抓到了问题的重点,即msgId和message做绑定.

针对3,4两个问题,只需要变通下即可解决


方案如下:

发送消息前,绑定并保存msgId和message的关系

当confirm或return回调时,根据ack类别等,分别处理. 例如return或者ack=false则说明有问题,报警, 如果ack=true则删除关系

(因为return在confirm前,所以一条消息在return后又ack=true的情况也是按return处理)


定时检查这个绑定关系列表,如果发现一些已经超时(自己设定的超时时间)未被处理(即未return和confirm),则手动处理这些消息.


至此,发送消息基本已经没问题了.

需要注意如果是自动重发的话,消费端需要做幂等或去重处理.




相关推荐

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

北京-小北

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值