RocketMQ—消费者

消费者启动

消费者启动

RebalanceService

负载均衡服务。
一个消息队列仅能被一个消费者消费,但一个消费者可以同时消费多个消息队列。这就涉及到如何将多个消息队列分配给等多个消费者的问题。

RebalanceService来专门处理多个消息队列和消费者的对应关系,并且提供了多个不同的消费者负载均衡策略,即如何分配消息队列给这些消费者。

有三种情况会触发Consumer进行负载均衡或者说重平衡:

  1. RebalanceService服务是一个线程任务,由MQClientInstance启动,其每隔20s自动进行一次自动负载均衡
  2. Broker触发的重平衡
    1. Broker收到心跳请求之后如果发现消息中有新的consumer连接或者consumer订阅了新的topic或者移除了topic的订阅, 则Broker发送Code为NOTIFY_CONSUMER_IDS_CHANGED的请求给该group下面的所有Consumer,要求进行一次负载均衡。
    2. 如果某个客户端连接出现连接异常事件EXCEPTION、连接断开事件CLOSE、或者连接闲置事件IDLE,则Broker同样会发送重平衡请求给消费者组下面的所有消费者。
  3. 新的Consumer服务启动的时候,主动调用rebalanceImmediately唤醒负载均衡服务rebalanceService,进行重平衡。

通过负载均衡算法为当前消费者分配了新的消息队列之后,需要更新新分配的消息队列MessageQueue和处理队列ProcessQueue的关系。在更新时,如果是顺序消费,调用lock方法请求broker锁定该队列。如果锁定失败,表示新增消息队列失败,这个队列可能还再被其他消费者消费,那么本次重平衡就不再消费该队列。

对于新分配到的消费队列,会新建PullRequest,这些PullRequest将会被存入PullMessageService服务内部的pullRequestQueue阻塞队列中,后续异步的消费,自动执行拉取消息的请求,这就是Push模式下最初的拉消息请求的来源。

消费者拉取消息

消费者拉取消息
为了提高效率,会为每个 Topic 在~/store/consumequeue中创建一个目录,目录名为 Topic 名称。在该 Topic 目录下,会再为每个该Topic 的 Queue 建立一个目录,目录名为 queueId。每个目录中存放着若干 consumequeue 文件,consumequeue 文件是 commitlog 的索引文件,可以根据 consumequeue 定位到具体的消息。

commitlog 真正存储消息的⽂件。

消费者消费消息

消费线程池,最小、最大线程数默认20,阻塞队列为无界阻塞队列LinkedBlockingQueue

消费者获取到消息后包装成ConsumeRequest提交到并发消费线程池。ConsumeRequest实现Runnable接口,并发消费和顺序消费是两个不同的ConsumeRequest

并发消费

并发消费

顺序消费

顺序消费
顺序消费服务ConsumeMessageOrderlyService在启动时,会启动一个定时任务,该定时任务请求Broker进行对MessageQueue的锁定,只有锁定成功的MessageQueue,对应的ProcessQueue才会设置为锁定状态

顺序消费在ConsumeRequest执行时,才会从ProcessQueue拿消息。

小结

多线程和顺序性。顺序消费和并发消费实际上都是使用线程池消费,但是不同的是,对于同一个消息队列的消息,并发消费可能有多条线程并发的消费消息,提升了消息速度,但是没有顺序性。

顺序消费则通过一系列锁,保证同一时刻对于同一个队列只有一个线程去消费它,注意是“只有一个线程”而不是“同一个线程”,因此有可能你先发送的消息被ThreadA消费了,但是你发送的的第二个消息被ThreadB消费了,这是完全正确的,因为他们并不是同时消费的。但是对于不同的队列,顺序消费则不能保证消费有序性,因为不同的队列有不同的锁。

消息重试

并发消费和顺序消费对于消费失败的消息均会有消息重试机制

顺序消费的保证

  1. broker端的分布式锁
  2. messageQueue的本地synchronized锁
  3. ProcessQueue的本地consumeLock
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值