private RemotingCommand processRequest(final Channel channel, RemotingCommand request,
boolean brokerAllowSuspend) throws RemotingCommandException {
RemotingCommand response = RemotingCommand.createResponseCommand(PullMessageResponseHeader.class);
final PullMessageResponseHeader responseHeader =
(PullMessageResponseHeader) response.getCustomHeader();
final PullMessageRequestHeader requestHeader =
(PullMessageRequestHeader) request.decodeCommandCustomHeader(PullMessageRequestHeader.class);
// 由于使用sendfile,所以必须要设置
response.setOpaque(request.getOpaque());
if (log.isDebugEnabled()) {
log.debug("receive PullMessage request command, " + request);
}
// 检查Broker权限
if (!PermName.isReadable(this.brokerController.getBrokerConfig().getBrokerPermission())) {
response.setCode(MQResponseCode.NO_PERMISSION_VALUE);
response.setRemark("the broker[" + this.brokerController.getBrokerConfig().getBrokerIP1()
+ "] pulling message is forbidden");
return response;
}
// 确保订阅组存在
SubscriptionGroupConfig subscriptionGroupConfig =
this.brokerController.getSubscriptionGroupManager().findSubscriptionGroupConfig(
requestHeader.getConsumerGroup());
if (null == subscriptionGroupConfig) {
response.setCode(MQResponseCode.SUBSCRIPTION_GROUP_NOT_EXIST_VALUE);
response.setRemark("subscription group not exist, " + requestHeader.getConsumerGroup() + " "
+ FAQUrl.suggestTodo(FAQUrl.SUBSCRIPTION_GROUP_NOT_EXIST));
return response;
}
// 这个订阅组是否可以消费消息
if (!subscriptionGroupConfig.isConsumeEnable()) {
response.setCode(MQResponseCode.NO_PERMISSION_VALUE);
response.setRemark("subscription group no permission, " + requestHeader.getConsumerGroup());
return response;
}
final boolean hasSuspendFlag = PullSysFlag.hasSuspendFlag(requestHeader.getSysFlag());
final boolean hasCommitOffsetFlag = PullSysFlag.hasCommitOffsetFlag(requestHeader.getSysFlag());
final boolean hasSubscriptionFlag = PullSysFlag.hasSubscriptionFlag(requestHeader.getSysFlag());
final long suspendTimeoutMillisLong = hasSuspendFlag ? requestHeader.getSuspendTimeoutMillis() : 0;
// 检查topic是否存在
TopicConfig topicConfig =
this.brokerController.getTopicConfigManager().selectTopicConfig(requestHeader.getTopic());
if (null == topicConfig) {
log.error("the topic " + requestHeader.getTopic() + " not exist, consumer: "
+ RemotingHelper.parseChannelRemoteAddr(channel));
response.setCode(MQResponseCode.TOPIC_NOT_EXIST_VALUE);
response.setRemark("topic[" + requestHeader.getTopic() + "] not exist, apply first please!"
+ FAQUrl.suggestTodo(FAQUrl.APPLY_TOPIC_URL));
return response;
}
// 检查topic权限
if (!PermName.isReadable(topicConfig.getPerm())) {
response.setCode(MQResponseCode.NO_PERMISSION_VALUE);
response.setRemark("the topic[" + requestHeader.getTopic() + "] pulling message is forbidden");
return response;
}
// 检查队列有效性
if (requestHeader.getQueueId() < 0 || requestHeader.getQueueId() >= topicConfig.getReadQueueNums()) {
String errorInfo =
"queueId[" + requestHeader.getQueueId() + "] is illagal,Topic :"
+ requestHeader.getTopic() + " topicConfig.readQueueNums: "
+ topicConfig.getReadQueueNums() + " consumer: " + channel.remoteAddress();
log.warn(errorInfo);
response.setCode(ResponseCode.SYSTEM_ERROR_VALUE);
response.setRemark(errorInfo);
return response;
}
// 订阅关系处理
SubscriptionData subscriptionData = null;
if (hasSubscriptionFlag) {
try {
subscriptionData =
FilterAPI.buildSubscriptionData(requestHeader.getTopic(),
requestHeader.getSubscription());
}
catch (Exception e) {
log.warn("parse the consumer's subscription[{}] failed, group: {}",
requestHeader.getSubscription(),//
requestHeader.getConsumerGroup());
response.setCode(MQResponseCode.SUBSCRIPTION_PARSE_FAILED_VALUE);
response.setRemark("parse the consumer's subscription failed");
return response;
}
}
else {
ConsumerGroupInfo consumerGroupInfo =
this.brokerController.getConsumerManager().getConsumerGroupInfo(
requestHeader.getConsumerGroup());
if (null == consumerGroupInfo) {
log.warn("the consumer's group info not exist, group: {}", requestHeader.getConsumerGroup());
response.setCode(MQResponseCode.SUBSCRIPTION_NOT_EXIST_VALUE);
response.setRemark("the consumer's group info not exist");
return response;
}
switch (consumerGroupInfo.getConsumeFromWhere()) {
case CONSUME_FROM_LAST_OFFSET:
case CONSUME_FROM_MAX_OFFSET:
break;
case CONSUME_FROM_LAST_OFFSET_AND_FROM_MIN_WHEN_BOOT_FIRST:
case CONSUME_FROM_MIN_OFFSET:
if (!subscriptionGroupConfig.isConsumeFromMinEnable()) {
response.setCode(MQResponseCode.NO_PERMISSION_VALUE);
response.setRemark("the consumer group[" + requestHeader.getConsumerGroup()
+ "] can not consume from min");
return response;
}
break;
default:
break;
}
if (!subscriptionGroupConfig.isConsumeBroadcastEnable() //
&& consumerGroupInfo.getMessageModel() == MessageModel.BROADCASTING) {
response.setCode(MQResponseCode.NO_PERMISSION_VALUE);
response.setRemark("the consumer group[" + requestHeader.getConsumerGroup()
+ "] can not consume by broadcast way");
return response;
}
subscriptionData = consumerGroupInfo.findSubscriptionData(requestHeader.getTopic());
if (null == subscriptionData) {
log.warn("the consumer's subscription not exist, group: {}", requestHeader.getConsumerGroup());
response.setCode(MQResponseCode.SUBSCRIPTION_NOT_EXIST_VALUE);
response.setRemark("the consumer's subscription not exist");
return response;
}
// 判断Broker的订阅关系版本是否最新
if (subscriptionData.getSubVersion() < requestHeader.getSubVersion()) {
log.warn("the broker's subscription is not latest, group: {} {}",
requestHeader.getConsumerGroup(), subscriptionData.getSubString());
response.setCode(MQResponseCode.SUBSCRIPTION_NOT_LATEST_VALUE);
response.setRemark("the consumer's subscription not latest");
return response;
}
}
final GetMessageResult getMessageResult =
this.brokerController.getMessageStore().getMessage(requestHeader.getTopic(),
requestHeader.getQueueId(), requestHeader.getQueueOffset(),
requestHeader.getMaxMsgNums(), subscriptionData);
if (getMessageResult != null) {
if (getMessageResult.getBufferTotalSize() > 0) {
PullmsgLiveMoniter.printProcessRequestLive(channel, request, getMessageResult);
}
response.setRemark(getMessageResult.getStatus().name());
responseHeader.setNextBeginOffset(getMessageResult.getNextBeginOffset());
responseHeader.setMinOffset(getMessageResult.getMinOffset());
responseHeader.setMaxOffset(getMessageResult.getMaxOffset());
// 消费较慢,重定向到另外一台机器
if (getMessageResult.isSuggestPullingFromSlave()) {
responseHeader.setSuggestWhichBrokerId(subscriptionGroupConfig
.getWhichBrokerWhenConsumeSlowly());
}
// 消费正常,按照订阅组配置重定向
else {
responseHeader.setSuggestWhichBrokerId(subscriptionGroupConfig.getBrokerId());
}
switch (getMessageResult.getStatus()) {
case FOUND:
response.setCode(ResponseCode.SUCCESS_VALUE);