public void processRequestCommand(final ChannelHandlerContext ctx, final RemotingCommand cmd) { final Pair<NettyRequestProcessor, ExecutorService> matched = this.processorTable.get(cmd.getCode()); final Pair<NettyRequestProcessor, ExecutorService> pair = null == matched ? this.defaultRequestProcessor : matched; if (pair != null) { Runnable run = new Runnable() { @Override public void run() { try { RPCHook rpcHook = NettyRemotingAbstract.this.getRPCHook(); if (rpcHook != null) { rpcHook.doBeforeRequest( RemotingHelper.parseChannelRemoteAddr(ctx.channel()), cmd); } final RemotingCommand response = pair.getObject1().processRequest(ctx, cmd); if (rpcHook != null) { rpcHook.doAfterResponse(cmd, response); } // Oneway形式忽略应答结果 if (!cmd.isOnewayRPC()) { if (response != null) { response.setOpaque(cmd.getOpaque()); response.markResponseType(); try { ctx.writeAndFlush(response); } catch (Throwable e) { plog.error("process request over, but response failed", e); plog.error(cmd.toString()); plog.error(response.toString()); } } else { // 收到请求,但是没有返回应答,可能是processRequest中进行了应答,忽略这种情况 } } } catch (Throwable e) { plog.error("process request exception", e); plog.error(cmd.toString()); if (!cmd.isOnewayRPC()) { final RemotingCommand response = RemotingCommand.createResponseCommand( RemotingSysResponseCode.SYSTEM_ERROR, // RemotingHelper.exceptionSimpleDesc(e)); response.setOpaque(cmd.getOpaque()); ctx.writeAndFlush(response); } } } }; try { // 这里需要做流控,要求线程池对应的队列必须是有大小限制的 pair.getObject2().submit(run); } catch (RejectedExecutionException e) { plog.warn( RemotingHelper.parseChannelRemoteAddr(ctx.channel()) // + ", too many requests and system thread pool busy, RejectedExecutionException " // + pair.getObject2().toString() // + " request code: " + cmd.getCode()); if (!cmd.isOnewayRPC()) { final RemotingCommand response = RemotingCommand.createResponseCommand( RemotingSysResponseCode.SYSTEM_BUSY, "too many requests and system thread pool busy, please try another server"); response.setOpaque(cmd.getOpaque()); ctx.writeAndFlush(response); } } } else { String error = " request type " + cmd.getCode() + " not supported"; final RemotingCommand response = RemotingCommand.createResponseCommand( RemotingSysResponseCode.REQUEST_CODE_NOT_SUPPORTED, error); response.setOpaque(cmd.getOpaque()); ctx.writeAndFlush(response); plog.error(RemotingHelper.parseChannelRemoteAddr(ctx.channel()) + error); } }
private RemotingCommand pullMessageForward( final ChannelHandlerContext ctx, final RemotingCommand request) throws Exception { final RemotingCommand response = RemotingCommand.createResponseCommand(PullMessageResponseHeader.class); final PullMessageResponseHeader responseHeader = (PullMessageResponseHeader) response.readCustomHeader(); final PullMessageRequestHeader requestHeader = (PullMessageRequestHeader) request.decodeCommandCustomHeader(PullMessageRequestHeader.class); // 由于异步返回,所以必须要设置 response.setOpaque(request.getOpaque()); DefaultMQPullConsumer pullConsumer = this.filtersrvController.getDefaultMQPullConsumer(); final FilterClassInfo findFilterClass = this.filtersrvController .getFilterClassManager() .findFilterClass(requestHeader.getConsumerGroup(), requestHeader.getTopic()); if (null == findFilterClass) { response.setCode(ResponseCode.SYSTEM_ERROR); response.setRemark("Find Filter class failed, not registered"); return response; } if (null == findFilterClass.getMessageFilter()) { response.setCode(ResponseCode.SYSTEM_ERROR); response.setRemark("Find Filter class failed, registered but no class"); return response; } responseHeader.setSuggestWhichBrokerId(MixAll.MASTER_ID); // 构造从Broker拉消息的参数 MessageQueue mq = new MessageQueue(); mq.setTopic(requestHeader.getTopic()); mq.setQueueId(requestHeader.getQueueId()); mq.setBrokerName(this.filtersrvController.getBrokerName()); long offset = requestHeader.getQueueOffset(); int maxNums = requestHeader.getMaxMsgNums(); final PullCallback pullCallback = new PullCallback() { @Override public void onSuccess(PullResult pullResult) { responseHeader.setMaxOffset(pullResult.getMaxOffset()); responseHeader.setMinOffset(pullResult.getMinOffset()); responseHeader.setNextBeginOffset(pullResult.getNextBeginOffset()); response.setRemark(null); switch (pullResult.getPullStatus()) { case FOUND: response.setCode(ResponseCode.SUCCESS); List<MessageExt> msgListOK = new ArrayList<MessageExt>(); try { for (MessageExt msg : pullResult.getMsgFoundList()) { boolean match = findFilterClass.getMessageFilter().match(msg); if (match) { msgListOK.add(msg); } } // 有消息返回 if (!msgListOK.isEmpty()) { returnResponse( requestHeader.getConsumerGroup(), requestHeader.getTopic(), ctx, response, msgListOK); return; } // 全部都被过滤掉了 else { response.setCode(ResponseCode.PULL_RETRY_IMMEDIATELY); } } // 只要抛异常,就终止过滤,并返回客户端异常 catch (Throwable e) { final String error = String.format( "do Message Filter Exception, ConsumerGroup: %s Topic: %s ", requestHeader.getConsumerGroup(), requestHeader.getTopic()); log.error(error, e); response.setCode(ResponseCode.SYSTEM_ERROR); response.setRemark(error + RemotingHelper.exceptionSimpleDesc(e)); returnResponse( requestHeader.getConsumerGroup(), requestHeader.getTopic(), ctx, response, null); return; } break; case NO_MATCHED_MSG: response.setCode(ResponseCode.PULL_RETRY_IMMEDIATELY); break; case NO_NEW_MSG: response.setCode(ResponseCode.PULL_NOT_FOUND); break; case OFFSET_ILLEGAL: response.setCode(ResponseCode.PULL_OFFSET_MOVED); break; default: break; } returnResponse( requestHeader.getConsumerGroup(), requestHeader.getTopic(), ctx, response, null); } @Override public void onException(Throwable e) { response.setCode(ResponseCode.SYSTEM_ERROR); response.setRemark("Pull Callback Exception, " + RemotingHelper.exceptionSimpleDesc(e)); returnResponse( requestHeader.getConsumerGroup(), requestHeader.getTopic(), ctx, response, null); return; } }; pullConsumer.pullBlockIfNotFound(mq, null, offset, maxNums, pullCallback); return null; }