导航菜单
路很长,又很短
博主信息
昵   称:Cocodroid ->关于我
Q     Q:2531075716
博文数:356
阅读量:1745019
访问量:218078
至今:
×
云标签 标签球>>
云标签 - Su的技术博客
Tags : RabbitMQ,Kafka,消息顺序发表时间: 2022-01-13 00:48:08

一、为什么要保证顺序

消息队列中的若干消息如果是对同一个数据进行操作,这些操作具有前后的关系,必须要按前后的顺序执行,否则就会造成数据异常。

例如,业务上产生三条消息,分别是对数据的增加、修改、删除,而如果没有保证顺序消费,结果可能是删除、修改、增加,本来数据最终要删除、结果变成增加。


二、RabbitMQ顺序消费模式

一个Queue,有多个Consumer去消费,这样就会造成顺序的错误,Consumer从MQ里面读取数据是有序的,但是每个Consumer的执行时间是不固定的,无法保证先读到消息的Consumer一定先完成操作,这样就会出现消息并没有按照顺序执行,造成数据顺序错误。

RabbitMQ和Kafka如何保证消息顺序执行?

解决方案:

一个Queue对应一下Consumer,把需要保证顺序的message都发送到一个Queue当中,关闭autoack,prefetchCount=1,每次只消费一条信息,处理过后进行手工ack,然后接收下一条message,只是由一个Consumer进行处理。

多数业务场景下,可以做局部顺序,创建多个队列,同一业务id的消息发送到同一个消息队列,这样队列数增加,消费者数量也会增加 了。

拆分多个Queue,每个Queue一个Consumer,就是多一些Queue而已。

RabbitMQ和Kafka如何保证消息顺序执行?

首先,我们在 RabbitMQ 中会建立有相同前缀的队列,后面跟着队列编号。然后,集群中的不同应用会分别监听这两个有着不同编号的队列。当在 A 发送信息时,我们会对信息做一次简单的哈希:

m = hash(id) mod n

这里,id 是订单的标识。n 是集群中 B 所在业务系统部署的数量。最终的 m 是我们需要发送到的目的队列编号。

RabbitMQ和Kafka如何保证消息顺序执行?

假设,hash(id) 的结果为 2000,n 为 2,经过计算 m = 0。此时,A 就会把他和 B 的对话信息都发送到 chat00 的队列里。B 收到消息后,就会依次显示给终端用户。这样,聊天乱序的问题就解决了。


三、kafka顺序消费模式

具有顺序的数据写入到了不同的partition里面,不同的消费者去消费,但是每个consumer的执行时间是不固定的,无法保证先读到消息的consumer一定先完成操作,这样就会出现消息并没有按照顺序执行,造成数据顺序错误。

RabbitMQ和Kafka如何保证消息顺序执行?

解决方案:

确保顺序消息发送到同一个partition,一个topic,一个partition,一个consumer,内部单线程消费。

RabbitMQ和Kafka如何保证消息顺序执行?
...阅读原文
推荐文章