当前位置:   article > 正文

MQ 幂等性_mq幂等性

mq幂等性

一、出现非幂等性的情况

1、生产者已把消息发送到mq,在mq给生产者返回ack的时候网络中断,故生产者未收到确定信息,生产者认为消息未发送成功,但实际情况是,mq已成功接收到了消息,在网络重连后,生产者会重新发送刚才的消息,造成mq接收了重复的消息

2、消费者在消费mq中的消息时,mq已把消息发送给消费者,消费者在给mq返回ack时网络中断,故mq未收到确认信息,该条消息会重新发给其他的消费者,或者在网络重连后再次发送给该消费者,但实际上该消费者已成功消费了该条消息,造成消费者消费了重复的消息;

二、MQ内部如何做到幂等性的

对于每条消息,MQ内部会为每条消息生成一个全局唯一、与业务无关的消息id:inner-msg-id,当MQ-Server接收到消息时,会先根据该id判断消息是否重复发送,mq再决定是否接收该消息。如果业务对消费重复非常敏感,务必要在业务层面进行去重处理。

三、消息消费者应当如何做到幂等性

  1、对于非幂等性业务且要求实现幂等性业务:生成一个唯一ID标记每一条消息,将消息处理成功和去重日志通过事物的形式写入去重表。

  2、对于非幂等性业务可不实现幂等性的业务:权衡去重所花的代价决定是否需要实现幂等性,如:购物会员卡成功,向用户发送通知短信,发送一次或者多次影响不大。不做幂等性可以省掉写去重日志的操作。

四、分布式幂等性

       分布式环境下可各个服务相互调用来达到幂等性的效果,进行程序处理。

五、 消费过程幂等

RocketMQ无法避免消息重复(Exactly-Once),所以如果业务对消费重复非常敏感,务必要在业务层面进行去重处理。可以借助关系数据库进行去重。首先需要确定消息的唯一键,可以是msgId,也可以是消息内容中的唯一标识字段,例如订单Id等。在消费之前判断唯一键是否在关系数据库中存在。如果不存在则插入,并消费,否则跳过。(实际过程要考虑原子性问题,判断是否存在可以尝试插入,如果报主键冲突,则插入失败,直接跳过)

msgId一定是全局唯一标识符,但是实际使用中,可能会存在相同的消息有两个不同msgId的情况(消费者主动重发、因客户端重投机制导致的重复等),这种情况就需要使业务字段进行重复消费。

 

参考资料:

https://github.com/apache/rocketmq/blob/master/docs/cn/best_practice.md

https://www.jianshu.com/p/86d3d72bd3fb

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/520023
推荐阅读
相关标签
  

闽ICP备14008679号