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。ui

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

     msgId:          3d

     如下是RocketMQ部分源码的节选blog

     

      初始化参数LEN,FIX_STRING,COUNTER进程

      初始化bufferip

      设置开始时间get

      字节转string工具方法源码

 

    最终生成msgId

   

     其中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进行移位转码就完成了,是否是很简单粗爆?!

 

      以上就是RocketMQ生成msgId和offsetMsgId的生成算法。经过阅读文章咱们除了了解RocketMQ生成msgId的方式以外,在平常项目中若是有遇到相似遇到生成全局惟一key场景时是否是也能够借鉴一下RocketMQ的思路?若是文章有什么不理解的地方欢迎你们提出宝贵的意见,也欢迎你们多多交流~~~~

相关文章
相关标签/搜索