mq 提供了两种方式确认消息的可靠投递

  • confirmCallback 确认模式
  • returnCallback 未投递到 queue 退回模式

在使用 RabbitMQ 的时候,作为消息发送方希望杜绝任何消息丢失或者投递失败场景。RabbitMQ 为我们提供了两个选项用来控制消息的投递可靠性模式。

rabbitmq 整个消息投递的路径为:
producer->rabbitmq broker cluster->exchange->queue->consumer

message 从 producer 到 rabbitmq broker cluster 则会返回一个 confirmCallback 。
message 从 exchange->queue 投递失败则会返回一个 returnCallback 。我们将利用这两个 callback 控制消息的最终一致性和部分纠错能力。

对于消息异常,可以使用以下方法进行解决

  1. 使用RepublishMessageRecoverer这个MessageRecoverer会发送发送消息到指定队列
  2. 给队列绑定死信队列,因为默认的RepublishMessageRecoverer会发送nack并且requeue为false。这样抛出一场是这种方式和上面的结果一样都是转发到了另外一个队列。详见DeadLetterConsumer
  3. 注册自己实现的MessageRecoverer
  4. 给MessageListenerContainer设置RecoveryCallback
  5. 对于方法手动捕获异常,进行处理
rabbitTemplate的发送流程是这样的:
1 发送数据并返回(不确认rabbitmq服务器已成功接收)
2 异步的接收从rabbitmq返回的ack确认信息
3 收到ack后调用confirmCallback函数
注意:在confirmCallback中是没有原message的,所以无法在这个函数中调用重发,confirmCallback只有一个通知的作用。

最安全的做法是是使用事务,但是这样效率就会很低,每秒钟处理的message在几百条左右。对于高性能的 mq 来说是非常不可取的。

另一种解决方法如下:在rabbitTemplate异步确认的基础上
1 在本地缓存已发送的 message
2 通过 confirmCallback 或者被确认的 ack,将被确认的message从本地删除
3 定时扫描本地的message,如果大于一定时间未被确认,则重发

这种解决方式也有一定的问题
想象这种场景,rabbitmq接收到了消息,在发送ack确认时,网络断了,造成客户端没有收到ack,重发消息。(相比于丢失消息,重发消息要好解决的多,我们可以在consumer端做到幂等)。

参考文献:

https://segmentfault.com/a/1190000016041620

https://www.jianshu.com/p/6579e48d18ae

https://github.com/littlersmall/rabbitmq-access/blob/master/src/main/java/com/littlersmall/rabbitmqaccess/MQAccessBuilder.java

https://www.jianshu.com/p/6579e48d18ae

最新文章

  1. VIP
  2. iOS上架90034问题解决
  3. vs2015密钥 企业版 专业版 (vs.net)
  4. 【bzoj2809】[Apio2012]dispatching 左偏树
  5. C#和Javascript中 正则表达式使用的总结
  6. Centos JAVA Eclipse
  7. ScrollView与ListView合用(正确计算Listview的高度)的问题解决
  8. 我和小美的撸码日记--基于MVC+Jqgrid的.Net快速开发框架
  9. Cocos2d-X 使用CCTableView创建滚动视图
  10. hdu 4445 Crazy Tank (暴力枚举)
  11. Spring (三)
  12. C#生成缩略图 (通用模式)
  13. ORACLE如何检查找出损坏索引(Corrupt Indexes)
  14. TJOI2010中位数
  15. 关于golang.org/x包问题
  16. 点击a标签不跳转的办法
  17. erlang 笔记(06/03/02)
  18. vue 如何在循环中绑定v-model
  19. 这些linux技巧大大提高你的工作效率
  20. java用正则方法验证文件名是否合法

热门文章

  1. window 删除文件提示指定的文件名无效或太长
  2. position:fixed;如何居中
  3. VS code deploy同步服务器代码
  4. GoWeb开发_Iris框架讲解(三):路由功能处理方式
  5. bzoj 3722: PA2014 Final Budowa
  6. hdu 4388 Stone Game II
  7. 洛谷P1314 聪明的质监员
  8. JSONObject,JSONArray,String,Map间的互转
  9. Spring Boot整合实战Spring Security JWT权限鉴权系统
  10. SQL语法:MySQL系列之四