版本: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