RocketMQ 源码分析 09 消息过滤

1、消息消费过滤机制

1.1 根据 tagcode 过滤

使用messageTag比对, 存储的Message Tag和订阅的Message Tag

1.2 高级过滤使用FilterServer

重点看下DefaultMessageStore#getMessage

1.设置拉取偏移量,从 PullRequest 中获取,初始从消费进度中获取

2.根据 topic、queueId 获取消息队列(ConsumeQueue)

3.获取该消息队列中最小偏移量(minOffset)\最大偏移量(maxOffset)

4.根据需要拉取消息的偏移量 与 队列最小,最大偏移量进行对比)

5.从 consuequeue 中从当前 offset 到当前 consueque 中最大可读消息内存。

    代码来源于 ConsumeQueue#getIndexBuffer

6. 当前拉取的物理偏移量。

7.如果拉取到的消息偏移量小于下一个要拉取的物理偏移量的话,直接跳过该条消息。

8.检查该offsetPy,拉取的偏移量是否在磁盘上。

9.判断本次拉取任务是否完成。

消息存储在磁盘中,最多只能拉取8条

拉取消息后,执行消息过滤

从commitlog(全量消息)再次过滤,consumeque 中只能处理 TAG 模式的过滤,SQL92 这种模式无法过滤,因为SQL92 需要依赖消息中的属性,故在这里再做一次过滤。如果消息符合条件,则加入到拉取结果中

设置下一次拉取偏移量,然后返回拉取结果。

RocketMQ: 消息过滤有两种模式

类过滤classFilterMode,表达式模式(Expression),又分为 ExpressionType.TAG 和 ExpressionType.SQL92。
TAG过滤,在服务端拉取时,会根据 ConsumeQueue 条目中存储的 tag hashcode 与订阅的 tag (hashcode 集合)进行匹配,匹配成功则放入待返回消息结果中,然后在消息消费端(消费者,还会对消息的订阅消息字符串进行再一次过滤。为什么需要进行两次过滤呢?为什么不在服务端直接对消息订阅 tag 进行匹配呢?主要就还是为了提高服务端消费消费队列(文件存储)的性能,如果直接进行字符串匹配,那么 consumequeue 条目就无法设置为定长结构,检索 consuequeue 就不方便。

tag模式只比对tag的hashcode

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

使用filterServer过滤

我们知道,一个客户端,一个专门的消息拉取线程(PullMessageService)专门负责拉取消息,多种过滤模式公用一套消息拉取机制【消息队列负载机制】,那 ClassFilter 模式是如何工作呢?首先,ClassFilter 模式,顾名思义就是消费端可以上传一个Class类文件到 FilterServer, 然后 FilterServer 从 Broker  拉取消息,执行过滤逻辑然后再返回给Consumer。

ClassFilter模式过滤机制,本文从如下三个方面展开。
1)ClassFilter注册(消费端如何提交自己的消息过滤实现类、以及消费订阅信息注册)。
2)消费端如何路由到FilterServer上拉取消息。
3)FilterServer消息拉取与消息消费。


RocketMQ路由信息维护,Broker 通过心跳向 NameServer 注册。再结合此图,应该能想到 FilterServer 向 Broker 注册,然后Broker再发送给 NameServer。

1、订阅消息与FilterServer注册流程

消息消费者 先用类过滤模式将过滤器类,过滤器类内容 添加到订阅消息中(RebalanceImpl)。
消费者拉取消息时,向FilterServer发送请求,那FilterServer怎么得到FilterServer服务器地址呢?通过主题路由信息,向NameServer获取。消费者在得到FilterServervf服务地址的时候,会将自己过滤器类代码发送到FilterServer,方便FilterServer在拉取消息时执行过滤逻辑。
FilterServer启动时向Broker注册Filter服务地址信息。(服务列表),然后Broker将该信息通过心跳向NameServer注册,将FilterServer服务列表保存在主题的路由信息中。
2、clientUploadFilterClassEnable 参数,如果设置为false, 则需要一个url,去下载过滤类:url/classname.java 这样的请求,FilterServer要能拿到过滤类代码。

3、类过滤模式,上传的类必须实现MessageFilter接口。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值