RocketMQ msgId生成算法

简介: RocketMQ msgId生成算法

当我们用RocketMQ发送信息的时候通常都会返回如下信息:
SendResult [sendStatus=SEND_OK, msgId=0A42333A0DC818B4AAC246C290FD0000, offsetMsgId=0A42333A00002A9F000000000134F1F5, messageQueue=MessageQueue [topic=topicTest1, brokerName=mac.local, queueId=3], queueOffset=4]

对于客户端来说msgId是由客户端producer自己生成的,offsetMsgId是由服务端broker生成的,其中offsetMsgId就是我们在rocketMQ控制台直接输入查询的那个messageId。

下面就来介绍一下这两个ID的生成算法:

msgId:

以下是RocketMQ部分源码的节选

  初始化参数LEN,FIX_STRING,COUNTER

image.png
初始化buffer
image.png
设置开始时间
image.png

字节转string工具方法
image.png

最终生成msgId
image.png
其中createUniqId就是最终生成msgId方法。除些之外的方法者是createUniqId调用或者被间接调用的方法,这些方法实现也比较简单。这里就不一一解释了~

StringBuilder sb = new StringBuilder(LEN * 2);

由此可知msgId的长度是LEN 2 = 16 2 = 32;

 设time = 当前时间 - 本月开始时间(ms);

 从代码得到 FIX_STRING = ip + 进程pid + MessageClientIDSetter.class.getClassLoader().hashCode();

 createUniqIDBuffer 加入time 和 counter 因子。

最终得到msgId的生成因子是:   ip + 进程pid + MessageClientIDSetter.class.getClassLoader().hashCode() + time + counter(AtomicInteger自增变量)

 最后调用bytes2string进行十六进制的移位和编码就产生了我们的msgId。

那我们来分析一下这个算法:

对于每个producer实例来说ip都是唯一的,所以不同producer生成的msgId是不会重复的。对于producer单个实例来说的区分因子是:time + counter。首先应用不重启的情况下msgId是保证唯一性的,应用重启了只要系统的时钟不变msgId也是唯一的。所以只要系统的时钟不回拨我们就可以保证msgId的全局唯一。

有人也许会说应用运行了一个月再进行重启msgId就会重复了。从生成算法上来说是的!但是MQ的message是有时效性的,有效期是72小时也就是3天。每天的凌晨4点rocketMQ会把过期的message清除掉。所以msgId也是保证全局唯一的。

offsetMsgId:

broker端生成的offsetMsgId就比较简单了,直接就是主机ip + 物理分区的offset,再调用UtilAll.bytes2string进行移位转码就完成了,是不是很简单粗爆?!
image.png
以上就是RocketMQ生成msgId和offsetMsgId的生成算法。

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
消息中间件 RocketMQ
RocketMQ极简入门-RocketMQ顺序消息发送
在某些业务场景下是需要消息按照顺序进行消费,比如一个账户的加钱,减钱的动作必须按照时间先后去执行,否则就会发生金额不够导致操作失败。 顺序消息故名知意就是消息按照发送的顺序进行消费,队列本身是一种先进先出的数据结构,而RocketMQ理论上说也遵循这种机制。但是默认生产者以Round Robin轮询方式把消息发送到不同的Queue分区队列;消费者从多个队列中消费消息,这种情况没法保证顺序。所以在RocketMQ中如何保证消息顺序呢?
112 0
|
消息中间件 Java RocketMQ
四.RocketMQ极简入门-RocketMQ顺序消息发送
RocketMQ极简入门-RocketMQ顺序消息发送
|
消息中间件 Java 网络安全
rocketmq发送消息报错
rocketmq发送消息报错
|
消息中间件 编解码 算法
RocketMQ msgId生成算法
RocketMQ msgId生成算法
RocketMQ msgId生成算法
|
存储 消息中间件 Java
RocketMQ的消息查询
RocketMQ的消息查询
RocketMQ的消息查询
|
消息中间件 前端开发 大数据
MQ学习-MQ是什么?
MQ学习-MQ是什么?
481 0
|
消息中间件 安全 Java
RocketMQ概念详细之Producer
RocketMQ 生产者
1541 0
|
消息中间件 存储 数据库
Rabbit MQ消息队列原理(2)
Rabbit MQ消息队列原理(2)
122 0
Rabbit MQ消息队列原理(2)
|
消息中间件 存储 网络协议
Rabbit MQ消息队列原理(5)
Rabbit MQ消息队列原理(5)
171 0
Rabbit MQ消息队列原理(5)
|
消息中间件 存储 缓存
Rabbit MQ消息队列原理(1)
Rabbit MQ消息队列原理(1)
333 0
Rabbit MQ消息队列原理(1)
下一篇
无影云桌面