作用:Consumer端可以重写MessageFilter的match方法,来在消费端做进一步的过滤,进而也可以实现负载均衡等功能。
例如下面Consumer端代码:
public class Consumer {
public static void main(String[] args) throws InterruptedException, MQClientException {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupNamecc4");
consumer.setNamesrvAddr("localhost:20881");
/**
* 使用Java代码,在服务器做消息过滤
*/
consumer.subscribe("TopicFilter7","MessageFilterImpl","import com.alibaba.rocketmq.common.filter.MessageFilter;\n" +
"import com.alibaba.rocketmq.common.message.MessageExt;\n" +
"\n" +
"\n" +
"public class MessageFilterImpl implements MessageFilter {\n" +
"\n" +
" @Override\n" +
" public boolean match(MessageExt msg) {\n" +
" String property = msg.getUserProperty(\"SequenceId\");\n" +
" if (property != null) {\n" +
" int id = Integer.parseInt(property);\n" +
" if ((id % 3) == 0 && (id > 10)) {\n" +
" return true;\n" +
" }\n" +
" }\n" +
"\n" +
" return false;\n" +
" }\n" +
"}");
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
ConsumeConcurrentlyContext context) {
System.out.println(Thread.currentThread().getName() + " Receive New Messages: " + msgs);
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
/**
* Consumer对象在使用之前必须要调用start初始化,初始化一次即可<br>
*/
consumer.start();
System.out.println("Consumer Started.");
}
}
FilterSrv注册到broker过程:
1、一个filterSrv需要指定一个broker
FiltersrvConfig方法
// 连接到哪个Broker
private String connectWhichBroker = "127.0.0.1:10911";
// 连接到哪个Broker
private String connectWhichBroker = "127.0.0.1:10911";
2、而一个broker是可以put多个filterSrv
registerFilterServer,
将filtersrv信息封装成了FilterServerInfo
并且放到了filterServerTable
一个 Map
对象中
filterServerInfo = new FilterServerInfo();
filterServerInfo.setFilterServerAddr(filterServerAddr);
filterServerInfo.setLastUpdateTimestamp(System.currentTimeMillis());
this.filterServerTable.put(channel, filterServerInfo);
3、broker注册到nameSrv
broker将自己注册到nameSrv时,也会将属于自己的filterSrv注册到nameSrv。
同理,client通过nameSrv查找对应topic的broker时,也会找到该broker对应的filterSrv,因为该filterSrv属于该broker
4、client端如何通过topic查找到对应broker
nameSrv代码是RockerMQ里最简洁的代码,只有9个类,而DefaultRequestProcessor一个类的processRequest方法就处理来自client和broker的所有请求,processRequest是根据传过来的RemotingCommand里的getCode的不同值来执行不同的操作,比如code为REGISTER_BROKER时,表示broker注册nameSrv,然后会判断MQ的版本,3.0.11版本之后支持通过filterSrv注册broker到nameSrv。
如果code为GET_ROUTEINTO_BY_TOPIC,表示client要根据topic获取broker信息,getRouteInfoByTopic-->pickupTopicRouteData获取TopicRouteData信息,