RocketMQ 过滤消息分为两种,一种tag过滤,另外一种是复杂的sql过滤。
tag过滤
首先创建producer然后启动,在这里创建了字符串的数组tags。字符串数组里面放置了多个字符串,然后去发送15条消息。
15条消息随着i的增长,然后取模做了一个哈希,值是0 1 2。要么是taga,要么是tagb,或者tagc。也就是topic TagFilterTest 里面的每条消息都会有一个tag。
15条消息会从taga到c。前面三条是 Tag A B C,到了第四条开始也是从A开始,第五条B,第六条C。
上面就是将15条消息打上tag然后发送过去。
消费者创建了consumer,消费者也去订阅这个主题。consumer会从这个主题上面去进行消费。
和之前消费者不同的地方在于"TagA || TagC" 这里写上了tag过滤的表达式。也就是消费者会去订阅这个主题里面标签为taga和tagc这样的消息,消费者是可以收到的。
这个过滤是在broker端还是消费端?
如果是broker端进行过滤的,那么会将a和c直接发给消费者,tagb是不会发送的。
如果是消费端过滤,那么会将所有的消息发给消费者,消费者收到所有消息的时候,那么会去消费a和c,那么b就不消费了。
消费者这里只消费了10条消息,可以看到消息带着的标签。只有a c是收到的,b是没有收到的。
实际上是broker过滤这些消息,broker将一些消费者需要的消息发送过去。其实也就是broker将消息已经过滤了。
这样来说,消费者的性能是得到了保证,这样就不需要在消费者这端再做一次消息的过滤。而是broker将已经过滤好的消息推送给你,你直接消费就行了。
tag过滤的限制,限制是⼀条消息只能有⼀个 标签,这可能不适⽤于复杂的场景。在这种情况下,您可以使⽤ SQL 表达式来过滤掉消息。
使⽤SQL过滤
SQL 功能可以通过您在发送消息时输⼊的属性进⾏⼀些计算。在 RocketMQ 定义的语法下,可以实现⼀些有趣的逻辑。这是⼀个例⼦:
语法 : RocketMQ 只定义了⼀些基本的语法来⽀持这个特性,也可以轻松扩展它。
msg对象创建之后,在发送之前做了一件事情,叫做msg.putUserProperty。也就是它存放着用户属性,这个属性是我们定义的属性。这个属性是一对键值对,可以放任意的键和任意的值,
之后往msg对象里面放入了键和值。每条消息有个键叫做a,创建了15个消息,每个消息键a对应的值都是不一样的。m1 a 0,m2 a 1,m3 a 2。这样的消息就会发送给broker。
很显然现在要去过滤a的键它的值是什么样的范畴。
消费者这边去订阅主题,同时消费者这边加上了一句话,意思就是tag不能是空的,并且tag是在a和b之间的。并且后面还带上了逻辑a属性不能为空。消费者其实是去消费TagA和TagB,并且0-3之间消息消费到。
要想现在实现这个效果,在broker里面配置加上下面配置,然后重启broker即可,那么sql的消息过滤就可以实现了