RocketMQ4.3.x对顺序消息的理解
1、RocketMQ消息队列简单介绍
这里简单介绍一下RocketMQ的消息队列的模型
一个topic对应多个队列如下图:
生产者和消费者分别向队列中发送和消费消息,生产者和消费者都可以是多个,通过组名进行群组约束。由于负载因素造成生产消息会生产到各个queue中。
消费群组进行queue消费时首先因为负载因素,queue会分配给各自的消费实例中,如果消费组有变化会重新分配,导致queue分配乱序。
另外一个消费者实例消费对应的queue时,消费者使用线程池进行处理消息。
以上各种操作都会导致消息不一定先处理就会先完成,所以造成消息消费不是严格顺序处理的。
所以在之前的版本中假如我们要求要严格按照顺序进行消息处理的话就必须进行单队列单线程进行消息消费处理
4.0.0之后版本支持顺序消费处理,我们看一看他是如何处理的。。。
2、顺序消费原来介绍
根据上面的简单介绍我们知道一个topic对应多个队列,我们生产消息的时候就可以针对队列的数量和消息的有效标识进行取模进行队列选择发送,如下示例代码
package org.apache.rocketmq.example.ordermessage; import java.io.UnsupportedEncodingException;
import java.util.List;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageQueue;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.apache.rocketmq.remoting.exception.RemotingException; public class Producer {
public static void main(String[] args) throws UnsupportedEncodingException {
try {
MQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");
producer.start(); String[] tags = new String[] {"TagA", "TagB", "TagC", "TagD", "TagE"};
for (int i = 0; i < 100; i++) {
int orderId = i % 10;
Message msg =
new Message("TopicTestjjj", tags[i % tags.length], "KEY" + i,
("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET));
SendResult sendResult = producer.send(msg, new MessageQueueSelector() {
@Override
public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
Integer id = (Integer) arg;
int index = id % mqs.size();
return mqs.get(index);
}
}, orderId); System.out.printf("%s%n", sendResult);
} producer.shutdown();
} catch (MQClientException | RemotingException | MQBrokerException | InterruptedException e) {
e.printStackTrace();
}
}
}
比如我们使用订单号作为和queue的ID取模的关键字段,我们就可以保证这个订单号的消息都会发送给一个队列,这样我们就保证了生产者生产消息在业务上是有序的
接下来我们看看消费端是怎样实现的。
1、消费者与broker建立连接分配队列的时候会尝试给队列加锁,如果成功则获取queue消费权利,否则尝试下一个queue。
2、如果消费模式为集群每20秒对分配给自己的队列自动加锁
3、消息消费时对queue进行加锁,同一时刻只允许一个线程对一个queue进行消费
4、根据消费时间进行队列和线程的切换默认60s(这个时间就是锁住队列的时间)
5、消息重试次数超过最大次数之后将消息移入死信queue
根据以上几点可以保证一个队列中的消息可以按顺序进行消费。
3、总结
RocketMQ4.0.0对顺序消息做了升级,但是牺牲了部分消费性能。因为要给队列加锁,并且只能一个队列同一时间只能有一个线程处理消息。
至于为什么是60秒(时间可设置)进行线程切换可能是更好的利用cpu或者不因为某个队列消息异常拖慢其他队列消息处理吧,还有待深入研究。
本人理解如有误请广大网友指正,谢谢!
RocketMQ4.3.x对顺序消息的理解的更多相关文章
- RocketMQ入门到入土(二)事务消息&顺序消息
接上一篇:RocketMQ入门到入土(一)新手也能看懂的原理和实战! 一.事务消息的由来 1.案例 引用官方的购物案例: 小明购买一个100元的东西,账户扣款100元的同时需要保证在下游的积分系统给小 ...
- 聊一聊顺序消息(RocketMQ顺序消息的实现机制)
当我们说顺序时,我们在说什么? 日常思维中,顺序大部分情况会和时间关联起来,即时间的先后表示事件的顺序关系. 比如事件A发生在下午3点一刻,而事件B发生在下午4点,那么我们认为事件A发生在事件B之前, ...
- RocketMQ源码 — 十、 RocketMQ顺序消息
RocketMQ本身支持顺序消息,在使用上发送顺序消息和非顺序消息有所区别 发送顺序消息 SendResult sendResult = producer.send(msg, new MessageQ ...
- RocketMQ学习笔记(9)----RocketMQ的Producer 顺序消息
1. 顺序消息原理图 2. 什么是顺序消息? 消费消息的顺序要求同发送消息的顺序一致,在RocketMQ中,主要指的是局部顺序,即一类消息为满足顺序性,必须Producer单线程顺序发送,并且发送给到 ...
- RocketMQ顺序消息
rocketmq的顺序消息需要满足2点: 1.Producer端保证发送消息有序,且发送到同一个队列.2.consumer端保证消费同一个队列. 生产端: RocketMQ可以严格的保证消息有序.但这 ...
- 【mq读书笔记】顺序消息
注意异常情况导致整个消费无限重试 阻塞消费 mq支持局部消息顺序消费,可以确保同一个消息消费队列中的消息被顺序消费.看下针对顺序消息在整个消费过程中做的调整: 队列负载: DefaultMQPushC ...
- junit4X系列源码--Junit4 Runner以及test case执行顺序和源代码理解
原文出处:http://www.cnblogs.com/caoyuanzhanlang/p/3534846.html.感谢作者的无私分享. 前一篇文章我们总体介绍了Junit4的用法以及一些简单的测试 ...
- 20171126-handler消息机制理解
1.handler消息机制的理解 http://www.jianshu.com/p/8343a39b8a2c?s_q_s_h_a_r_e_1MTAzNTIwODAxNTExNTg5NTkwMzE0Nz ...
- 一条sql语句搞定基于mysql的sql执行顺序的基本理解
对数据库基本操作是每个程序员基本功,如何理解并快速记住sql执行的顺序呢,其实一条复杂的sql就能搞定: SELECT DISTINCT <select_list> FROM <le ...
随机推荐
- Visual Studio Code-批量添加或删除注释行
小技巧一例,批量删除Visual Studio code或notepad++注解信息,便于读取有效代码或文本信息,具体操作如下: Visual Studio Code批量删除注解行信息: 在VS Co ...
- Centos7.3离线(rpm方式)安装mysql服务
1.mysql官网下载安装包,官网地址:www.mysql.com [root@seiang software]# ll total 580020 -rw-r--r--. 1 root root 59 ...
- Ambari安装HDP问题:User root is not allowed to impersonate anonymous.User: hcat is not allowed to impersonate ambari-qa
User root is not allowed to impersonate anonymous 修改hadoop 配置文件 etc/hadoop/core-site.xml,加入如下配置项 < ...
- Taurus.MVC 2.3 开源发布:增强属性Require验证功能,自带WebAPI文档生成功能
背景: 上周,把 Taurus.MVC 在 Linux (CentOS7) 上部署任务完成后. 也不知怎么的,忽然就想给框架集成一下WebAPI文档功能,所以就动手了. 以为一天能搞完,结果,好几天过 ...
- Hadoop系列007-HDFS客户端操作
title: Hadoop系列007-HDFS客户端操作 date: 2018-12-6 15:52:55 updated: 2018-12-6 15:52:55 categories: Hadoop ...
- oracle无法插入数据
最近遇到一个问题,本来插入数据好好的,突然都不能插入了. 报错------------------->ora-01653:表无法通过128(在表空间)扩展 原因是表满了!!! 解决方案: 1. ...
- win10激活(免费+永久)视频教程
U盘重装Win10系统视频教程 好久不见,不知同学们有没有想我~ 最近因为工作太忙所以好久都没有写文章了,很多朋友希望我推一期win10激活教程,所以今天带三胖打完针后,开始写一期win10激活教程: ...
- .NET Core微服务之基于Ocelot+Butterfly实现分布式追踪
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.什么是Tracing? 微服务的特点决定了功能模块的部署是分布式的,以往在单应用环境下,所有的业务都在同一个服务器上,如果服务器出现错 ...
- 一致性Hash漫画图解
一年之前—— 未来两年内,系统预估的总订单数量可达一亿条左右. 按Mysql单表存储500万条记录来算,暂时不必分库,单库30个分表是比较合适的水平分表方案. 于是小灰设计了这样的分表逻辑: 订单表创 ...
- SpringBoot-MongoDB 索引冲突分析及解决
一.背景 spring-data-mongo 实现了基于 MongoDB 的 ORM-Mapping 能力, 通过一些简单的注解.Query封装以及工具类,就可以通过对象操作来实现集合.文档的增删改查 ...