发表时间:2022-03-25来源:网络
RocketMQ的消息是存储到Topic的queue里面的,queue本身是FIFO(First Int First Out)先进先出队列。所以单个queue是可以保证有序性的。但是问题是1个topic有N个queue,作者这么设计的好处也很明显,天然支持集群和负载均衡的特性,将海量数据均匀分配到各个queue上,你发了10条消息到同一个topic上,这10条消息会自动分散在topic下的所有queue中,所以消费的时候不一定是先消费哪个queue,后消费哪个queue,这就导致了无序消费。

一个Producer发送了m1、m2、m3、m4四条消息到topic上,topic有四个队列,由于自带的负载均衡策略,四个队列上分别存储了一条消息。queue1上存储的m1,queue2上存储的m2,queue3上存储的m3,queue4上存储的m4,Consumer消费的时候是多线程消费,所以他无法保证先消费哪个队列或者哪个消息,比如发送的时候顺序是m1,m2,m3,m4,但是消费的时候由于Consumer内部是多线程消费的,所以可能先消费了queue4队列上的m4,然后才是m1,这就导致了无序。
很简单,问题产生的关键在于多个队列都有消息,我消费的时候又不知道哪个队列的消息是最新的。那么思路就有了,发消息的时候你要想保证有序性的话,就都给我发到一个queue上,然后消费的时候因为只有那一个queue上有消息且queue是FIFO,先进先出,所以正常消费就完了。很完美。而且RocketMQ也给我们提供了这种发消息的时候选择queue的api(Message)。直接上代码。
很完美,有序输出!
比如你新需求:把未支付的订单都放到queue1里,已支付的订单都放到queue2里,支付异常的订单都放到queue3里,然后你消费的时候要保证每个queue是有序的,不能消费queue1一条直接跑到queue2去了,要逐个queue去消费。
这时候思路是发消息的时候利用自定义参数arg,消息体里肯定包含支付状态,判断是未支付的则选择queue1,以此类推。这样就保证了每个queue里只包含同等状态的消息。那么消费者目前是多线程消费的,肯定乱序。三个queue随机消费。解决方案更简单,直接将消费端的线程数改为1个,这样队列是FIFO,他就逐个消费了。RocketMQ也为我们提供了这样的api,如下两句:
// 最大线程数1 consumer.setConsumeThreadMax(1); // 最小线程数 consumer.setConsumeThreadMin(1);
皓盘云建最新版下载v9.0 安卓版
53.38MB |商务办公
ris云客移动销售系统最新版下载v1.1.25 安卓手机版
42.71M |商务办公
粤语翻译帮app下载v1.1.1 安卓版
60.01MB |生活服务
人生笔记app官方版下载v1.19.4 安卓版
125.88MB |系统工具
萝卜笔记app下载v1.1.6 安卓版
46.29MB |生活服务
贯联商户端app下载v6.1.8 安卓版
12.54MB |商务办公
jotmo笔记app下载v2.30.0 安卓版
50.06MB |系统工具
鑫钜出行共享汽车app下载v1.5.2
44.7M |生活服务
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-02-15
2022-03-26
2022-02-14