序
本文主要研究一下rocketmq-proxy的popMessage
MessagingProcessor
org/apache/rocketmq/proxy/processor/MessagingProcessor.java
public interface MessagingProcessor extends StartAndShutdown {
//......
CompletableFuture<PopResult> popMessage(
ProxyContext ctx,
QueueSelector queueSelector,
String consumerGroup,
String topic,
int maxMsgNums,
long invisibleTime,
long pollTime,
int initMode,
SubscriptionData subscriptionData,
boolean fifo,
PopMessageResultFilter popMessageResultFilter,
String attemptId,
long timeoutMillis
);
//......
}
MessagingProcessor接口定义了popMessage方法
DefaultMessagingProcessor
org/apache/rocketmq/proxy/processor/DefaultMessagingProcessor.java
public class DefaultMessagingProcessor extends AbstractStartAndShutdown implements MessagingProcessor {
//......
public CompletableFuture<PopResult> popMessage(
ProxyContext ctx,
QueueSelector queueSelector,
String consumerGroup,
String topic,
int maxMsgNums,
long invisibleTime,
long pollTime,
int initMode,
SubscriptionData subscriptionData,
boolean fifo,
PopMessageResultFilter popMessageResultFilter,
String attemptId,
long timeoutMillis
) {
return this.consumerProcessor.popMessage(ctx, queueSelector, consumerGroup, topic, maxMsgNums,
invisibleTime, pollTime, initMode, subscriptionData, fifo, popMessageResultFilter, attemptId, timeoutMillis);
}
//......
}
DefaultMessagingProcessor的popMessage方法委托给了consumerProcessor.popMessage
ConsumerProcessor
org/apache/rocketmq/proxy/processor/ConsumerProcessor.java
public CompletableFuture<PopResult> popMessage(
ProxyContext ctx,
QueueSelector queueSelector,
String consumerGroup,
String topic,
int maxMsgNums,
long invisibleTime,
long pollTime,
int initMode,
SubscriptionData subscriptionData,
boolean fifo,
PopMessageResultFilter popMessageResultFilter,
String attemptId,
long timeoutMillis
) {
CompletableFuture<PopResult> future = new CompletableFuture<>();
try {
AddressableMessageQueue messageQueue = queueSelector.select(ctx, this.serviceManager.getTopicRouteService().getCurrentMessageQueueView(ctx, topic));
if (messageQueue == null) {
throw new ProxyException(ProxyExceptionCode.FORBIDDEN, "no readable queue");
}
return popMessage(ctx, messageQueue, consumerGroup, topic, maxMsgNums, invisibleTime, pollTime, initMode,
subscriptionData, fifo, popMessageResultFilter, attemptId, timeoutMillis);
} catch (Throwable t) {
future.completeExceptionally(t);
}
return future;
}
public CompletableFuture<PopResult> popMessage(
ProxyContext ctx,
AddressableMessageQueue messageQueue,
String consumerGroup,
String topic,
int maxMsgNums,
long invisibleTime,
long pollTime,
int initMode,
SubscriptionData subscriptionData,
boolean fifo,
PopMessageResultFilter popMessageResultFilter,
String attemptId,
long timeoutMillis
) {
CompletableFuture<PopResult> future = new CompletableFuture<>();
try {
if (maxMsgNums > ProxyUtils.MAX_MSG_NUMS_FOR_POP_REQUEST) {
log.warn("change maxNums from {} to {} for pop request, with info: topic:{}, group:{}",
maxMsgNums, ProxyUtils.MAX_MSG_NUMS_FOR_POP_REQUEST, topic, consumerGroup);
maxMsgNums = ProxyUtils.MAX_MSG_NUMS_FOR_POP_REQUEST;
}
PopMessageRequestHeader requestHeader = new PopMessageRequestHeader();
requestHeader.setConsumerGroup(consumerGroup);
requestHeader.setTopic(topic);
requestHeader.setQueueId(messageQueue.getQueueId());
requestHeader.setMaxMsgNums(maxMsgNums);
requestHeader.setInvisibleTime(invisibleTime);
requestHeader.setPollTime(pollTime);
requestHeader.setInitMode(initMode);
requestHeader.setExpType(subscriptionData.getExpressionType());
requestHeader.setExp(subscriptionData.getSubString());
requestHeader.setOrder(fifo);
requestHeader.setAttemptId(attemptId);
future = this.serviceManager.getMessageService().popMessage(
ctx,
messageQueue,
requestHeader,
timeoutMillis)
.thenApplyAsync(popResult -> {
if (PopStatus.FOUND.equals(popResult.getPopStatus()) &&
popResult.getMsgFoundList() != null &&
!popResult.getMsgFoundList().isEmpty() &&
popMessageResultFilter != null) {
List<MessageExt> messageExtList = new ArrayList<>();
for (MessageExt messageExt : popResult.getMsgFoundList()) {
try {
fillUniqIDIfNeed(messageExt);
String handleString = createHandle(messageExt.getProperty(MessageConst.PROPERTY_POP_CK), messageExt.getCommitLogOffset());
if (handleString == null) {
log.error("[BUG] pop message from broker but handle is empty. requestHeader:{}, msg:{}", requestHeader, messageExt);
messageExtList.add(messageExt);
continue;
}
MessageAccessor.putProperty(messageExt, MessageConst.PROPERTY_POP_CK, handleString);
PopMessageResultFilter.FilterResult filterResult =
popMessageResultFilter.filterMessage(ctx, consumerGroup, subscriptionData, messageExt);
switch (filterResult) {
case NO_MATCH:
this.messagingProcessor.ackMessage(
ctx,
ReceiptHandle.decode(handleString),
messageExt.getMsgId(),
consumerGroup,
topic,
MessagingProcessor.DEFAULT_TIMEOUT_MILLS);
break;
case TO_DLQ:
this.messagingProcessor.forwardMessageToDeadLetterQueue(
ctx,
ReceiptHandle.decode(handleString),
messageExt.getMsgId(),
consumerGroup,
topic,
MessagingProcessor.DEFAULT_TIMEOUT_MILLS);
break;
case MATCH:
default:
messageExtList.add(messageExt);
break;
}
} catch (Throwable t) {
log.error("process filterMessage failed. requestHeader:{}, msg:{}", requestHeader, messageExt, t);
messageExtList.add(messageExt);
}
}
popResult.setMsgFoundList(messageExtList);
}
return popResult;
}, this.executor);
} catch (Throwable t) {
future.completeExceptionally(t);
}
return FutureUtils.addExecutor(future, this.executor);
}
ConsumerProcessor的popMessage方法先通过queueSelector.select选择messageQueue,之后再执行popMessage;这里限制了每次pop消息的数量不能超过MAX_MSG_NUMS_FOR_POP_REQUEST(
32),构建PopMessageRequestHeader之后再委托给了this.serviceManager.getMessageService().popMessage,之后返回popResult,拉取到的消息放到了msgFoundList属性
MessageService
org/apache/rocketmq/proxy/service/message/MessageService.java
CompletableFuture<PopResult> popMessage(
ProxyContext ctx,
AddressableMessageQueue messageQueue,
PopMessageRequestHeader requestHeader,
long timeoutMillis
);
MessageService接口定义了popMessage方法,它有两个实现类,分别是LocalMessageService
LocalMessageService
org/apache/rocketmq/proxy/service/message/LocalMessageService.java
public CompletableFuture<PopResult> popMessage(ProxyContext ctx, AddressableMessageQueue messageQueue,
PopMessageRequestHeader requestHeader, long timeoutMillis) {
requestHeader.setBornTime(System.currentTimeMillis());
RemotingCommand request = LocalRemotingCommand.createRequestCommand(RequestCode.POP_MESSAGE, requestHeader, ctx.getLanguage());
CompletableFuture<RemotingCommand> future = new CompletableFuture<>();
SimpleChannel channel = channelManager.createInvocationChannel(ctx);
InvocationContext invocationContext = new InvocationContext(future);
channel.registerInvocationContext(request.getOpaque(), invocationContext);
ChannelHandlerContext simpleChannelHandlerContext = channel.getChannelHandlerContext();
try {
RemotingCommand response = brokerController.getPopMessageProcessor().processRequest(simpleChannelHandlerContext, request);
if (response != null) {
invocationContext.handle(response);
channel.eraseInvocationContext(request.getOpaque());
}
} catch (Exception e) {
future.completeExceptionally(e);
channel.eraseInvocatio

最低0.47元/天 解锁文章
999

被折叠的 条评论
为什么被折叠?



