RocketMQ之消息的多种订阅方式&消息过滤器

目录

消息的消费(订阅全部)

消息的消费(订阅指定操作)

消息过滤器


 

消息的消费(订阅全部)

 

订阅时,我们设置通配符“*”意味订阅topic匹配的全部消息

package cn.itcast.rocketmq.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.message.MessageExt;
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;

import java.io.UnsupportedEncodingException;
import java.util.List;

public class ConsumerDemo {

    public static void main(String[] args) throws Exception {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("haoke-consumer");
        consumer.setNamesrvAddr("192.168.62.132:9876");

        // 订阅消息,接收的是所有消息
        consumer.subscribe("my-topic", "*");
        //consumer.subscribe("my-topic", "add || update");

        //consumer.setMessageModel(MessageModel.CLUSTERING);

        consumer.registerMessageListener(new MessageListenerConcurrently() {

            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List msgs,
                                                            ConsumeConcurrentlyContext context) {

                try {
                    for (MessageExt msg : msgs) {
                        System.out.println("消息:" + new String(msg.getBody(), "UTF-8"));
                    }
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }

                System.out.println("接收到消息 -> " + msgs);

                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });

        // 启动消费者
        consumer.start();

    }
}

 启动测试类

RocketMQ之消息的多种订阅方式&消息过滤器_第1张图片

 

 

 

消息的消费(订阅指定操作)

 

消费者可以根据topic的类型订阅。例如我们把通配符*换成add || update操作。意为消费者仅获取add和update操作的消息。然后我们先把消费者启动起来

package cn.itcast.rocketmq.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.message.MessageExt;
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;

import java.io.UnsupportedEncodingException;
import java.util.List;

public class ConsumerDemo {

    public static void main(String[] args) throws Exception {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("haoke-consumer");
        consumer.setNamesrvAddr("192.168.62.132:9876");

        // 订阅消息,接收的是所有消息
        //consumer.subscribe("my-topic", "*");
        consumer.subscribe("my-topic", "add || update");

        //consumer.setMessageModel(MessageModel.CLUSTERING);

        consumer.registerMessageListener(new MessageListenerConcurrently() {

            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List msgs,
                                                            ConsumeConcurrentlyContext context) {

                try {
                    for (MessageExt msg : msgs) {
                        System.out.println("消息:" + new String(msg.getBody(), "UTF-8"));
                    }
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }

                System.out.println("接收到消息 -> " + msgs);

                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });

        // 启动消费者
        consumer.start();

    }
}

 

然后我们在生产者类中修改发送的topic类型,我设置成了add。发送的消息内容为3

package cn.itcast.rocketmq.sendmsg;

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;

public class SyncProducer {
    public static void main(String[] args) throws Exception {
        //分组名haoke这个可以任意设置
        DefaultMQProducer producer = new DefaultMQProducer("haoke");

        //设置nameserver的地址
        producer.setNamesrvAddr("192.168.62.132:9876");

        //启动生产者
        producer.start();

        //发送消息
        String msg = "我的第一个消息3!";
        Message message = new Message("my-topic", "add", msg.getBytes("UTF-8"));
        SendResult sendResult = producer.send(message);
        System.out.println("消息id: " + sendResult.getMsgId());
        System.out.println("消息队列: " + sendResult.getMessageQueue());
        System.out.println("消息offset值: " + sendResult.getQueueOffset());
        System.out.println(sendResult);
        producer.shutdown();
    }
}

可以看到消费者接收到了

假如我们不更改发送者的topic类型,用mytag作为要发送的tags,消息内容为4。由于tags匹配不上,发送的消息就会被消费者过滤掉了。

 

 

消息过滤器

 

通过tags标签过滤粒度比较大,raocketmq为我们提供了基于属性的过滤器机制,它更加强大,消费者在过滤时通过近似sql语句的方式进行过滤。

使用filter有前提,rocketmq默认是不支持自定义过滤的,需要先进入到broker.conf文件中

vim /haoke/rmq/rmqbroker/conf/broker.conf

你需要在broker的配置文件中新增一行内容

然后你需要重启broker服务

docker restart rmqbroker

 

接下来我们新建消费者。这里我过滤的条件是必须在名为my-topic-filter的分组下,sex字段限定为女,age字段限定为18。否则消费者不接收

package cn.itcast.rocketmq.filter;

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.message.MessageExt;

import java.io.UnsupportedEncodingException;
import java.util.List;

public class ConsumerFilter {

    public static void main(String[] args) throws Exception {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("haoke-consumer");
        consumer.setNamesrvAddr("192.168.62.132:9876");

        // 订阅消息,接收的是所有消息
//        consumer.subscribe("my-topic", "*");
        consumer.subscribe("my-topic-filter", MessageSelector.bySql("sex='女' AND age>=18"));

        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List msgs,
                                                            ConsumeConcurrentlyContext context) {

                try {
                    for (MessageExt msg : msgs) {
                        System.out.println("消息:" + new String(msg.getBody(), "UTF-8"));
                    }
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }

                System.out.println("接收到消息 -> " + msgs);

                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });

        // 启动消费者
        consumer.start();

    }
}

 

我们再新建消息生产者类。我们先限定topic分组和消费者一致,然后发送的参数通过message.putUserProperty来设定。

package cn.itcast.rocketmq.filter;

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;

public class SyncProducer {

    public static void main(String[] args) throws Exception {
        DefaultMQProducer producer = new DefaultMQProducer("haoke");

        producer.setNamesrvAddr("192.168.62.132:9876");

        producer.start();

        //发送消息
        String msg = "这是一个用户的消息, id = 1001";
        Message message = new Message("my-topic-filter", "delete", msg.getBytes("UTF-8"));
        message.putUserProperty("sex","女");
        message.putUserProperty("age","18");
        SendResult sendResult = producer.send(message);
        System.out.println("消息id:" + sendResult.getMsgId());
        System.out.println("消息队列:" + sendResult.getMessageQueue());
        System.out.println("消息offset值:" + sendResult.getQueueOffset());
        System.out.println(sendResult);

        producer.shutdown();
    }
}

测试一下,可以看到。消费者顺利拿到了消息。

RocketMQ之消息的多种订阅方式&消息过滤器_第2张图片

 

 

 

你可能感兴趣的:([RocketMQ])