我擦,RocketMQ的tag还有这个“坑”!(一)

WilliamGates
发布于 2022-6-20 17:49
浏览
0收藏

 

大家好,我是威哥,《RocketMQ技术内幕》作者、RocketMQ社区首席布道师、中通快递基础架构资深架构师,越努力越幸运,唯有坚持不懈,与大家共勉。

 

RocketMQ提供了基于Tag的消息过滤机制,但在使用过程中有很多朋友或多或少会有一些疑问,我不经意在RocketMQ官方钉钉群,我记得有好多朋友都有问到如下问题:

 我擦,RocketMQ的tag还有这个“坑”!(一)-鸿蒙开发者社区
今天我就与RocketMQ Tag几个值得关注的问题,和大家来做一个分享,看过后的朋友,如果觉得有帮助,期待你的点赞支持。

  • 消费组订阅关系不一致为什么会到来消息丢失?
  • 如果一个tag的消息数量很少,是否会显示很高的延迟?


1、消费组订阅关系不一致导致消息丢失


从消息消费的视角来看消费组是一个基本的物理隔离单位,每一个消费组拥有自己的消费位点、消费线程池等。

 

RocketMQ的初学者容易犯这样一个错误:消费组中的不同消费者,订阅同一个topic的不同的tag,这样会导致消息丢失(部分消息没有消费),在思考这个问题时,我们不妨先来看一张图:

 我擦,RocketMQ的tag还有这个“坑”!(一)-鸿蒙开发者社区
简单阐述一下其核心关键点:

1.例如一个Topic共有4个队列。
2.消息发送者连续发送4条tagA的消息后,再连续发送4条tagb的消息,消息发送者端默认采取轮循的负载均衡机制,这样topic的每一个队列中都存在tagA、tabB两个tag的消息。
3.消费组dw_tag_test的IP为192.168.3.10的消费者订阅tagA,另外一个IP为192.168.3.11的消费者订阅tagB。
4.消费组内的消费者在进行消息消费之前,首先会进行队列负载,默认为平均分配,分配结果:

  • 消费者然后向Broker发起消息拉取请求,192.168.3.10消费者会由于只订阅了tagA,这样存在q0、q1中的tagB的消息会被过滤,但被过滤的tagB并不会投递到另外一个订阅了tagB的消费者,造成这部分消息没有被投递,从而导致消息丢失。
  • 同样192.168.3.11消费者会由于只订阅了tagB,这样存在q2、q3中的tagA的消息会被过滤,但被过滤的tagA并不会投递到另外一个订阅了tagA的消费者,造成这部分消息没有被投递,从而导致消息丢失。
  • 192.168.3.10 分配到q0、q1。
  • 192.168.3.11 分配到q2、q3。


2、如果一个tag的消息数量很少,是否会显示很高的延迟?


开篇有群友会存在这样一个担忧,其场景大概如下图所示:

 我擦,RocketMQ的tag还有这个“坑”!(一)-鸿蒙开发者社区
消费者在消费offset=100的这条tag1消息后,后面连续出现1000W条非tag1的消息,这个消费组的积压会持续增加,直接到1000W吗?

 

要想明白这个问题,我们至少应该要重点去查看如下几个功能的源码:

  • 消息拉取流程
  • 位点提交机制


本文不准备全流程去分析这块的源码,如果大家对这块代码有兴趣,可以查阅笔者出版的《RocketMQ技术内幕》书籍。


本文将从以问题为导向,经过自己的思考,并找到关键源码加以求证,最后进行简单的示例代码进行验证。

 

遇到问题之前,我们可以先尝试思考一下,如果这个功能要我们实现,我们大概会怎么去思考?

 

要判断消费组在消费为offset=100的消息后,在接下来1000W条消息都会被过滤的情况下,如果我们希望位点能够提交,我们应该怎么设计?我觉得应该至少有如下几个关键点:

  • 消息消息拉取时连续1000W条消息找不到合适的消息,服务端会如何处理
  • 客户端拉取到消息与未拉取到消息两种情况如何提交位点

 

文章转自公众号:中间件兴趣圈

标签
已于2022-6-20 17:49:10修改
收藏
回复
举报
回复
    相关推荐