RocketMQ使用Filter问题!
OK,我们在使用RocketMQ的Filter服务时候,需要注意一些问题,如题我们迅速开始吧!
首先,我们需要启动我们的MQ服务,顺序为 namesrv、broker、filter。我配置的为:2m-2s-async(也就是两主两从模式)
我们需要在broker-*.properties文件里添加一句话,如下:
filterServerNums=1
其实我们也可以手工的去启动filter!
接下来:
马上进行建立rocketMQAPI工程,然后引入jar,可从github上来下载demo,地址为:https://github.com/alibaba/RocketMQ ,如图所示:
首先看一下product端代码,如下:发送100条消息到broker。
package bhz.mq.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; public class Producer { public static void main(String[] args) throws MQClientException, InterruptedException { String group_name = "filter_producer"; DefaultMQProducer producer = new DefaultMQProducer(group_name); producer.setNamesrvAddr("192.168.1.111:9876;192.168.1.112:9876;192.168.1.113:9876;192.168.1.114:9876"); producer.start(); try { for (int i = 0; i < 100; i++) { Message msg = new Message("TopicFilter7",// topic "TagA",// tag "OrderID001",// key ("Hello MetaQ" + i).getBytes());// body msg.putUserProperty("SequenceId", String.valueOf(i)); SendResult sendResult = producer.send(msg); System.out.println(sendResult); } } catch (Exception e) { e.printStackTrace(); } producer.shutdown(); } }
接下来我们看一下consumer代码,如下:需要注意的一点是我们所上传的过滤器类里,一定不允许有中文,否则MixAll.file2String方法返回null,Filter不识别!!!!
package bhz.mq.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.consumer.ConsumeFromWhere; import com.alibaba.rocketmq.common.message.MessageExt; public class Consumer { public static void main(String[] args) throws InterruptedException, MQClientException { String group_name = "filter_consumer"; DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(group_name); consumer.setNamesrvAddr("192.168.1.111:9876;192.168.1.112:9876;192.168.1.113:9876;192.168.1.114:9876"); // 使用Java代码,在服务器做消息过滤 String filterCode = MixAll.file2String("D:\\workspace_001\\rocketmqAPI\\src\\bhz\\mq\\filter\\MessageFilterImpl.java"); System.out.println(filterCode); consumer.subscribe("TopicFilter7", "bhz.mq.filter.MessageFilterImpl", filterCode); consumer.registerMessageListener(new MessageListenerConcurrently() { @Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) { //System.out.println(Thread.currentThread().getName() + " Receive New Messages: " + msgs); try { System.out.println(new String(msgs.get(0).getBody(),"utf-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } }); consumer.start(); System.out.println("Consumer Started."); } }
OK 最后我们看一下MessageFilterImpl这个类:再次强调一下,注意这个类是上传到FilterSrv的,不要有中文,上面说了不然MixAll.file2String方法返回null。
package bhz.mq.filter; import com.alibaba.rocketmq.common.filter.MessageFilter; import com.alibaba.rocketmq.common.message.MessageExt; public class MessageFilterImpl implements MessageFilter { @Override public boolean match(MessageExt msg) { // NO Chinese System.out.println("-------------"); String property = msg.getUserProperty("SequenceId"); System.out.println("---------" + property); if (property != null) { int id = Integer.parseInt(property); if((id % 2) == 0) { //if ((id % 3) == 0 && (id > 10)) { return true; } } return false; } }
OK。我们进行测试,先运行consumer,然后运行producer发送数据,这样就好根据MessageFilterImpl的代码过滤出来 id % 2 == 0 的所有数据给Consumer端消费了!
最后我们总结下:我们一般是一个broker上配置多个filter服务,其实就是用cpu换取宝贵网卡的资源!