前言
本篇文章比较简单,分别介绍RocketMQ支持几种过滤机制,其原理和使用。
RocketMQ 提供了多种消息过滤机制,帮根据业务需求高效筛选消息,可以减少不必要的消息传输和处理。以下是其核心过滤机制及使用场景:
1. Tag 标签过滤
-
原理 :
每个消息发送时可附加一个 Tag(字符串标签),消费者订阅时指定一个或多个 Tag,Broker 会过滤出匹配 Tag 的消息投递给消费者。 -
使用方式 :
-
生产者 :发送消息时设置
setTags
。javaMessage msg = new Message("TopicTest", "TagA", "Hello RocketMQ".getBytes());
-
消费者 :订阅时指定 Tag(支持
*
表示全部,||
表示或关系)。javaconsumer.subscribe("TopicTest", "TagA || TagB");
-
-
特点 :
- 高效:Broker 端过滤,性能损耗低。
- 简单:仅支持精确匹配,适用于简单分类场景(如订单状态分类)。
2. SQL92 属性过滤
-
原理 :
基于消息的 自定义属性(Key-Value) ,通过 SQL 表达式进行复杂条件过滤(如数值比较、逻辑运算)。需开启 Broker 的enablePropertyFilter=true
。 -
使用方式 :
-
生产者 :为消息添加自定义属性。
javaMessage msg = new Message("TopicTest", "TagA", "Hello RocketMQ".getBytes()); msg.putUserProperty("a", "10"); msg.putUserProperty("b", "5");
-
消费者 :订阅时编写 SQL 表达式。
javaconsumer.subscribe("TopicTest", MessageSelector.bySql("a > 5 AND b = '5'"));
-
-
特点 :
- 灵活 :支持复杂逻辑(如
>
,<
,BETWEEN
,IS NULL
等)。 - 性能损耗:相比 Tag 过滤略高,需评估表达式复杂度。
- 灵活 :支持复杂逻辑(如
3. 类过滤(Class Filter)
-
原理 :
允许用户自定义 Java 类实现过滤逻辑,Broker 加载该类并调用其方法判断消息是否投递。适用于高度定制化的过滤需求。 -
使用方式 :
-
实现接口 :编写类实现
org.apache.rocketmq.common.filter.MessageFilter
。javapublic class CustomFilter implements MessageFilter { @Override public boolean match(MessageExt msg, FilterContext context) { // 自定义过滤逻辑 return msg.getUserProperty("region").equals("CN"); } }
-
部署类 :将编译后的类文件上传到 Broker 指定路径(需配置
filterSupportRetry=true
)。 -
消费者订阅 :指定过滤类名。
javaconsumer.subscribe("TopicTest", MessageSelector.byFilterClass("com.example.CustomFilter"));
-
-
特点 :
- 高度灵活:可编写任意复杂逻辑(如结合外部配置或数据库)。
- 维护成本高:需管理类的版本和部署,适合有特殊需求的场景。
对比与选型建议
机制 | 性能 | 灵活性 | 适用场景 |
---|---|---|---|
Tag 过滤 | 高 | 低(精确匹配) | 简单分类(如订单状态、日志类型) |
SQL92 | 中 | 高 | 复杂属性条件(如价格范围、地域) |
类过滤 | 低 | 极高(自定义) | 特殊逻辑(需动态规则或外部查询) |
注意事项
- Broker 配置 :SQL 和类过滤需 Broker 开启支持(
enablePropertyFilter
或filterSupportRetry
)。 - 版本兼容性:SQL92 过滤需 RocketMQ 4.3.0+,类过滤需 4.6.0+。
- 生产环境慎用类过滤:频繁更新过滤类可能导致服务中断,建议优先使用 Tag 或 SQL 过滤。
通过合理选择过滤机制,可以显著提升消息系统的效率和可维护性。