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;
  }