RocketMQ消费\生产消息的过程

这几天在看RocketMQ的知识,跟踪了下源码,弄清楚了MQ生产和消费消息的流程,这里记录下MQ消费消息的过程。

1:RebalanceService线程构造PullRequest并将request放入pullRequestQueue,而PullRequest的具体信息来源于topicSubscribeInfoTable

2:PullRequest放入pullRequestQueue后由PullMessageService线程从pullRequestQueue阻塞取出然后将请求构造成PullMessageRequestHeader,然后交给MQClient发送请求,发送请求就不必跟下去了底层就是通过Netty通信,如果要看Netty是如何通信的可以看我之前写关于Dubbo的provider和consumer交互的博客。如果是异步发送的话在构造PullMessageRequestHeader之前将会new一个PullCallback,用于处理返回结果(见下面第二张图)。

 

 

3:在broker端,经过Netty接收消息并对消息解码后,把pull请求交给PullMessageThread_X处理。通过CommitLog获取结果,而commitLog则是在之前存入消息的MappedFile中获取对应的消息。

4:broker返回结果后会通过之前提到的PullCallback的onSuccess方法来处理响应(见上面第2点的第二张图)并将响应构造成一个ConsumeRequest(注意这个request实现了Runable接口的)然后交给consumeExecutor处理,consumeExecutor会执行request的Run方法,并最终将响应交给在consumer中注册的MessageListenerConcurrently实例去处理(见下图3)。

5:消息生成从producer传送到broker保存的过程就相对要简单些,一样地在producer端需要根据topicPublishInfo中的信息选择一个broker的特定队列,然后构造SendMessageRequestHeader最终交给MQClient发送消息。

6:broker通过Netty接受消息并解码后,将消息交给SendMessageThread_X线程来处理请求,在将消息写入MappedFile之前为了防止多线程同时向MappedFile写消息,所以用了一个putMessageLock锁,注意下图最下面的红色的框中,当MappedFile写完后,系统将会再创建一个MappedFile继续写消息。

7:向MappedFile写入消息后还有两个重要的操作就是通知刷盘,和HA处理。下图二是刷盘的代码,其实异步刷盘的操作很简单只是通过wakeup()方法通知定时刷盘服务可以刷盘了。普通消息(非事务消息)的定时刷盘服务由FlushRealTimeService来完成的。

8 上面7介绍了一个消息正常的生命周期,那么非正常的处理有哪些呢?在broker启动时会启动一个清理过期请求的服务,其会清理四种类型的请求,如果你收到了[TIMEOUT_CLEAN_QUEUE]broker busy, start flow control for a while, period in queue: %sms, size of queue: %d 这种消息,那么肯定就是消息在队列中过期被清理掉了(见下面第三张图)默认的SendQueue的过期时间是200ms其可以通过配置waitTimeMillsInSendQueue=200来改变过期时间。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值