美文网首页
MQ异步发送,那消息可靠性怎么保证?

MQ异步发送,那消息可靠性怎么保证?

作者: 嘘寒问暖 | 来源:发表于2022-05-22 22:27 被阅读0次

消息丢失可能发⽣在⽣产者发送消息、MQ本身丢失消息、消费者丢失消息3个⽅⾯。

⽣产者丢失

⽣产者丢失消息的可能点在于程序发送失败抛异常了没有重试处理,或者发送的过程成功但是过程中⽹络闪断MQ没收到,消息就丢失了。由于同步发送的⼀般不会出现这样使⽤⽅式,所以我们就不考虑同步发送的问题,我们基于异步发送的场景来说。

异步发送分为两个⽅式:异步有回调和异步⽆回调,⽆回调的⽅式,⽣产者发送完后不管结果可能就会造成消息丢失,⽽通过异步发送+回调通知+本地消息表的形式我们就可以做出⼀个解决⽅案。以下单的场景举例。

1. 下单后先保存本地数据和MQ消息表,这时候消息的状态是发送中,如果本地事务失败,那么下单失败,事务回滚。

2. 下单成功,直接返回客户端成功,异步发送MQ消息

3. MQ回调通知消息发送结果,对应更新数据库MQ发送状态

4. JOB轮询超过⼀定时间(时间根据业务配置)还未发送成功的消息去重试

5. 在监控平台配置或者JOB程序处理超过⼀定次数⼀直发送不成功的消息,告警,⼈⼯介⼊。

⼀般⽽⾔,对于⼤部分场景来说异步回调的形式就可以了,只有那种需要完全保证不能丢失消息的场景我们做⼀套完整的解决⽅案。

MQ丢失

如果⽣产者保证消息发送到MQ,⽽MQ收到消息后还在内存中,这时候宕机了⼜没来得及同步给从节点,就有可能导致消息丢失。

⽐如RocketMQ:

RocketMQ分为同步刷盘和异步刷盘两种⽅式,默认的是异步刷盘,就有可能导致消息还未刷到硬盘上就丢失了,可以通过设置为同步刷盘的⽅式来保证消息可靠性,这样即使MQ挂了,恢复的时候也可以从磁盘中去恢复消息。

⽐如Kafka也可以通过配置做到:

acks=all 只有参与复制的所有节点全部收到消息,才返回⽣产者成功。这样的话除⾮所有的节点都挂 了,消息才会丢失。 replication.factor=N,设置⼤于1的数,这会要求每个partion⾄少有2个副本 min.insync.replicas=N,设置⼤于1的数,这会要求leader⾄少感知到⼀个follower还保持着连 接 retries=N,设置⼀个⾮常⼤的值,让⽣产者发送失败⼀直重试

虽然我们可以通过配置的⽅式来达到MQ本身⾼可⽤的⽬的,但是都对性能有损耗,怎样配置需要根据业务做出权衡。

消费者丢失

消费者丢失消息的场景:消费者刚收到消息,此时服务器宕机,MQ认为消费者已经消费,不会重复发送消息,消息丢失。

RocketMQ默认是需要消费者回复ack确认,⽽kafka需要⼿动开启配置关闭⾃动offset。

消费⽅不返回ack确认,重发的机制根据MQ类型的不同发送时间间隔、次数都不尽相同,如果重试超过次数之后会进⼊死信队列,需要⼿⼯来处理了。(Kafka没有这些)

相关文章

网友评论

      本文标题:MQ异步发送,那消息可靠性怎么保证?

      本文链接:https://www.haomeiwen.com/subject/bielprtx.html