在大多数情况下,TAG是一个简单而有用的设计,其可以来选择您想要的消息。例如:
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 |
------------
基本语法
RocketMQ只定义了一些基本语法来支持这个特性。你也可以很容易地扩展它。
- 数值比较,比如:>,>=,<,<=,BETWEEN,=;
- 字符比较,比如:=,<>,IN;
- IS NULL 或者 IS NOT NULL;
- 逻辑符号 AND,OR,NOT;
常量支持类型为:
- 数值,比如:123,3.1415;
- 字符,比如:'abc',必须用单引号包裹起来;
- NULL,特殊的常量
- 布尔值,TRUE 或 FALSE
只有使用push模式的消费者才能用使用SQL92标准的sql语句,接口如下:
public void subscribe(finalString topic, final MessageSelector messageSelector)
生产者样例
public class Producer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("sql_producer_group");
producer.setNamesrvAddr("106.15.42.999:9876");
producer.start();
for (int i = 0; i < 10; i++) {
/**
* 4.创建消息对象,指定主题Topic、Tag和消息体
* 参数一:消息主题Topic
* 参数二:消息Tag
* 参数三:消息内容
*/
Message message = new Message("TopicSQL", "SQL", ("hello .... " + i).getBytes(StandardCharsets.UTF_8));
message.putUserProperty("a", String.valueOf(i));
SendResult sendResult = producer.send(message);
System.out.println("发送结果: " + sendResult);
}
}
}
消费者样例
public class Consumer {
public static void main(String[] args) throws Exception {
// 创建消费者Consumer,制定消费者组名
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("sql_consumer_group");
// 指定Nameserver地址
consumer.setNamesrvAddr("106.15.42.148:9876");
// 订阅主题和tag
consumer.subscribe("TopicSQL", MessageSelector.bySql("a between 0 and 3"));
// 设置回调函数处理消息
consumer.registerMessageListener(new MessageListenerConcurrently() {
// 接受消息内容
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
for (MessageExt message : list) {
try {
String topic = message.getTopic();
String tags = message.getTags();
byte[] body = message.getBody();
String result = new String(body, RemotingHelper.DEFAULT_CHARSET);
System.out.println("Consumer消费信息:topic:" + topic + ",tags:" + tags + ",result:" + result);
} catch (Exception e) {
e.printStackTrace();
}
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();
}
}