消息如何保障100%的投递成功?
日期: 2020-01-29 分类: 个人收藏 386次阅读
什么是生产端的可靠性投递?
- 保障消息的
成功发出
- 保障MQ节点的
成功接收
- 发送端收到MQ节点(Broker)
确认应答
- 完善的消息
补偿机制
BAT/TMD互联网大厂的解决方案:
- 消息落库,对消息状态进行变更
- 消息的延迟投递,做二次确认,回调检查
方案一:消息落库,对消息状态进行变更
- Step1:进行订单数据入业务库,同时插入一条消息数据入消息库,此时数据状态
status为0
- Step2:发送消息
- Step3:服务器发送消息确认
- Step4:生产者监听器监听到了消息确认,这时候更改消息库数据状态
status为1
- Step5:分布式定时任务会定时查询消息库状态status为0的数据(说明数据未可靠发送,发送失败或者接收确认失败)
- Step6:将状态status为0的数据进行二次重试发送,每重试一次
次数加1
- Step7:如果重试次数超过3次,则将消息库数据状态
status改为2
,数据状态status为2的数据只能通过人工去排查问题
思考:上面这种可靠性投递,在高并发的场景下是否合适?
其实很明显,高并发场景下是有性能瓶颈的,每次消息的推送都需要多一次的入库(数据入消息库),带来多一次的磁盘IO消耗
。由于有性能的限制,我们来看第二种方案,消息的延迟投递,做二次确认,回调检查。
方案二:消息的延迟投递,做二次确认,回调检查
- Step1:首先对业务订单数据落库,再发送消息到消息服务器
- Step2:第一次发送消息几分钟之后重新发送该消息,目的是做
confirm消息确认检查
(延迟投递) - Step3:下游服务监听消息,进行消费
- Step4:接收到消息之后会发送一个confirm确认消息到服务器
- Step5:回调服务会监听下游服务发送的确认消息,监听到之后会落入消息库
- Step6:几分钟之后,Step2发送了消息确认数据,回调服务接收到了该消息,会和消息库中的消息进行一个比对检查,假如消息库中没有该消息的确认,回调服务就会发起一个ReSend Command命令,通知上游服务
重新发送一次消息
。
思考:这种方案和上一种方案的区别是什么呢?
其实也很明显啊,对于主业务流程来说,他只有一条线,就是业务数据落库,然后发送消息到服务器,少了消息库的插入。这个方案把消息库的操作都给了回调服务,而回调服务是一种补偿服务,完全可以异步去处理
,不影响主业务进程,性能就提高了。
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
精华推荐