RabbitMQ如何保证消息的可靠性投递
目前来说,现在有两种方案实施:
1.数据库持久化方案
2.消息延迟投递方案
数据库持久化方案
![数据库持久化方案流程图](https://img-blog.csdnimg.cn/20190516174020678.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE4NDgzMzAx,size_16,color_FFFFFF,t_70)
流程:
1.将业务订单数据和生成的Message进行持久化操作(一般情况下插入数据库,这里如果分库的话可能涉及到分布式事务)
2.将Message发送到Broker服务器中
3.通过RabbitMQ的Confirm机制,在producer端,监听服务器是否ACK。
4.如果ACK了,就将Message这条数据状态更新为已发送。如果失败,修改为失败状态。
5.分布式定时任务查询数据库3分钟(这个具体时间应该根据的时效性来定)之前的发送失败的消息
6.重新发送消息,记录发送次数
7.如果发送次数过多仍然失败,那么就需要人工排查之类的操作。
优点:
能够保证消息百分百不丢失
缺点:
1.第一步中涉及到分布式事务问题,分布式事务一点会降低时效性(据说互联网大厂一般不会使用分布式事务)。
2.
消息延迟投递方案(据说互联网大厂使用该方案)
![消息延迟投递方案](https://img-blog.csdnimg.cn/20190516174053409.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE4NDgzMzAx,size_16,color_FFFFFF,t_70)
流程:
流程图中,颜色不同的代表不同的message
1.将业务订单持久化
2.发送一条Message到broker(称之为主Message),再发送相同的一条到不同的队列或者交换机(这条称为确认Message)中。
3.主Message由实际业务处理端消费后,生成一条响应Message。之前的确认Message由Message Service应用处理入库。
4~6.实际业务处理端发送的确认Message由Message Service接收后,将原Message状态修改。
7.如果该条Message没有被确认,则通过rpc调用重新由producer进行全过程。
优点:
1.相对于数据库持久化方案来说响应速度有所提升
缺点:
1.系统复杂性有点高
2.万一两条消息都失败了,消息存在丢失情况,仍需Confirm机制做补偿