RocketMQ提供了两种消费模式,PUSH和PULL,大多数场景使用的是PUSH模式,这两种模式分别对应的是DefaultMQPushConsumer类和DefaultMQPullConsumer类。PUSH模式实际上在内部还是使用的PULL方式实现的,通过PULL不断地轮询Broker获取消息,当不存在新消息时,Broker会挂起PULL请求,直到有新消息产生才取消挂起,返回新消息。故此处主要讲解PUSH模式,即DefaultMQPushConsumer。
在业务应用层使用DefaultMQPushConsumer主要分两部分,首先是初始化DefaultMQPushConsumer对象并进行相关变量的设置;然后是启动DefaultMQPushConsumer;
一、初始化DefaultMQPushConsumer对象,并设置变量值:
1、以consumerGroup名称为参数初始化DefaultMQPushConsumer对象,在初始化的过程中,默认初始化MssageQueue分配策略AllocateMessageQueueAveragely赋值给DefaultMQPushConsumer. allocateMessageQueueStrategy变量;
2、设置NameServer值;
3、调用DefaultMQPushConsumer.setSubscription(Map<String, String> subscription)方法将应用层的topic-subExpression值存入DefaultMQPushConsumer.subscription:Map<String /* topic */, String /* sub expression */>变量中;
4、调用DefaultMQPushConsumer.subscribe(String topic, String subExpression)方法用于构建Consumer端的订阅数据SubscriptionData对象。
4.1)以consumerGroup、topic、subExpression为参数调用FilterAPI.buildSubscriptionData(String consumerGroup, String topic, String subExpression)方法构造SubscriptionData对象并返回:
A)初始化SubscriptionData对象,将topic赋值给该对象的topic变量;
B)检查subExpression是否为空或为"*",若是则给SubscriptionData对象的subString变量赋值为"*";
C)否则置subString变量为subExpression参数值;对于多个subExpression则以"||"分隔,将subExpression拆分成单个subExpression,并存入SubscriptionData.tagsSet:Set<String>集合中;并且将每个subExpression进行hash之后,存入SubscriptionData.codeSet :Set<Integer>集合中;
4.2)以topic和返回的SubscriptionData对象为K-V值存入DefaultMQPushConsumer.RebalancePushImpl.subscriptionInner:ConcurrentHashMap<String /* topic */, SubscriptionData>变量中;
4.3)调用MQClientInstance.sendHeartbeatToAllBrokerWithLock()方法,在该方法中,第一,向所有在MQClientInstance.brokerAddrTable列表中的Broker发送心跳消息;第二,向Filter过滤服务器发送REGISTER_MESSAGE_FILTER_CLASS请求码,更新过滤服务器中的Filterclass文件;
5、设置Conumser线程的最大值(DefaultMQPushConsumer. consumeThreadMax,默认为64)、最小值(DefaultMQPushConsumer.consumeThreadMin,默认为2