第九章-Broker-接收并处理生产者发送的消息

要找到生产者发送的消息被谁接收了,就得先确定两件事情:

1、发送消息使用的请求码?

答:从章节3.5.1中,可以得出该请求码是,RequestCode.SEND_MESSAGE。

2、Broker端针对发送消息使用的处理器?

答:从章节8.5中,可以得出处理器是 SendMessageProcessor,并且直接进到 processRequest 方法。

至此,两个必要条件已经确定,接下来就看源码怎么实现了。

public RemotingCommand processRequest(ChannelHandlerContext ctx,
                                      RemotingCommand request) throws RemotingCommandException {
   
    SendMessageContext mqtraceContext;
    switch (request.getCode()) {
   
        case RequestCode.CONSUMER_SEND_MSG_BACK: // 这个是消费失败重推请求码,不在此次范围内
            return this.consumerSendMsgBack(ctx, request);
        default:// 既然是default,那指定是包括了请求码 RequestCode.SEND_MESSAGE,往下走就行
            // 解析请求命令,并转换成broker内部识别的发送消息请求对象,这个方法在 AbstractSendMessageProcessor 类中
            SendMessageRequestHeader requestHeader = parseRequestHeader(request);
            if (requestHeader == null) {
   
                // 请求都为 null 了,那指定返回 null
                return null;
            }
		   // 构建消息追踪对象
            mqtraceContext = buildMsgContext(ctx, requestHeader);
            // 发送消息前调用,其实这个hook就是给用户扩展的,类似拦截器,用户自定义一个类,并实现接口 SendMessageHook 就行
            this.executeSendMessageHookBefore(ctx, request, mqtraceContext);

            RemotingCommand response;
            if (requestHeader.isBatch()) {
   
                // 批量消息的处理,具体看章节`9.2`
                response = this.sendBatchMessage(ctx, request, mqtraceContext, requestHeader);
            } else {
   
                // 单个消息的处理,具体看章节`9.1`
                response = this.sendMessage(ctx, request, mqtraceContext, requestHeader);
            }

            // 发送消息后调用,hook就是给用户扩展的,类似拦截器,用户自定义一个类,并实现接口 SendMessageHook 就行
            this.executeSendMessageHookAfter(response, mqtraceContext);
            return response;
    }
}

AbstractSendMessageProcessor.parseRequestHeader

// 这是一个 protected 方法,实际上就是想着子类重写的方法
protected SendMessageRequestHeader parseRequestHeader(RemotingCommand request)
    throws RemotingCommandException {
   

    SendMessageRequestHeaderV2 requestHeaderV2 = null;
    SendMessageRequestHeader requestHeader = null;
    switch (request.getCode()) {
   
        case RequestCode.SEND_BATCH_MESSAGE:
        case RequestCode.SEND_MESSAGE_V2:
            requestHeaderV2 =
                (SendMessageRequestHeaderV2) request
                .decodeCommandCustomHeader(SendMessageRequestHeaderV2.class);
        case RequestCode.SEND_MESSAGE: // 看到这里,是不是很惊讶,这不就是我们要的请求码么
            if (null == requestHeaderV2) {
   
                // 这一步就简单了,decodeCommandCustomHeader 方法内部就是反射构建 SendMessageRequestHeader 类对象,然后给它赋值,有兴趣的读者自行进去看。
                requestHeader =
                    (SendMessageRequestHeader) request
                    .decodeCommandCustomHeader(SendMessageRequestHeader.class);
            } else {
   
                requestHeader = SendMessageRequestHeaderV2.createSendMessageRequestHeaderV1(requestHeaderV2);
            }
        default:
            break;
    }
    return requestHeader;
}

9.1 发送单个消息处理

private RemotingCommand sendMessage(final ChannelHandlerContext ctx,
                                    final RemotingCommand request,
                                    final SendMessageContext sendMessageContext,
                                    final SendMessageRequestHeader requestHeader) throws RemotingCommandException {
   

    // 先创建响应命令对象
    final RemotingCommand response = RemotingCommand.createResponseCommand(SendMessageResponseHeader.class);
    final SendMessageResponseHeader responseHeader = (SendMessageResponseHeader)response.readCustomHeader();

    // 唯一标识当前请求的id
    response.setOpaque(request.getOpaque());

    // MSG_REGION 属性
    response.addExtField(MessageConst.PROPERTY_MSG_REGION, this.brokerController.getBrokerConfig().getRegionId());
    // TRACE_ON 属性
    response.addExtField(MessageConst.PROPERTY_TRACE_SWITCH, String.valueOf(this.brokerController.getBrokerConfig().isTraceOn()));

    log.debug("receive SendMessage request command, {}", request);

    // 记录开始接收请求的时间
    final long startTimstamp = this.brokerController.getBrokerConfig()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

多栖码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值