Search in sources :

Example 16 with PutMessageResult

use of org.apache.rocketmq.store.PutMessageResult in project rocketmq by apache.

the class SendMessageProcessorTest method testProcessRequest_FlushTimeOut.

@Test
public void testProcessRequest_FlushTimeOut() throws RemotingCommandException {
    when(messageStore.putMessage(any(MessageExtBrokerInner.class))).thenReturn(new PutMessageResult(PutMessageStatus.FLUSH_DISK_TIMEOUT, new AppendMessageResult(AppendMessageStatus.UNKNOWN_ERROR)));
    assertPutResult(ResponseCode.FLUSH_DISK_TIMEOUT);
}
Also used : PutMessageResult(org.apache.rocketmq.store.PutMessageResult) MessageExtBrokerInner(org.apache.rocketmq.store.MessageExtBrokerInner) AppendMessageResult(org.apache.rocketmq.store.AppendMessageResult) Test(org.junit.Test)

Example 17 with PutMessageResult

use of org.apache.rocketmq.store.PutMessageResult in project rocketmq by apache.

the class SendMessageProcessorTest method testProcessRequest_ServiceNotAvailable.

@Test
public void testProcessRequest_ServiceNotAvailable() throws RemotingCommandException {
    when(messageStore.putMessage(any(MessageExtBrokerInner.class))).thenReturn(new PutMessageResult(PutMessageStatus.SERVICE_NOT_AVAILABLE, new AppendMessageResult(AppendMessageStatus.UNKNOWN_ERROR)));
    assertPutResult(ResponseCode.SERVICE_NOT_AVAILABLE);
}
Also used : PutMessageResult(org.apache.rocketmq.store.PutMessageResult) MessageExtBrokerInner(org.apache.rocketmq.store.MessageExtBrokerInner) AppendMessageResult(org.apache.rocketmq.store.AppendMessageResult) Test(org.junit.Test)

Example 18 with PutMessageResult

use of org.apache.rocketmq.store.PutMessageResult in project rocketmq-rocketmq-all-4.1.0-incubating by lirenzuo.

the class EndTransactionProcessor method processRequest.

@Override
public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) throws RemotingCommandException {
    final RemotingCommand response = RemotingCommand.createResponseCommand(null);
    final EndTransactionRequestHeader requestHeader = (EndTransactionRequestHeader) request.decodeCommandCustomHeader(EndTransactionRequestHeader.class);
    if (requestHeader.getFromTransactionCheck()) {
        switch(requestHeader.getCommitOrRollback()) {
            case MessageSysFlag.TRANSACTION_NOT_TYPE:
                {
                    LOGGER.warn("check producer[{}] transaction state, but it's pending status." + "RequestHeader: {} Remark: {}", RemotingHelper.parseChannelRemoteAddr(ctx.channel()), requestHeader.toString(), request.getRemark());
                    return null;
                }
            case MessageSysFlag.TRANSACTION_COMMIT_TYPE:
                {
                    LOGGER.warn("check producer[{}] transaction state, the producer commit the message." + "RequestHeader: {} Remark: {}", RemotingHelper.parseChannelRemoteAddr(ctx.channel()), requestHeader.toString(), request.getRemark());
                    break;
                }
            case MessageSysFlag.TRANSACTION_ROLLBACK_TYPE:
                {
                    LOGGER.warn("check producer[{}] transaction state, the producer rollback the message." + "RequestHeader: {} Remark: {}", RemotingHelper.parseChannelRemoteAddr(ctx.channel()), requestHeader.toString(), request.getRemark());
                    break;
                }
            default:
                return null;
        }
    } else {
        switch(requestHeader.getCommitOrRollback()) {
            case MessageSysFlag.TRANSACTION_NOT_TYPE:
                {
                    LOGGER.warn("the producer[{}] end transaction in sending message,  and it's pending status." + "RequestHeader: {} Remark: {}", RemotingHelper.parseChannelRemoteAddr(ctx.channel()), requestHeader.toString(), request.getRemark());
                    return null;
                }
            case MessageSysFlag.TRANSACTION_COMMIT_TYPE:
                {
                    break;
                }
            case MessageSysFlag.TRANSACTION_ROLLBACK_TYPE:
                {
                    LOGGER.warn("the producer[{}] end transaction in sending message, rollback the message." + "RequestHeader: {} Remark: {}", RemotingHelper.parseChannelRemoteAddr(ctx.channel()), requestHeader.toString(), request.getRemark());
                    break;
                }
            default:
                return null;
        }
    }
    final MessageExt msgExt = this.brokerController.getMessageStore().lookMessageByOffset(requestHeader.getCommitLogOffset());
    if (msgExt != null) {
        final String pgroupRead = msgExt.getProperty(MessageConst.PROPERTY_PRODUCER_GROUP);
        if (!pgroupRead.equals(requestHeader.getProducerGroup())) {
            response.setCode(ResponseCode.SYSTEM_ERROR);
            response.setRemark("the producer group wrong");
            return response;
        }
        if (msgExt.getQueueOffset() != requestHeader.getTranStateTableOffset()) {
            response.setCode(ResponseCode.SYSTEM_ERROR);
            response.setRemark("the transaction state table offset wrong");
            return response;
        }
        if (msgExt.getCommitLogOffset() != requestHeader.getCommitLogOffset()) {
            response.setCode(ResponseCode.SYSTEM_ERROR);
            response.setRemark("the commit log offset wrong");
            return response;
        }
        MessageExtBrokerInner msgInner = this.endMessageTransaction(msgExt);
        msgInner.setSysFlag(MessageSysFlag.resetTransactionValue(msgInner.getSysFlag(), requestHeader.getCommitOrRollback()));
        msgInner.setQueueOffset(requestHeader.getTranStateTableOffset());
        msgInner.setPreparedTransactionOffset(requestHeader.getCommitLogOffset());
        msgInner.setStoreTimestamp(msgExt.getStoreTimestamp());
        if (MessageSysFlag.TRANSACTION_ROLLBACK_TYPE == requestHeader.getCommitOrRollback()) {
            msgInner.setBody(null);
        }
        final MessageStore messageStore = this.brokerController.getMessageStore();
        final PutMessageResult putMessageResult = messageStore.putMessage(msgInner);
        if (putMessageResult != null) {
            switch(putMessageResult.getPutMessageStatus()) {
                // Success
                case PUT_OK:
                case FLUSH_DISK_TIMEOUT:
                case FLUSH_SLAVE_TIMEOUT:
                case SLAVE_NOT_AVAILABLE:
                    response.setCode(ResponseCode.SUCCESS);
                    response.setRemark(null);
                    break;
                // Failed
                case CREATE_MAPEDFILE_FAILED:
                    response.setCode(ResponseCode.SYSTEM_ERROR);
                    response.setRemark("create mapped file failed.");
                    break;
                case MESSAGE_ILLEGAL:
                case PROPERTIES_SIZE_EXCEEDED:
                    response.setCode(ResponseCode.MESSAGE_ILLEGAL);
                    response.setRemark("the message is illegal, maybe msg body or properties length not matched. msg body length limit 128k, msg properties length limit 32k.");
                    break;
                case SERVICE_NOT_AVAILABLE:
                    response.setCode(ResponseCode.SERVICE_NOT_AVAILABLE);
                    response.setRemark("service not available now.");
                    break;
                case OS_PAGECACHE_BUSY:
                    response.setCode(ResponseCode.SYSTEM_ERROR);
                    response.setRemark("OS page cache busy, please try another machine");
                    break;
                case UNKNOWN_ERROR:
                    response.setCode(ResponseCode.SYSTEM_ERROR);
                    response.setRemark("UNKNOWN_ERROR");
                    break;
                default:
                    response.setCode(ResponseCode.SYSTEM_ERROR);
                    response.setRemark("UNKNOWN_ERROR DEFAULT");
                    break;
            }
            return response;
        } else {
            response.setCode(ResponseCode.SYSTEM_ERROR);
            response.setRemark("store putMessage return null");
        }
    } else {
        response.setCode(ResponseCode.SYSTEM_ERROR);
        response.setRemark("find prepared transaction message failed");
        return response;
    }
    return response;
}
Also used : RemotingCommand(org.apache.rocketmq.remoting.protocol.RemotingCommand) MessageStore(org.apache.rocketmq.store.MessageStore) MessageExt(org.apache.rocketmq.common.message.MessageExt) PutMessageResult(org.apache.rocketmq.store.PutMessageResult) MessageExtBrokerInner(org.apache.rocketmq.store.MessageExtBrokerInner) EndTransactionRequestHeader(org.apache.rocketmq.common.protocol.header.EndTransactionRequestHeader)

Example 19 with PutMessageResult

use of org.apache.rocketmq.store.PutMessageResult in project rocketmq-rocketmq-all-4.1.0-incubating by lirenzuo.

the class SendMessageProcessor method consumerSendMsgBack.

// Broker Consumer将处理不了的消息发回服务器
private RemotingCommand consumerSendMsgBack(final ChannelHandlerContext ctx, final RemotingCommand request) throws RemotingCommandException {
    final RemotingCommand response = RemotingCommand.createResponseCommand(null);
    final ConsumerSendMsgBackRequestHeader requestHeader = (ConsumerSendMsgBackRequestHeader) request.decodeCommandCustomHeader(ConsumerSendMsgBackRequestHeader.class);
    // 消息轨迹:记录消费失败的消息
    if (this.hasConsumeMessageHook() && !UtilAll.isBlank(requestHeader.getOriginMsgId())) {
        // 执行hook
        ConsumeMessageContext context = new ConsumeMessageContext();
        context.setConsumerGroup(requestHeader.getGroup());
        context.setTopic(requestHeader.getOriginTopic());
        context.setCommercialRcvStats(BrokerStatsManager.StatsType.SEND_BACK);
        context.setCommercialRcvTimes(1);
        context.setCommercialOwner(request.getExtFields().get(BrokerStatsManager.COMMERCIAL_OWNER));
        this.executeConsumeMessageHookAfter(context);
    }
    // 确保订阅组存在
    SubscriptionGroupConfig subscriptionGroupConfig = this.brokerController.getSubscriptionGroupManager().findSubscriptionGroupConfig(requestHeader.getGroup());
    if (null == subscriptionGroupConfig) {
        response.setCode(ResponseCode.SUBSCRIPTION_GROUP_NOT_EXIST);
        response.setRemark("subscription group not exist, " + requestHeader.getGroup() + " " + FAQUrl.suggestTodo(FAQUrl.SUBSCRIPTION_GROUP_NOT_EXIST));
        return response;
    }
    // 检查Broker权限
    if (!PermName.isWriteable(this.brokerController.getBrokerConfig().getBrokerPermission())) {
        response.setCode(ResponseCode.NO_PERMISSION);
        response.setRemark("the broker[" + this.brokerController.getBrokerConfig().getBrokerIP1() + "] sending message is forbidden");
        return response;
    }
    // 如果重试队列数目为0,则直接丢弃消息
    if (subscriptionGroupConfig.getRetryQueueNums() <= 0) {
        response.setCode(ResponseCode.SUCCESS);
        response.setRemark(null);
        return response;
    }
    String newTopic = MixAll.getRetryTopic(requestHeader.getGroup());
    int queueIdInt = Math.abs(this.random.nextInt() % 99999999) % subscriptionGroupConfig.getRetryQueueNums();
    // 如果是单元化模式,则对 topic 进行设置
    int topicSysFlag = 0;
    if (requestHeader.isUnitMode()) {
        topicSysFlag = TopicSysFlag.buildSysFlag(false, true);
    }
    // 检查topic是否存在
    TopicConfig topicConfig = // 
    this.brokerController.getTopicConfigManager().createTopicInSendMessageBackMethod(// 
    newTopic, // 
    subscriptionGroupConfig.getRetryQueueNums(), PermName.PERM_WRITE | PermName.PERM_READ, topicSysFlag);
    if (null == topicConfig) {
        response.setCode(ResponseCode.SYSTEM_ERROR);
        response.setRemark("topic[" + newTopic + "] not exist");
        return response;
    }
    // 检查topic权限
    if (!PermName.isWriteable(topicConfig.getPerm())) {
        response.setCode(ResponseCode.NO_PERMISSION);
        response.setRemark(String.format("the topic[%s] sending message is forbidden", newTopic));
        return response;
    }
    // 查询消息,这里如果堆积消息过多,会访问磁盘
    // 另外如果频繁调用,是否会引起gc问题,需要关注 TODO
    MessageExt msgExt = this.brokerController.getMessageStore().lookMessageByOffset(requestHeader.getOffset());
    if (null == msgExt) {
        response.setCode(ResponseCode.SYSTEM_ERROR);
        response.setRemark("look message by offset failed, " + requestHeader.getOffset());
        return response;
    }
    // 构造消息
    final String retryTopic = msgExt.getProperty(MessageConst.PROPERTY_RETRY_TOPIC);
    if (null == retryTopic) {
        MessageAccessor.putProperty(msgExt, MessageConst.PROPERTY_RETRY_TOPIC, msgExt.getTopic());
    }
    msgExt.setWaitStoreMsgOK(false);
    // 客户端自动决定定时级别
    int delayLevel = requestHeader.getDelayLevel();
    int maxReconsumeTimes = subscriptionGroupConfig.getRetryMaxTimes();
    if (request.getVersion() >= MQVersion.Version.V3_4_9.ordinal()) {
        maxReconsumeTimes = requestHeader.getMaxReconsumeTimes();
    }
    // 死信消息处理
    if (// 
    msgExt.getReconsumeTimes() >= maxReconsumeTimes || delayLevel < 0) {
        newTopic = MixAll.getDLQTopic(requestHeader.getGroup());
        queueIdInt = Math.abs(this.random.nextInt() % 99999999) % DLQ_NUMS_PER_GROUP;
        topicConfig = // 
        this.brokerController.getTopicConfigManager().createTopicInSendMessageBackMethod(// 
        newTopic, // 
        DLQ_NUMS_PER_GROUP, // 死信消息不需要同步,不需要较正。
        PermName.PERM_WRITE, // 死信消息不需要同步,不需要较正。
        0);
        if (null == topicConfig) {
            response.setCode(ResponseCode.SYSTEM_ERROR);
            response.setRemark("topic[" + newTopic + "] not exist");
            return response;
        }
    } else // 继续重试
    {
        if (0 == delayLevel) {
            delayLevel = 3 + msgExt.getReconsumeTimes();
        }
        msgExt.setDelayTimeLevel(delayLevel);
    }
    // 构建 MessageExtBrokerInner
    MessageExtBrokerInner msgInner = new MessageExtBrokerInner();
    msgInner.setTopic(newTopic);
    msgInner.setBody(msgExt.getBody());
    msgInner.setFlag(msgExt.getFlag());
    MessageAccessor.setProperties(msgInner, msgExt.getProperties());
    msgInner.setPropertiesString(MessageDecoder.messageProperties2String(msgExt.getProperties()));
    msgInner.setTagsCode(MessageExtBrokerInner.tagsString2tagsCode(null, msgExt.getTags()));
    msgInner.setQueueId(queueIdInt);
    msgInner.setSysFlag(msgExt.getSysFlag());
    msgInner.setBornTimestamp(msgExt.getBornTimestamp());
    msgInner.setBornHost(msgExt.getBornHost());
    msgInner.setStoreHost(this.getStoreHost());
    msgInner.setReconsumeTimes(msgExt.getReconsumeTimes() + 1);
    // 保存源生消息的 msgId
    String originMsgId = MessageAccessor.getOriginMessageId(msgExt);
    MessageAccessor.setOriginMessageId(msgInner, UtilAll.isBlank(originMsgId) ? msgExt.getMsgId() : originMsgId);
    PutMessageResult putMessageResult = this.brokerController.getMessageStore().putMessage(msgInner);
    if (putMessageResult != null) {
        switch(putMessageResult.getPutMessageStatus()) {
            case PUT_OK:
                // 统计失败重试的Topic
                String backTopic = msgExt.getTopic();
                String correctTopic = msgExt.getProperty(MessageConst.PROPERTY_RETRY_TOPIC);
                if (correctTopic != null) {
                    backTopic = correctTopic;
                }
                this.brokerController.getBrokerStatsManager().incSendBackNums(requestHeader.getGroup(), backTopic);
                response.setCode(ResponseCode.SUCCESS);
                response.setRemark(null);
                return response;
            default:
                break;
        }
        response.setCode(ResponseCode.SYSTEM_ERROR);
        response.setRemark(putMessageResult.getPutMessageStatus().name());
        return response;
    }
    response.setCode(ResponseCode.SYSTEM_ERROR);
    response.setRemark("putMessageResult is null");
    return response;
}
Also used : RemotingCommand(org.apache.rocketmq.remoting.protocol.RemotingCommand) ConsumeMessageContext(org.apache.rocketmq.broker.mqtrace.ConsumeMessageContext) MessageExt(org.apache.rocketmq.common.message.MessageExt) PutMessageResult(org.apache.rocketmq.store.PutMessageResult) ConsumerSendMsgBackRequestHeader(org.apache.rocketmq.common.protocol.header.ConsumerSendMsgBackRequestHeader) MessageExtBrokerInner(org.apache.rocketmq.store.MessageExtBrokerInner) TopicConfig(org.apache.rocketmq.common.TopicConfig) SubscriptionGroupConfig(org.apache.rocketmq.common.subscription.SubscriptionGroupConfig)

Example 20 with PutMessageResult

use of org.apache.rocketmq.store.PutMessageResult in project rocketmq-rocketmq-all-4.1.0-incubating by lirenzuo.

the class SendMessageProcessor method sendMessage.

private // 
RemotingCommand sendMessage(// 
final ChannelHandlerContext ctx, // 
final RemotingCommand request, // 
final SendMessageContext sendMessageContext, final SendMessageRequestHeader requestHeader) throws RemotingCommandException {
    // init response
    final RemotingCommand response = RemotingCommand.createResponseCommand(SendMessageResponseHeader.class);
    final SendMessageResponseHeader responseHeader = (SendMessageResponseHeader) response.readCustomHeader();
    // 由于有直接返回的逻辑,所以必须要设置
    response.setOpaque(request.getOpaque());
    response.addExtField(MessageConst.PROPERTY_MSG_REGION, this.brokerController.getBrokerConfig().getRegionId());
    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().getStartAcceptSendRequestTimeStamp();
    if (this.brokerController.getMessageStore().now() < startTimstamp) {
        response.setCode(ResponseCode.SYSTEM_ERROR);
        response.setRemark(String.format("broker unable to service, until %s", UtilAll.timeMillisToHumanString2(startTimstamp)));
        return response;
    }
    response.setCode(-1);
    super.msgCheck(ctx, requestHeader, response);
    if (response.getCode() != -1) {
        return response;
    }
    final byte[] body = request.getBody();
    int queueIdInt = requestHeader.getQueueId();
    TopicConfig topicConfig = this.brokerController.getTopicConfigManager().selectTopicConfig(requestHeader.getTopic());
    // 如果队列小于0,从可用队列随机选择
    if (queueIdInt < 0) {
        queueIdInt = Math.abs(this.random.nextInt() % 99999999) % topicConfig.getWriteQueueNums();
    }
    MessageExtBrokerInner msgInner = new MessageExtBrokerInner();
    msgInner.setTopic(requestHeader.getTopic());
    msgInner.setQueueId(queueIdInt);
    if (!handleRetryAndDLQ(requestHeader, response, request, msgInner, topicConfig)) {
        return response;
    }
    msgInner.setBody(body);
    msgInner.setFlag(requestHeader.getFlag());
    // 设置的属性进行解码  UNIQ_ID就在里面
    MessageAccessor.setProperties(msgInner, MessageDecoder.string2messageProperties(requestHeader.getProperties()));
    msgInner.setPropertiesString(requestHeader.getProperties());
    msgInner.setBornTimestamp(requestHeader.getBornTimestamp());
    msgInner.setBornHost(ctx.channel().remoteAddress());
    msgInner.setStoreHost(this.getStoreHost());
    msgInner.setReconsumeTimes(requestHeader.getReconsumeTimes() == null ? 0 : requestHeader.getReconsumeTimes());
    if (this.brokerController.getBrokerConfig().isRejectTransactionMessage()) {
        String traFlag = msgInner.getProperty(MessageConst.PROPERTY_TRANSACTION_PREPARED);
        if (traFlag != null) {
            response.setCode(ResponseCode.NO_PERMISSION);
            response.setRemark("the broker[" + this.brokerController.getBrokerConfig().getBrokerIP1() + "] sending transaction message is forbidden");
            return response;
        }
    }
    // 进行存储
    PutMessageResult putMessageResult = this.brokerController.getMessageStore().putMessage(msgInner);
    return handlePutMessageResult(putMessageResult, response, request, msgInner, responseHeader, sendMessageContext, ctx, queueIdInt);
}
Also used : RemotingCommand(org.apache.rocketmq.remoting.protocol.RemotingCommand) SendMessageResponseHeader(org.apache.rocketmq.common.protocol.header.SendMessageResponseHeader) PutMessageResult(org.apache.rocketmq.store.PutMessageResult) MessageExtBrokerInner(org.apache.rocketmq.store.MessageExtBrokerInner) TopicConfig(org.apache.rocketmq.common.TopicConfig)

Aggregations

PutMessageResult (org.apache.rocketmq.store.PutMessageResult)34 MessageExtBrokerInner (org.apache.rocketmq.store.MessageExtBrokerInner)32 AppendMessageResult (org.apache.rocketmq.store.AppendMessageResult)22 Test (org.junit.Test)22 RemotingCommand (org.apache.rocketmq.remoting.protocol.RemotingCommand)10 TopicConfig (org.apache.rocketmq.common.TopicConfig)6 ArrayList (java.util.ArrayList)4 MessageExt (org.apache.rocketmq.common.message.MessageExt)4 SendMessageResponseHeader (org.apache.rocketmq.common.protocol.header.SendMessageResponseHeader)4 ConsumeMessageContext (org.apache.rocketmq.broker.mqtrace.ConsumeMessageContext)2 SendMessageContext (org.apache.rocketmq.broker.mqtrace.SendMessageContext)2 SendMessageHook (org.apache.rocketmq.broker.mqtrace.SendMessageHook)2 MessageExtBatch (org.apache.rocketmq.common.message.MessageExtBatch)2 ConsumerSendMsgBackRequestHeader (org.apache.rocketmq.common.protocol.header.ConsumerSendMsgBackRequestHeader)2 EndTransactionRequestHeader (org.apache.rocketmq.common.protocol.header.EndTransactionRequestHeader)2 SubscriptionGroupConfig (org.apache.rocketmq.common.subscription.SubscriptionGroupConfig)2 RemotingCommandException (org.apache.rocketmq.remoting.exception.RemotingCommandException)2 MessageStore (org.apache.rocketmq.store.MessageStore)2