过滤消息的示例
在大多数情况下,标记是一种简单而有用的设计,用于选择所需的消息。例如:
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("CID_EXAMPLE");
consumer.subscribe("TOPIC", "TAGA || TAGB || TAGC");
消费者将收到包含TAGA、TAGB或TAGC的消息。但限制是一条消息只能有一个标记,这可能不适用于复杂的场景。在这种情况下,可以使用SQL表达式筛选出消息。
规范
SQL特性通过消息的属性进行一些计算。通过RocketMQ定义的语法,您可以实现一些有趣的逻辑。下面是一个例子:
------------
| message |
|----------| a > 5 AND b = 'abc'
| a = 10 | --------------------> Gotten
| b = 'abc'|
| c = true |
------------
------------
| message |
|----------| a > 5 AND b = 'abc'
| a = 1 | --------------------> Missed
| b = 'abc'|
| c = true |
------------
语法
RocketMeQ 只定义一些基础的语法,来支持这个SQL过滤的功能。您也可以很轻松地扩展它。
- 数字比较,例如
>
,>=
,<
,<=
,BETWEEN
,=
; - 字符比较,例如
=
,<>
,IN
; IS NULL
或IS NOT NULL
;- 逻辑运算
AND
,OR
,NOT
;
常量类型有:
- 数字, 例如123, 3.1415;
- 字符, 例如‘abc’, 必须带单引号;
NULL
, 特殊常量;- 布尔值,
TRUE
orFALSE
;
使用限制
只有Push Consumer能通过SQL92过滤消息. 这个接口是:
public void subscribe(final String topic, final MessageSelector messageSelector)
生产者示例
在发送消息时,您可以通过putUserProperty
方法,给消息设置属性,即properties.
DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");
producer.start();
Message msg = new Message("TopicTest",
tag,
("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET)
);
// 设置一些属性,可以是多个属性
msg.putUserProperty("a", String.valueOf(i));
SendResult sendResult = producer.send(msg);
producer.shutdown();
消费者示例
消费者可以使用MessageSelector.bySql,来利用SQL92规范过滤消息
.
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("please_rename_unique_group_name_4");
//只订阅有属性a,满足a>=0并且a<=3的消息
consumer.subscribe("TopicTest", MessageSelector.bySql("a between 0 and 3");
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();