一、MQ消息发送

        

  1、发送端MQ-client(消息生产者:Producer)将消息发送给MQ-server;

  2、MQ-server将消息落地;

  3、MQ-server回ACK给MQ-client(Producer);

  4、MQ-server将消息发送给消息接受端MQ-client(消息消费者:Customer);

  5、MQ-client(Customer)消费接受到消息后发送ACK给MQ-server;

  6、MQ-server将落地消息删除

二、消息重复发送原因

  为了保证消息必达,MQ使用了消息超时、重传、确认机制。使得消息可能被重复发送,如上图中,由于网络不可达原因:3和5中断,可能导致消息重发。消息生产者a收不到MQ-server的ACK,重复向MQ-server发送消息。MQ-server收不到消息消费者b的ACK,重复向消息消费者b发消息。

三、消息重复发送产生的后果

  举个例子:购买会员卡,上游支付系统负责给用户扣款,下游系统负责给用户发卡,通过MQ异步通知。不管是上半场的ACK丢失,导致MQ收到重复的消息,还是下半场ACK丢失,导致购卡系统收到重复的购卡通知,都可能出现,上游扣了一次钱,下游发了多张卡。

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

  对于每条消息,MQ内部生成一个全局唯一、与业务无关的消息ID:inner-msg-id。当MQ-server接收到消息时,先根据inner-msg-id判断消息是否重复发送,再决定是否将消息落地到DB中。这样,有了这个inner-msg-id作为去重的依据就能保证一条消息只能一次落地到DB。

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

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

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

MQ解决消息重发--做到幂等性的更多相关文章

  1. 避免MQ消息重发的简单实现思路

    一.MQ消息发送 一.MQ消息发送 1.发送端MQ-client(消息生产者:Producer)将消息发送给MQ-server: 2.MQ-server将消息落地: 3.MQ-server回ACK给M ...

  2. MQ如何解决消息的顺序问题和消息的重复问题?

    一.摘要 分布式消息系统作为实现分布式系统可扩展.可伸缩性的关键组件,需要具有高吞吐量.高可用等特点.而谈到消息系统的设计,就回避不了两个问题: 1.消息的顺序问题 2.消息的重复问题 二.关键特性以 ...

  3. RocketMQ(消息重发、重复消费、事务、消息模式)

    分布式开放消息系统(RocketMQ)的原理与实践 RocketMQ基础:https://github.com/apache/rocketmq/tree/rocketmq-all-4.5.1/docs ...

  4. MQ的消息丢失/重复/积压的问题解决

    在我们实际的开发过程中,我们肯定会用到MQ中间件,常见的MQ中间件有kafka,RabbitMQ,RocketMQ.在使用的过程中,我们必须要考虑这样一个问题,在使用MQ的时候,我们怎么确保消息100 ...

  5. 聊聊mq中消息消费的几种方式

    mq系列文章 对mq了解不是很多的,可以看一下下面两篇文章: 聊聊mq的使用场景 聊聊业务系统中投递消息到mq的几种方式 聊聊消息消费的几种方式 如何确保消息至少消费一次 如何保证消息消费的幂等性 本 ...

  6. 分布式事务解决方案(二)消息系统避免分布式事务 & MQ事务消息 & Sagas 事务模型

    参考文档: 如何用消息系统避免分布式事务:http://blog.jobbole.com/89140/ https://www.cnblogs.com/savorboard/p/distributed ...

  7. springboot整合mq接收消息队列

    继上篇springboot整合mq发送消息队列 本篇主要在上篇基础上进行activiemq消息队列的接收springboot整合mq发送消息队列 第一步:新建marven项目,配置pom文件 < ...

  8. MQ(队列消息的入门)

    消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成,通过提供消息传递和消息排队模型,它可以在分布式环境下拓展进程间的通信,对于消息中间件,常见的角色大致也 ...

  9. activemq消息重发机制[转]

    大家知道,JMS规范中,Message消息头接口中有setJMSRedelivered(boolean redelivered)和getJMSRedelivered()方法,用于设置和获取消息的重发标 ...

随机推荐

  1. [Luogu] 均分数据

    题面:https://www.luogu.org/problemnew/show/P2503 题解:https://www.zybuluo.com/wsndy-xx/note/1141736

  2. Gym - 101955K Let the Flames Begin 约瑟夫环

    Gym - 101955KLet the Flames Begin  说实话,没怎么搞懂,直接挂两博客. 小飞_Xiaofei的约瑟夫问题(Josephus Problem)3:谁最后一个出列 小飞_ ...

  3. [CQOI2016]手机号码 数位DP

    [CQOI2016]手机号码 用来数位DP入门,数位DP把当前是否需要限制取数范围(是否正在贴着临界值跑,即下面的limited)和一切需要满足的条件全部塞进记忆化搜索参数里面就好了,具体情况转移便好 ...

  4. linux中fork--子进程是从哪里开始运行

    转自  http://blog.csdn.net/koches/article/details/7787468 fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值 ...

  5. form 表单提交数据和文件(fromdata的使用方法)

    <!-- 数据和文件一次性提交 --> <form class="form_meren" id="mainForm" name="m ...

  6. Java实例化对象过程中的内存分配

    Java实例化对象过程中的内存分配: https://blog.csdn.net/qq_36934826/article/details/82685791 问题引入这里先定义一个很不标准的“书”类,这 ...

  7. springboot的注解

    1.@ConfigurationProperties 功能:装载配置文件信息到实体 原理:aop,通知类型:?(方法或对象创建完后) 注意:作用于方法上可以不需要改源码(例如durid配置) 转载:h ...

  8. Docker安装redis3.2

    1.拉取redis3.2镜像 2.使用docker images查看拉去下来的镜像 3.运行容器,命令如下 docker run -p : -v $PWD/data:/data -d redis:3. ...

  9. What do you do as a DevOps?

    https://ilhicas.com/2019/08/11/What-you-as-a-Devops.html Introduction In this post I'll just explain ...

  10. kotlin委托属性

    fun main(arg: Array<String>) { val myClass1 = myClass1() myClass1.name="mycalsss1" v ...