合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
>[info] 如何保证消息的100%接收(一) **Producer 的可靠性投递要求** * 保证消息的成功发出 * 保证MQ节点的成功接收 * 发送端收到MQ节点(Broker) 确认应答 * 完善的消息补偿机制 ***** **解决方案:** 方案一:消息信息落库,对消息状态进行打标 (常见方案) * 将消息持久化到DB并设置状态值,收到Consumer的应答就改变当前记录的状态. * 再轮询重新发送没接收到应答的消息,注意这里要设置重试次数. **方案流程图:** 状态为:0 发送失败 1 发送成功 ![![](https://img.kancloud.cn/1b/b4/1bb46c66541b5cf90a9d49a4982cb754_1028x580.png)](images/screenshot_1627025877313.png) **方案实现流程:** 比如我下单成功 * step1 - 对订单数据入BIZ DB订单库,并对因此生成的业务消息入MSG DB消息库 此处由于采用了两个数据库,需要两次持久化操作,为了保证数据的一致性,有人可能就想着采用分布式事务,但在大厂实践中,基本都是采用补偿机制! >[] 这里一定要保证step1 中消息都存储成功了,没有出现任何异常情况,然后生产端再进行消息发送。如果失败了就进行快速失败机制 对业务数据和消息入库完毕就进入 * setp2 - 发送消息到 MQ 服务上,如果一切正常无误消费者监听到该消息,进入 * step3 - 生产端有一个 Confirm Listener ,异步监听Broker回送的响应,从而判断消息是否投递成功 * step4 - 如果成功,去数据库查询该消息,并将消息状态更新为1 * step5 - 如果出现意外情况,消费者未接收到或者 Listener 接收确认时发生网络闪断,导致生产端的Listener就永远收不到这条消息的confirm应答了,也就是说这条消息的状态就一直为0了,这时候就需要用到我们的 分布式定时任务来从 MSG 数据库抓取那些超时了还未被消费的消息,重新发送一遍 此时我们需要设置一个规则,比如说消息在入库时候设置一个临界值timeout,5分钟之后如果还是0的状态那就需要把消息抽取出 来。这里我们使用的是分布式定时任务,去定时抓取DB中距离消息创建时间超过5分钟的且状态为0的消息。 * step6 - 把抓取出来的消息进行重新投递(Retry Send),也就是从第二步开始继续往下走 * step7 - 当然有些消息可能就是由于一些实际的问题无法路由到Broker,比如routingKey设置不对,对应的队列被误删除了,那么这种消息即使重试多次也仍然无法投递成功,所以需要对重试次数做限制,比如限制3次, 如果投递次数大于三次,那么就将消息状态更新为2,表示这个消息最终投递失败,然后通过补偿机制,人工去处理。实际生产中,这种情况还是比较少的,但是你不能没有这个补偿机制,要不然就做不到可靠性了。 ***** **优缺点:** * 缺点是:生产者在第一步需要更新或者插入操作数据库,生产监听器,对用户体验下降。 * 在大厂中 都不会加事务,都是进行的补偿操作。 * 优化:不需要消息进行持久化 只需要业务持久化