mq中如何保证消费者顺序消费

author author     2023-04-27     164

关键词:

参考技术A 通常mq可以保证先到队列的消息按照顺序分发给消费者消费来保证顺序,但是一个队列有多个消费者消费的时候,那将失去这个保证,因为这些消息被多个线程并发的消费。但是有的时候消息按照顺序处理是很重要的,那我们该如何来保证消息的顺序呢,下面将从activemq和rocketmq来看看,它们是如何来保证消息的顺序问题的?我们还可以有别的处理方案么?

1、利用Activemq的高级特性:consumer之独有消费者(exclusive consumer)

在ActiveMQ4.x中可以采用Exclusive Consumer,broker会从queue中,一次发送消息给一个消费者,这样就避免了多个消费者并发消费的问题,从而保证顺序,配置如下:

.当在接收信息的时候有一个或者多个备份接收消息者和一个独占消息者的同时接收时候,无论两者创建先后,在接收的时候,均为独占消息者接收。
.当在接收信息的时候,有多个独占消费者的时候,只有一个独占消费者可以接收到消息。
.当有多个备份消息者和多个独占消费者的时候,当所有的独占消费者均close的时候,只有一个备份消费者接到到消息。
.当主消费者挂了话,会立刻启用故障切换转移到下一台消费者继续消费

独占消息就是在有多个消费者同时消费一个queue时,可以保证只有一个消费者可以消费消息,这样虽然保证了消息的顺序问题,不过也带来了一个问题,就是这个queue的所有消息将只会在这一个主消费者上消费,其他消费者将闲置,达不到负载均衡分配,而实际业务我们可能更多的是这样的场景,比如一个订单会发出一组顺序消息,我们只要求这一组消息是顺序消费的,而订单与订单之间又是可以并行消费的,不需要顺序,因为顺序也没有任何意义,有没有办法做到呢?答案是可以的,下面就来看看activemq的另一个高级特性之messageGroup。
2、利用Activemq的高级特性:messageGroups

Message Groups特性是一种负载均衡的机制。在一个消息被分发到consumer之前,broker首先检查消息JMSXGroupID属性。如果存在,那么broker会检查是否有某个consumer拥有这个message group。如果没有,那么broker会选择一个consumer,并将它关联到这个message group。此后,这个consumer会接收这个message group的所有消息,直到:

Consumer被关闭
Message group被关闭,通过发送一个消息,并设置这个消息的JMSXGroupSeq为-1

如上图所示,同一个queue中,拥有相同JMSXGroupID的消息将发往同一个消费者,解决顺序问题,不同分组的消息又能被其他消费者并行消费,解决负载均衡的问题,两全其美啦!

Rocketmq处理方案

那rocketmq又是如何保证消息顺序消费的问题呢?

Rocketmq跟传统的MQ有一点区别,这里有必要讲一下topic的概念,Topic是RocketMQ中的一个重要概念,RocketMQ的各组件都是围绕着Topic建立起对应关系的,在RocketMQ官方文档和本文中, Topic在不同的语境下被赋予了两种不同的语义:

1)消息的Topic属性值:在描述Consumer的订阅设置信息或消息的属性时。

2)Topic属性为某个值的消息(单个消息或消息集合):在描述Broker,Producer和Consumer的对应关系,Queue以及负载均衡策略时。

topic和queue的对应关系是一个topic拥有多个queue,当producer往broken发送消息时,消息会存储在topic下的不同队列中,而一个队列只会被一个consumer消费,这样消息户被均衡负载到不同的队列下,也就是会被多个消费者并行消费,顺序就无法保证了。该怎么办呢?答案是把需要顺序消费的消息发送到同一台broker server下的同一个队列,而这些消息也只会被同一个消费者消费,这样就可以保证严格的顺序了,如下图:

1、消息要有顺序,首先得保证producer发送消息有顺序,如上图msg1,msg2,msg3发送到queue0是要有顺序的,只要producer等待前面的消息发送成功,在发送后面的消息就完全可以保证了,

2、假设msg1发送给consumer1,消费没有响应,该怎么办呢?是继续发送msg2还是重新发送msg1,一般为了保证消息一定被消费,肯定会选择重发msg1到下一台消费者consumer2。

3、消费端1没有响应Server时有两种情况,一种是msg1确实没有到达(数据在网络传送中丢失),另外一种消费端已经消费msg2且已经发送响应消息,只是MQ Server端没有收到。如果是第二种情况,重发msg1,就会造成msg1被重复消费。也就引入了消息重复问题,那就要幂等了。

Rocketmq同样做到了保证消息的顺序情况下,均衡消费的消费消息。

综上,我看到,在分布式系统中,要想消息有顺序的被消费,无论是Activemq还是Rocketmq都要想办法让有顺序的消息被同一消费者消费,而不是并发的消费,在消费者消费成功后,接着才会消费下一个消息,这样就可以保证了严格的顺序。

如何解决顺序消费重复消费

...到两个概念——普通顺序和严格顺序。所谓普通顺序是指消费者通过同一个消费队列收到的消息是有顺序的,不同消息队列收到的消息则可能是无顺序的。普通顺序消息在Broker重启情况下不会保证消息顺序性(短暂时间)。所... 查看详情

mq如何保证消息顺序性(代码片段)

...到不同的Partition。Kafka中的消费是基于拉模式的,即消费者主动向服务端发起请求来拉取消息。Kakfa中的消息消费是一个不断轮询的过程,消费者所要做的就是重复地调用poll()方法,而poll()方法返回的是所订阅主题ÿ... 查看详情

3、rabbitmq如何保证消息不被重复消费

...来看看什么情况下可能会出现重复消费的情况。一般来说消费者消费完消息后,会ack到MQ然后MQ会删除这条消息。但假设由于网络原因这条ACK丢失了,又或者此时我kill掉了消费端的应用。MQ没有收到确认信息,认为该消息没有被... 查看详情

如何保证rabbitmq消息顺序消费(代码片段)

...,这样也会造成消息消费顺序错误。解决方案队列与消费者一对一 将原来的一个queue拆分成多个queue,然后保证每个queue对应一个consumer,就是多一些queue而已,确实是麻烦点;这样也会造成吞吐量下降,可... 查看详情

mq-面试题

...比较强kafka:实时计算,日志采集等场景消息顺序问题:消费者固定,比如kafka到一个指定partition。缺点是并发度较低,消费端出现异常会阻塞消费。理论程序应该保证消息的顺序,而不是靠消息中间件保证顺序。消息重复问题... 查看详情

rabbitmq--顺序消费模式和迅速消息发送模式

MQ使用过程中,有些业务场景需要我们保证顺序消费,而如果一个Producer,一个Queue,多个Consumer的情况下是无法保证顺序的举例:  1、业务上产生三条消息,分别是对数据的增加、修改、删除,而如果没有保证顺序消费,结果... 查看详情

关于mq的几件小事如何保证消息不重复消费

1.幂等性幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复... 查看详情

rocketmq如何保证消费顺序

...会有本地队列锁进行锁定保证同一个队列只会同时被一个消费者线程锁定本地消费时也按队列进行锁定操作MQConsumerInner获取到消息就把消息放到ProcessQueue,并且会启动一个消费者任务ProcessQueue底层用treeMap存储消息保证消息获取... 查看详情

消息队列总结

...必然会讨论mq顺序性问题,比如生产者发送消息1,2,3...对于消费者必须按照1,2,3...这样的顺序来消费,那么消息队列应该怎么样去考虑这样事情呢,有人说了消息队列是先进先出不就保证了顺序性,其实并非如此,而且想通过队列来保证... 查看详情

mq如何保证高可用,解决重复消费、数据丢失问题和顺序性问题

参考技术Arabbitmq有三种模式:单机模式,普通集群模式,镜像集群模式kafka架构:多个broker组成,每个broker是一个节点;创建一个topic,这个topic可以划分为多个partition,每个partition可以存在于不同的broker上,每个partition就放一部... 查看详情

如何保证消息队列里的数据顺序执行?

使用MQ的时候,经常会有按顺序消费的需求,比如大数据团队为了做数据分析,会把数据库里数据同步到其他系统做一些数据统计分析。同步MySQL的时候,为了保证数据同步的实时性,会在中间加一个MQ,多... 查看详情

一条消息怎么被两个消费者消费

在保证MQ消息不重复的情况下,消费者消费消息成功后,在给MQ发送消息确认的时候出现了网络异常(或者是服务中断),MQ没有接收到确认,此时MQ不会将发送的消息删除,为了保证消息被消费,当消费者网络稳定后,MQ就会继续给... 查看详情

rabbitmq面试题:如何解决消息的顺序问题?---2022-04-03

...三个队伍,不同队伍之间的,不能确保谁先进站。在多个消费者消费同一个消息队列的场景,通常是无法保证消息顺序的。例如:消息A、B、C按顺序进入队列,消费者A1拿到消息A、消费者B1拿到消息B,结果消费者B执行速度快,就... 查看详情

rocketmq顺序消费

...做不到有序。接下来,会从provider、consumer两个方面说明如何做到有序。首先针对顺序消息,生产者可以是多线程的,只要保证每个线程发的是不同类型的消息(如发生不同订单的消息),那么在不同的分区就可以保证有序;针... 查看详情

rocketmq概述

...而且仅消费一次。 1、消息架构:生产者、服务器、消费者、路由发现。2、消息顺序:严格按照消息到达服务器的顺序进行消费。3、消息过滤:  a、服务端过滤  b、消费端过滤。  缺点:无用的消息也传输到消费端... 查看详情

rabbitmq消息重复消费场景及解决方案

...际情况再做细化处理。目录消息重复消费MQ的一条消息被消费者消费了多次重复消费场景重现测试如何解决消息重复消费的问题编码解决消息重复消费测试消息重复消费什么是消息重复消费?首先我们来看一下消息的传输流... 查看详情

架构设计消息篇之保证消息顺序性

...以保证消息的存储顺序和原始顺序一致,也无法绝对保证消费者一定是按存储顺序消费。比如说,一个消费者开启了多线程进行消费,那么并行地消费就会导致消费乱序。因此,我们可以发现消息的消费顺序与如何 查看详情

kafka如何保证消息的顺序性

...partition中去,而且这个partition中的数据一定是有顺序的。消费者从partition中取出来数据的时候,也一定是有顺序的。到这里,顺序还是ok的,没有错乱。接着,我们在消费者里可能会搞多个线程来并发处理消息。因为如果消费者... 查看详情