rocketmq消息过滤

来源:互联网 发布:mac打开网页一直转圈 编辑:程序博客网 时间:2024/05/24 15:40

RocketMQ 执行过滤是在 Broker 端,Broker 所在的机器会启动多个 FilterServer 过滤进程;Consumer 启动后,会向 FilterServer 上传一个过滤的 Java 类;Consumer 从 FilterServer 拉消息,FilterServer 将请求转发给 Broker,FilterServer 从 Broker 收到消息后,按照 Consumer 上传的 Java 过滤程序做过滤,过滤完成后返回给 Consumer。这种过滤方法可以节省网络流量,但是增加了 Broker 的负担


首先我们需要在rocketmq 的我们需要在broker-*.properties文件里添加一句话filterServerNums=1

生产者代码:

package com.sun.activemq.filter;import com.alibaba.rocketmq.client.exception.MQClientException;import com.alibaba.rocketmq.client.producer.DefaultMQProducer;import com.alibaba.rocketmq.client.producer.SendResult;import com.alibaba.rocketmq.common.message.Message;/** *  * @ClassName: FilterProducer  * @Description: 生产者 * @author: Dell * @date: 2017-6-4 上午6:39:23 */public class FilterProducer {public static void main(String[] args) throws MQClientException {DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");producer.setNamesrvAddr("192.168.1.244:9876;192.168.1.245:9876;192.168.1.242:9876;192.168.1.243:9876");producer.start();try {for (int i = 0; i < 100; i++) {Message msg = new Message("TopicFilter7",// topic"TagA",// tag("Hello MetaQ").getBytes());// body//这个属性作为过滤的条件msg.putUserProperty("SequenceId", String.valueOf(i));SendResult sendResult = producer.send(msg);System.out.println(sendResult+","+String.valueOf(i));Thread.sleep(100);}}catch (Exception e) {e.printStackTrace();}producer.shutdown();}}

消费者代码:

package com.sun.activemq.filter;import java.io.UnsupportedEncodingException;import java.util.List;import com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;import com.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently;import com.alibaba.rocketmq.client.exception.MQClientException;import com.alibaba.rocketmq.common.MixAll;import com.alibaba.rocketmq.common.message.MessageExt;/** *  * @ClassName: FilterConsumer  * @Description: 消费者 * @author: sunqz * @date: 2017-6-4 上午6:38:59 */public class FilterConsumer {public static void main(String[] args) throws InterruptedException,MQClientException {DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupNamecc4");consumer.setNamesrvAddr("192.168.1.244:9876;192.168.1.245:9876;192.168.1.242:9876;192.168.1.243:9876");// 使用Java代码,在服务器做消息过滤String filterCode = MixAll.file2String("D:/Workspaces/rocket-simple/src/main/java/com/sun/activemq/filter/MessageFilterImpl.java");System.out.println(filterCode);//有了filter不用指定tag了 其实tag也可以作为过滤consumer.subscribe("TopicFilter7","com.sun.activemq.filter.MessageFilterImpl", filterCode);consumer.registerMessageListener(new MessageListenerConcurrently() {@Overridepublic ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {for(MessageExt mext : msgs) {            try {System.out.println("消费了一条消息:"+new String(mext.getBody(),"utf-8")+mext.getUserProperty("SequenceId"));} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();//消费失败告诉mq重新发送继续消费return ConsumeConcurrentlyStatus.RECONSUME_LATER;}             }             /*              * 告诉mq消费成功               */                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});/** * Consumer对象在使用之前必须要调用start初始化,初始化一次即可<br> */consumer.start();System.out.println("Consumer Started.");}}

过滤器:

package com.sun.activemq.filter;import com.alibaba.rocketmq.common.filter.MessageFilter;import com.alibaba.rocketmq.common.message.MessageExt;public class MessageFilterImpl implements MessageFilter {@Overridepublic boolean match(MessageExt msg) {String property = msg.getUserProperty("SequenceId");System.out.println(property);if (property != null) {int id = Integer.parseInt(property);if((id % 2) == 0) { return true;}}return false;}}

先启动消费者 ,再启动生产者,打印结果如下:

生产者打印部分结果:



消费者打印部分结果


原创粉丝点击