要找到生产者发送的消息被谁接收了,就得先确定两件事情:
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()