MQ如何解决消息的顺序问题和消息的重复问题?
一、摘要
分布式消息系统作为实现分布式系统可扩展、可伸缩性的关键组件,需要具有高吞吐量、高可用等特点。而谈到消息系统的设计,就回避不了两个问题:
1、消息的顺序问题
2、消息的重复问题
二、关键特性以及其实现原理
2.1、顺序消息
要实现严格的顺序消息,简单且可行的办法就是:
保证生产者 - MQServer - 消费者是一对一对一的关系
这样的设计虽然简单易行,但也会存在一些很严重的问题,比如:
1、并行度就会成为消息系统的瓶颈(吞吐量不够)
2、更多的异常处理,比如:只要消费端出现问题,就会导致整个处理流程阻塞,我们不得不花费更多的精力来解决阻塞的问题。
但我们的最终目标是要集群的高容错性和高吞吐量。这似乎是一对不可调和的矛盾,那么阿里是如何解决的?
有些问题,看起来很重要,但实际上我们可以通过合理的设计或者将问题分解来规避。如果硬要把时间花在解决问题本身,实际上不仅效率低下,而且也是一种浪费。从这个角度来看消息的顺序问题,我们可以得出两个结论:
1、不关注乱序的应用实际大量存在
2、队列无序并不意味着消息无序
2.2、消息重复
上面在解决消息顺序问题时,引入了一个新的问题,就是消息重复。那么MQ是怎样解决消息重复的问题呢?还是“恰好”不解决。
造成消息的重复的根本原因是:网络不可达。只要通过网络交换数据,就无法避免这个问题。所以解决这个问题的办法就是不解决,转而绕过这个问题。那么问题就变成了:如果消费端收到两条一样的消息,应该怎样处理?
1、消费端处理消息的业务逻辑保持幂等性
2、保证每条消息都有唯一编号且保证消息处理成功与去重表的日志同时出现
第1条很好理解,只要保持幂等性,不管来多少条重复消息,最后处理的结果都一样。第2条原理就是利用一张日志表来记录已经处理成功的消息的ID,如果新到的消息ID已经在日志表中,那么就不再处理这条消息。
我们可以看到第1条的解决方式,很明显应该在消费端实现,不属于消息系统要实现的功能。第2条可以消息系统实现,也可以业务端实现。正常情况下出现重复消息的概率不一定大,且由消息系统实现的话,肯定会对消息系统的吞吐量和高可用有影响,所以最好还是由业务端自己处理消息重复的问题,这也是MQ不解决消息重复的问题的原因。
MQ不保证消息不重复,如果你的业务需要保证严格的不重复消息,需要你自己在业务端去重。
MQ如何解决消息的顺序问题和消息的重复问题?的更多相关文章
- MQ如何解决消息的顺序性
一.消息的顺序性 1.延迟队列:设置一个全局变量index,根据实际情况一次按照index++的逻辑一次给消息队列设置延迟时间段,可以是0.5s,甚至1s; 弊端:如果A,B,C..消息队列消费时间不 ...
- 关于MQ的几件小事(五)如何保证消息按顺序执行
1.为什么要保证顺序 消息队列中的若干消息如果是对同一个数据进行操作,这些操作具有前后的关系,必须要按前后的顺序执行,否则就会造成数据异常.举例: 比如通过mysql binlog进行两个数据库的数据 ...
- rocketmq总结(消息的顺序、重复、事务、消费模式)
rocketmq总结(消息的顺序.重复.事务.消费模式) 参考: http://www.cnblogs.com/wxd0108/p/6038543.html https://www.cnblogs.c ...
- 分布式开放消息系统RocketMQ的原理与实践(消息的顺序问题、重复问题、可靠消息/事务消息)
备注:1.如果您此前未接触过RocketMQ,请先阅读附录部分,以便了解RocketMQ的整体架构和相关术语2.文中的MQServer与Broker表示同一概念 分布式消息系统作为实现分布式系统可扩展 ...
- 解决spring boot在RabbitMQ堆积消息情况下无法启动问题
最近遇到一个问题,服务站点上线之前,先去新建需要的rabbitmq并绑定关系,此时 如果发送消息方运行, 那边会造成新建的q消息部分堆积得不到及时消费 那么问题来了? 在消息堆积情况下,服务站点无法启 ...
- 关于MQ的几件小事(六)消息积压在消息队列里怎么办
1.大量消息在mq里积压了几个小时了还没解决 场景:几千万条数据在MQ里积压了七八个小时,从下午4点多,积压到了晚上很晚,10点多,11点多.线上故障了,这个时候要不然就是修复consumer的问题, ...
- RabbitMQ多消费者顺序性消费消息实现
最近起了个项目消息中心,用来中转各个系统中产生的消息,用到的是RabbitMQ,由于UAT环境.生产环境每台消费者服务都是多台,有些消息要求按顺序消费,所以需要采取一定的措施保证消息的顺序消费,下面讲 ...
- RocketMQ消息的顺序与重复
1.如何保证消息的顺序 原因:生产者将消息发给topic,topic分发给不同的队列再给多个消费者并发消费,难以保证顺序. 方案:topic和队列之间加入MessageQueueSelector.将一 ...
- 分布式消息队列RocketMQ&Kafka -- 消息的“顺序消费”
在说到消息中间件的时候,我们通常都会谈到一个特性:消息的顺序消费问题.这个问题看起来很简单:Producer发送消息1, 2, 3... Consumer按1, 2, 3...顺序消费. 但实际情况却 ...
随机推荐
- 关于后台动态模板添加内容的总结 Builder使用
1.后台控制器中ArticleController中加载 formBuilder,listBuilder类: 2.实例化FormBuilder对象,调用类中的方法: 3.初始化时加载Builder/f ...
- codeforce 379(div.2)
A.B略 C题 ——贪心,二分查找: 对于每一个a[i], 在d中二分查找 s-b[i],注意不要忘记计算速度为x时需要花费的最小时间,以及整数范围为64位整数 1 #include <cstd ...
- 2018-12-14-恢复-U-盘隐藏文件夹
title author date CreateTime categories 恢复 U 盘隐藏文件夹 lindexi 2018-12-14 19:24:56 +0800 2018-12-14 19: ...
- easyui—element-ui框架套用(表格宽度自适应)
外层使用easyui框架中window组件,便于使用最大化功能:内部表格使用element-ui在的el-table,el-table列宽须设置为最小宽度才能在最大化窗口时列表中列宽自适应window ...
- H3C 配置静态及动态域名解析
- H3C 计算子网内可用主机地址数
- 2018.12.7 浪在ACM 集训队第八次测试赛
2018.12.7 浪在ACM 集训队第八次测试赛 https://blog.csdn.net/QLU_minoz/article/details/84886717 感谢苗学林同学C题和D题题解 ...
- tikz 常用命令总结
使用斜线填充区域,并绘制边界 \fill[pattern color=red, pattern=north west lines, opacity=0.4] (0,0) -- (0,1) -- (1, ...
- 网摘-获取屏幕dc并且将其画面显示在窗体中
获取屏幕dc并且将其画面显示在窗体中 HWND hWnd = ::GetDesktopWindow();//获得屏幕的HWND. HDC hScreenDC = ::GetDC(hWnd); // ...
- koa2--07.cookies的设置和使用
cookies本身在koa中即可直接设置和使用,不需要在安装中间件 //cookies的使用 const koa = require('koa'); var router = require('koa ...