- 1.长轮询概述
- 背景:当broker端无数据时,即相应为空,consuemr不断拉取,对broker造成压力,那应该采用何种方式?
- 长轮循:长轮循并不是真正的推送;长轮循是传统的轮循技术的变种,但它允许模拟推送的机制在一些情况下:安全验证等。
- 2.Long Polling in RocketMq
-
-
1.consumer发送request,broker通过网络层拿到request后放入PullMessageProcessor执行。执行内容:1.做权限验证;2.通过commitlog && consumerQueue获取message,若获取结果是SUCCESS后,通过channel.writeAndFlush写回到consumer端。若获取结果是PULL_NO_FOUND,把该请求hold住,把PullRequest包装成PR参数,放入PullRequestHoldService的pullRequestTable(key:topic@queueid,value:list),而暂时不给consumer端响应。
-
2.producer发送数据,被网络层接收后由sendMessageProcessor处理,放入commitlog,无论是放入堆外内存或是pagecache,commitlog的maxOffset会变动,会触发reputMessageService,该service把commitlog中数据dispatch至commitQueue中,通知执行messageArrivingListener.arrving来通知PullRequestHoldService
-
3.PullRequestHoldService收到arrvintg通知,把之前hold住的pullRequest开始执行。
-
若是判断出消息已发送过,PullMessageHoldService会把pullRequest请求异步由PullMessageProcessor执行,且brokerAllowSuspend=false,表示不允许broker再次suspend。
-
若是pullRequest被hold的时间太久,也会把pullRequest请求异步由PullMessageProcessor执行,且把brokerAllowSuspend=false。
-
-
4.PullMessageProcessor针对再次放入的pullRequest,做权限验证,获取message,若判断是消息已发出,会返回SUCCESS;若是超时,可能仍会是PULL_NOT_FOUND,都会调用channel.writeAndFlush,写回给consumer端。
-
问题:PullRequestHoldService.suspendPullRequest,想要hold住的那条消息还未放入PullRequestTable中,但producer发送的这条消息已经过来,并开始通知了,hold住的那条消息会一直存在 PullRequestTable中,mq是如何处理?
-
request被hold的时间太久,强制唤醒,返回consumer端null,再次拉请求发送到broker,若仍是not found的话,则新一轮的hold住
-
-
-
3.FileRegion优化
- 零拷贝代码,设置isTransferMsgByHeap=false,会使用零拷贝技术。
七、RocketMQ消息长轮询(Longpolling)与FileRegion优化
最新推荐文章于 2023-07-05 09:13:04 发布