RocketMQ 基础教程-应用篇-消息过滤

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

消息者在进行消息订阅时,除了可以指定要订阅消息的Topic外,还可以对指定Topic中的消息根据指定条件进行过滤,即可以订阅比Topic更加细粒度的消息类型。

对于指定Topic消息的过滤有两种过滤方式:Tag过滤与SQL过滤。

1、Tag过滤

通过consumer的subscribe()方法指定要订阅消息的Tag。如果订阅多个Tag的消息,Tag间使用或运算符(双竖线||)连接。

    DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("CID_EXAMPLE");
    consumer.subscribe("TOPIC", "TAGA || TAGB || TAGC");

2、SQL过滤

SQL过滤是一种通过特定表达式对事先埋入到消息中的用户属性进行筛选过滤的方式。通过SQL过滤,可以实现对消息的复杂过滤。不过,只有使用PUSH模式的消费者才能使用SQL过滤。

SQL过滤表达式中支持多种常量类型与运算符。

支持的常量类型:

  • 数值:比如:123,3.1415
  • 字符:必须用单引号包裹起来,比如:'abc'
  • 布尔:TRUE 或 FALSE
  • NULL:特殊的常量,表示空

支持的运算符有:

  • 数值比较:>,>=,<,<=,BETWEEN,=
  • 字符比较:=,<>,IN
  • 逻辑运算 :AND,OR,NOT
  • NULL判断:IS NULL 或者 IS NOT NULL

默认情况下Broker没有开启消息的SQL过滤功能,需要在Broker加载的配置文件中添加如下属性,以开启该功能:

    enablePropertyFilter = true

在启动Broker时需要指定这个修改过的配置文件。

例如对于单机Broker的启动,其修改的配置文件是conf/broker.conf,启动时使用如下命令:

    sh bin/mqbroker -n localhost:9876 -c conf/broker.conf &

3、代码举例

3.1、定义Tag过滤Producer

    import org.apache.rocketmq.client.producer.DefaultMQProducer;
    import org.apache.rocketmq.client.producer.SendResult;
    import org.apache.rocketmq.common.message.Message;
    
    public class FilterByTagProducer {
        public static void main(String[] args) throws Exception {
            DefaultMQProducer producer = new DefaultMQProducer("pg");
            producer.setNamesrvAddr("rocketmqOS:9876");
            producer.start();
            String[] tags = {"myTagA", "myTagB", "myTagC"};
            for (int i = 0; i < 10; i++) {
                byte[] body = ("Hi," + i).getBytes();
                String tag = tags[i % tags.length];
                Message msg = new Message("myTopic", tag, body);
                SendResult sendResult = producer.send(msg);
                System.out.println(sendResult);
            }
            producer.shutdown();
        }
    }

3.2、定义Tag过滤Consumer

    import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
    import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
    import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
    import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
    import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
    import org.apache.rocketmq.common.message.MessageExt;
    
    import java.util.List;
    
    public class FilterByTagConsumer {
        public static void main(String[] args) throws Exception {
            DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("pg");
            consumer.setNamesrvAddr("rocketmqOS:9876");
            consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
            consumer.subscribe("myTopic", "myTagA || myTagB");
            consumer.registerMessageListener(new MessageListenerConcurrently() {
                @Override
                public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                    for (MessageExt me : msgs) {
                        System.out.println(me);
                    }
                    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                }
            });
            consumer.start();
            System.out.println("Consumer Started");
        }
    }

3.3、定义SQL过滤Producer

    import org.apache.rocketmq.client.producer.DefaultMQProducer;
    import org.apache.rocketmq.client.producer.SendResult;
    import org.apache.rocketmq.common.message.Message;
    
    public class FilterBySQLProducer {
        public static void main(String[] args) throws Exception {
            DefaultMQProducer producer = new DefaultMQProducer("pg");
            producer.setNamesrvAddr("rocketmqOS:9876");
            producer.start();
            for (int i = 0; i < 10; i++) {
                try {
                    byte[] body = ("Hi," + i).getBytes();
                    Message msg = new Message("myTopic", "myTag", body);
                    msg.putUserProperty("age", i + "");
                    SendResult sendResult = producer.send(msg);
                    System.out.println(sendResult);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            producer.shutdown();
        }
    }

3.4、定义SQL过滤Consumer

    import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
    import org.apache.rocketmq.client.consumer.MessageSelector;
    import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
    import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
    import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
    import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
    import org.apache.rocketmq.common.message.MessageExt;
    
    import java.util.List;
    
    public class FilterBySQLConsumer {
        public static void main(String[] args) throws Exception {
            DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("pg");
            consumer.setNamesrvAddr("rocketmqOS:9876");
            consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
            consumer.subscribe("myTopic", MessageSelector.bySql("age between 0 and 6"));
            consumer.registerMessageListener(new MessageListenerConcurrently() {
                @Override
                public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
                                                                ConsumeConcurrentlyContext context) {
                    for (MessageExt me : msgs) {
                        System.out.println(me);
                    }
                    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                }
            });
            consumer.start();
            System.out.println("Consumer Started");
        }
    }
RocketMQ是一款开源的分布式消息队列系统,而rocketmq-client-java是RocketMQ的Java客户端。 rocketmq-client-java提供了丰富的API,使得开发者可以方便地使用RocketMQ进行消息的发布和订阅。它支持多种消息发送模式,包括同步发送、异步发送和单向发送。同步发送保证了消息的可靠性和顺序性,异步发送提高了发送效率,而单向发送则不需要等待服务器的响应。此外,rocketmq-client-java还支持批量发送和延迟发送等特性,满足了不同场景下的需求。 rocketmq-client-java提供了多种消息消费模式,包括集群模式和广播模式。在集群模式下,多个消费者可以共同消费一个队列的消息,实现消息的负载均衡和高可用性;而在广播模式下,每个消费者都能收到所有队列的消息,适用于需要实时获得消息的场景。 rocketmq-client-java还提供了自动负载均衡和故障转移的功能。当消费者增减或者下线时,RocketMQ会自动进行负载均衡,保证每个消费者都能平均地消费消息。而当某个消费者出现故障时,RocketMQ会将该消费者的消息重新分配给其他正常工作的消费者,保证消息的可靠性和高可用性。 此外,rocketmq-client-java还支持消息过滤消息事务和顺序消息等高级特性。消息过滤可以根据指定的条件对消息进行过滤,只消费符合条件的消息消息事务可以保证消息的原子性,要么一起成功,要么一起失败。顺序消息可以保证按照发送顺序进行消费,避免了消息的乱序问题。 综上所述,rocketmq-client-java是RocketMQ的Java客户端,提供了丰富的API和多种特性,使得开发者可以方便地使用RocketMQ进行消息的发布和订阅,并满足不同场景下的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值