1: consumer会每30s从nameserver上更新所订阅的topic路由列表,同时会更新broker路由->brokerName与角色和地址关系
2: consumer会每30s与所有broker进行一次心跳,将clientid,topic,group发送至broker
rebalance开始: consumer会每10s进行一次rebalance
1 首先选择一个broker,根据topic和group查询到订阅此topic的属于同一group的所有的consumer clientid
2 根据rebalance策略,进行分配.rebalance完毕之后,就可以知道当前的consumer消费哪些broker的哪些queue
重点在步骤4和5.1和5.2,现在只针对一个broker做一下分析:
假设consumer1先启动,对于broker_a一开始关系是group1->topic1
当consumer2启动并rebalance完成后,consumer2发送group1->topic2,
在步骤4,会根据group1将原先的group1->topic1取出。
在步骤5.1,添加topic2
在步骤5.2,移除topic1
这个对应关系呢,对应着一个重要的对象,如下图,对于上面rebalance之后的结果会产生8个PullRequest对象,分别对应8个队列:
PullMessageService为一个阻塞队列服务,其内有一个线程不断轮询队列,获取PullRequest对象,调用DefaultMQPushConsumerImpl进行消息拉取
DefaultMQPushConsumerImpl消息拉取前进行状态,参数校验和准备,并负责构造回调实例PullCallback进行消息的消费. 调用PullAPIWrapper进行消息拉取
PullAPIWrapper主要负责broker路由的解析,压力均衡
NettyRemotingClient为netty封装,负责与broker通信,并在结果返回后回调PullCallback
PullCallback对返回的结果进行解码,更新下次拉取的偏移量,并调用ConsumeMessageService触发客户端消费,它还会将PullRequest放回PullMessageService,从而形成一个循环.
ConsumeMessageService负责调用客户端的并发消费或顺序消费,并处理消费的结果.
对于广播模式,消费失败的消息不作处理
对于集群模式,消费失败的发到重试队列,发送失败的尝试让客户端继续消费
对于集群模式,消费失败的消息且重试次数>16,则发往DLQ,表示该消息不再重试,为死消息.
rebalance中,如果topic路由发生变化,会新生成PullRequest,其中的属性netxOffset采用用户设置的ConsumeFromWhere,计算响应的偏移量.
首先说下集群消费模式下的offset请求:
针对返回的offset>=0的情况,三种消费位置都直接接受,即从offset处消费
只有对于offset<0的情况(即这个topic的queue没有被此group消费过,或者说这个group第一次启动)不一样:
CONSUME_FROM_LAST_OFFSET: 会继续拉取队列的最大偏移量作为消费的起始位置
CONSUME_FROM_FIRST_OFFSET: 消费的起始位置为0
CONSUME_FROM_TIMESTAMP: 首先根据时间戳定位到consumerqueue的位置文件上,通过二分查找法遍历commitlog中的消息的时间戳,查找起始位置
广播模式与集群模式类似,唯一不同的是不会从broker查询,而是从本地文件查询offset
原文链接:https://blog.csdn.net/a417930422/article/details/50663639