RocketMQ Broker 消息拉取原理

版本:4.2.0,源码:class文件

consumer拉取消息发送请求的RemotingCommand的code为11

RemotingCommand request = RemotingCommand.createRequestCommand(11, requestHeader)

broker启动时会注册一系列的processor

BrokerController

public boolean initialize() throws CloneNotSupportedException {
        。。。
        this.pullMessageExecutor = new BrokerFixedThreadPoolExecutor(this.brokerConfig.getPullMessageThreadPoolNums(), this.brokerConfig.getPullMessageThreadPoolNums(), 60000L, TimeUnit.MILLISECONDS, this.pullThreadPoolQueue, new ThreadFactoryImpl("PullMessageThread_"));
        。。。
        this.registerProcessor();
        。。。
}
public void registerProcessor() {
    。。。
    this.remotingServer.registerProcessor(11, this.pullMessageProcessor, this.pullMessageExecutor);
    this.pullMessageProcessor.registerConsumeMessageHook(this.consumeMessageHookList);
    。。。
}
public void registerProcessor(int requestCode, NettyRequestProcessor processor, ExecutorService executor) {
    ExecutorService executorThis = executor;
    if (null == executor) {
        executorThis = this.publicExecutor;
    }
​
    Pair<NettyRequestProcessor, ExecutorService> pair = new Pair(processor, executorThis);
    // processor和线程池缓存到本地
    this.processorTable.put(requestCode, pair);
}

从上面的源码可以知道的是,broker处理consumer拉取消息的processor是pullMessageProcessor,用的线程池是pullMessageExecutor,线程池的任务队列是pullThreadPoolQueue。

 

broker处理拉取请求是通过长轮询的方式,consumer发起请求,broker接受到请求会look一下是否有消息,如果有消息就直接返回给consumer,如果没有消息,broker不会断开连接,5秒之后会再检查是否有消息,不管是否有消息都会响应consumer。

 

两种情况:

1.consumer发起请求,broker接受到请求,处理完就响应consumer

 

netty接收请求

NettyRemotingAbstract

public void processMessageReceived(ChannelHandlerContext ctx, RemotingCommand msg) throws Exception {
    if (msg != null) {
        switch(msg.getType()) {
            case REQUEST_COMMAND:
                // 处理请求
                this.processRequestCommand(ctx, msg);
                break;
            case RESPONSE_COMMAND:
                this.processResponseCommand(ctx, msg);
        }
    }
​
}

processRequestCommand

public void processRequestCommand(final ChannelHandlerContext ctx, final RemotingCommand cmd) {
    // 根据code匹配到对应的processor和线程池
    // processorTable在服务启动的时候初始化
    Pair<NettyRequestProcessor, ExecutorService> matched = (Pair)this.processorTable.get(cmd.getCode());
    final Pair<NettyRequestProcessor, ExecutorService> pair = null == matched ? this.defaultRequestProcessor : matched;
    final int opaque = cmd.getOpaque();
    RemotingCommand response;
    if (pair != null) {
        Runnable run = new Runnable() {
            public void run() {
                RemotingCommand response;
                try {
                    // 调用processor,11对应的processor是pullMessageProcessor
                    response = ((NettyRequestProcessor)pair.getObject1()).processRequest(ctx, cmd);
                    。。。
                } catch (Throwable var5) {
                    。。。
                }
​
            }
        };
        。。。
​
        try {
            RequestTask requestTask = new RequestTask(run, ctx.chan
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值