Пример #1
0
    private MessageExtBrokerInner messageTimeup(MessageExt msgExt) {
      MessageExtBrokerInner msgInner = new MessageExtBrokerInner();
      msgInner.setBody(msgExt.getBody());
      msgInner.setFlag(msgExt.getFlag());
      msgInner.setProperties(msgExt.getProperties());

      TopicFilterType topicFilterType = MessageExt.parseTopicFilterType(msgInner.getSysFlag());
      long tagsCodeValue =
          MessageExtBrokerInner.tagsString2tagsCode(topicFilterType, msgInner.getTags());
      msgInner.setTagsCode(tagsCodeValue);
      msgInner.setPropertiesString(MessageDecoder.messageProperties2String(msgExt.getProperties()));

      msgInner.setSysFlag(msgExt.getSysFlag());
      msgInner.setBornTimestamp(msgExt.getBornTimestamp());
      msgInner.setBornHost(msgExt.getBornHost());
      msgInner.setStoreHost(msgExt.getStoreHost());
      msgInner.setReconsumeTimes(msgExt.getReconsumeTimes());

      msgInner.setWaitStoreMsgOK(false);
      msgInner.clearProperty(Message.PROPERTY_DELAY_TIME_LEVEL);

      // 恢复Topic
      msgInner.setTopic(msgInner.getProperty(Message.PROPERTY_REAL_TOPIC));

      // 恢复QueueId
      String queueIdStr = msgInner.getProperty(Message.PROPERTY_REAL_QUEUE_ID);
      int queueId = Integer.parseInt(queueIdStr);
      msgInner.setQueueId(queueId);

      return msgInner;
    }
  private void endTransaction( //
      final SendResult sendResult, //
      final LocalTransactionState localTransactionState, //
      final Throwable localException)
      throws RemotingException, MQBrokerException, InterruptedException, UnknownHostException {
    final MessageId id = MessageDecoder.decodeMessageId(sendResult.getMsgId());
    final String addr = RemotingUtil.socketAddress2String(id.getAddress());
    EndTransactionRequestHeader requestHeader = new EndTransactionRequestHeader();
    requestHeader.setCommitLogOffset(id.getOffset());
    switch (localTransactionState) {
      case COMMIT_MESSAGE:
        requestHeader.setCommitOrRollback(MessageSysFlag.TransactionCommitType);
        break;
      case ROLLBACK_MESSAGE:
        requestHeader.setCommitOrRollback(MessageSysFlag.TransactionRollbackType);
        break;
      case UNKNOW:
        requestHeader.setCommitOrRollback(MessageSysFlag.TransactionNotType);
        break;
      default:
        break;
    }

    requestHeader.setProducerGroup(this.defaultMQProducer.getProducerGroup());
    requestHeader.setTranStateTableOffset(sendResult.getQueueOffset());
    requestHeader.setMsgId(sendResult.getMsgId());
    String remark =
        localException != null
            ? ("executeLocalTransactionBranch exception: " + localException.toString())
            : null;
    this.mQClientFactory
        .getMQClientAPIImpl()
        .endTransactionOneway(
            addr, requestHeader, remark, this.defaultMQProducer.getSendMsgTimeout());
  }
  private SendResult sendKernelImpl(
      final Message msg, //
      final MessageQueue mq, //
      final CommunicationMode communicationMode, //
      final SendCallback sendCallback //
      ) throws MQClientException, RemotingException, MQBrokerException, InterruptedException {
    String brokerAddr = this.mQClientFactory.findBrokerAddressInPublish(mq.getBrokerName());
    if (null == brokerAddr) {
      // TODO 此处可能对Name Server压力过大,需要调优
      tryToFindTopicPublishInfo(mq.getTopic());
      brokerAddr = this.mQClientFactory.findBrokerAddressInPublish(mq.getBrokerName());
    }

    SendMessageContext context = null;
    if (brokerAddr != null) {
      byte[] prevBody = msg.getBody();
      try {
        int sysFlag = 0;
        if (this.tryToCompressMessage(msg)) {
          sysFlag |= MessageSysFlag.CompressedFlag;
        }

        final String tranMsg = msg.getProperty(MessageConst.PROPERTY_TRANSACTION_PREPARED);
        if (tranMsg != null && Boolean.parseBoolean(tranMsg)) {
          sysFlag |= MessageSysFlag.TransactionPreparedType;
        }

        // 执行hook
        if (this.hasHook()) {
          context = new SendMessageContext();
          context.setProducerGroup(this.defaultMQProducer.getProducerGroup());
          context.setCommunicationMode(communicationMode);
          context.setBrokerAddr(brokerAddr);
          context.setMessage(msg);
          context.setMq(mq);
          this.executeHookBefore(context);
        }

        SendMessageRequestHeader requestHeader = new SendMessageRequestHeader();
        requestHeader.setProducerGroup(this.defaultMQProducer.getProducerGroup());
        requestHeader.setTopic(msg.getTopic());
        requestHeader.setDefaultTopic(this.defaultMQProducer.getCreateTopicKey());
        requestHeader.setDefaultTopicQueueNums(this.defaultMQProducer.getDefaultTopicQueueNums());
        requestHeader.setQueueId(mq.getQueueId());
        requestHeader.setSysFlag(sysFlag);
        requestHeader.setBornTimestamp(System.currentTimeMillis());
        requestHeader.setFlag(msg.getFlag());
        requestHeader.setProperties(MessageDecoder.messageProperties2String(msg.getProperties()));

        SendResult sendResult =
            this.mQClientFactory
                .getMQClientAPIImpl()
                .sendMessage( //
                    brokerAddr, // 1
                    mq.getBrokerName(), // 2
                    msg, // 3
                    requestHeader, // 4
                    this.defaultMQProducer.getSendMsgTimeout(), // 5
                    communicationMode, // 6
                    sendCallback // 7
                    );

        // 执行hook
        if (this.hasHook()) {
          context.setSendResult(sendResult);
          this.executeHookAfter(context);
        }

        return sendResult;
      } catch (RemotingException e) {
        // 执行hook
        if (this.hasHook()) {
          context.setException(e);
          this.executeHookAfter(context);
        }
        throw e;
      } catch (MQBrokerException e) {
        // 执行hook
        if (this.hasHook()) {
          context.setException(e);
          this.executeHookAfter(context);
        }
        throw e;
      } catch (InterruptedException e) {
        // 执行hook
        if (this.hasHook()) {
          context.setException(e);
          this.executeHookAfter(context);
        }
        throw e;
      } finally {
        msg.setBody(prevBody);
      }
    }

    throw new MQClientException("The broker[" + mq.getBrokerName() + "] not exist", null);
  }
Пример #4
0
    public AppendMessageResult doAppend(
        final long fileFromOffset,
        final ByteBuffer byteBuffer,
        final int maxBlank,
        final Object msg) {
      /** 生成消息ID STORETIMESTAMP + STOREHOSTADDRESS + OFFSET <br> */
      MessageExtBrokerInner msgInner = (MessageExtBrokerInner) msg;
      // PHY OFFSET
      long wroteOffset = fileFromOffset + byteBuffer.position();
      String msgId =
          MessageDecoder.createMessageId(
              this.msgIdMemory, msgInner.getStoreHostBytes(), wroteOffset);

      /** 记录ConsumeQueue信息 */
      String key = msgInner.getTopic() + "-" + msgInner.getQueueId();
      Long queueOffset = CommitLog.this.topicQueueTable.get(key);
      if (null == queueOffset) {
        queueOffset = 0L;
        CommitLog.this.topicQueueTable.put(key, queueOffset);
      }

      /** 事务消息需要特殊处理 */
      final int tranType = MessageSysFlag.getTransactionValue(msgInner.getSysFlag());
      switch (tranType) {
        case MessageSysFlag.TransactionPreparedType:
          queueOffset =
              CommitLog.this
                  .defaultMessageStore
                  .getTransactionStateService()
                  .getTranStateTableOffset()
                  .get();
          break;
        case MessageSysFlag.TransactionRollbackType:
          queueOffset = msgInner.getQueueOffset();
          break;
        case MessageSysFlag.TransactionNotType:
        case MessageSysFlag.TransactionCommitType:
        default:
          break;
      }

      /** 序列化消息 */
      final byte[] propertiesData =
          msgInner.getPropertiesString() == null ? null : msgInner.getPropertiesString().getBytes();
      final int propertiesLength = propertiesData == null ? 0 : propertiesData.length;

      final byte[] topicData = msgInner.getTopic().getBytes();
      final int topicLength = topicData == null ? 0 : topicData.length;

      final int bodyLength = msgInner.getBody() == null ? 0 : msgInner.getBody().length;

      final int msgLen =
          4 // 1 TOTALSIZE
              + 4 // 2 MAGICCODE
              + 4 // 3 BODYCRC
              + 4 // 4 QUEUEID
              + 4 // 5 FLAG
              + 8 // 6 QUEUEOFFSET
              + 8 // 7 PHYSICALOFFSET
              + 4 // 8 SYSFLAG
              + 8 // 9 BORNTIMESTAMP
              + 8 // 10 BORNHOST
              + 8 // 11 STORETIMESTAMP
              + 8 // 12 STOREHOSTADDRESS
              + 4 // 13 RECONSUMETIMES
              + 8 // 14 Prepared Transaction Offset
              + 4
              + bodyLength // 14 BODY
              + 1
              + topicLength // 15 TOPIC
              + 2
              + propertiesLength // 16 propertiesLength
              + 0;

      // 消息超过设定的最大值
      if (msgLen > this.maxMessageSize) {
        CommitLog.log.warn(
            "message size exceeded, msg total size: "
                + msgLen
                + ", msg body size: "
                + bodyLength
                + ", maxMessageSize: "
                + this.maxMessageSize);
        return new AppendMessageResult(AppendMessageStatus.MESSAGE_SIZE_EXCEEDED);
      }

      // 判断是否有足够空余空间
      if ((msgLen + END_FILE_MIN_BLANK_LENGTH) > maxBlank) {
        this.resetMsgStoreItemMemory(maxBlank);
        // 1 TOTALSIZE
        this.msgStoreItemMemory.putInt(maxBlank);
        // 2 MAGICCODE
        this.msgStoreItemMemory.putInt(CommitLog.BlankMagicCode);
        // 3 剩余空间可能是任何值
        //

        // 此处长度特意设置为maxBlank
        byteBuffer.put(this.msgStoreItemMemory.array(), 0, maxBlank);
        return new AppendMessageResult(
            AppendMessageStatus.END_OF_FILE,
            wroteOffset,
            maxBlank,
            msgId,
            msgInner.getStoreTimestamp(),
            queueOffset);
      }

      // 初始化存储空间
      this.resetMsgStoreItemMemory(msgLen);
      // 1 TOTALSIZE
      this.msgStoreItemMemory.putInt(msgLen);
      // 2 MAGICCODE
      this.msgStoreItemMemory.putInt(CommitLog.MessageMagicCode);
      // 3 BODYCRC
      this.msgStoreItemMemory.putInt(msgInner.getBodyCRC());
      // 4 QUEUEID
      this.msgStoreItemMemory.putInt(msgInner.getQueueId());
      // 5 FLAG
      this.msgStoreItemMemory.putInt(msgInner.getFlag());
      // 6 QUEUEOFFSET
      this.msgStoreItemMemory.putLong(queueOffset);
      // 7 PHYSICALOFFSET
      this.msgStoreItemMemory.putLong(fileFromOffset + byteBuffer.position());
      // 8 SYSFLAG
      this.msgStoreItemMemory.putInt(msgInner.getSysFlag());
      // 9 BORNTIMESTAMP
      this.msgStoreItemMemory.putLong(msgInner.getBornTimestamp());
      // 10 BORNHOST
      this.msgStoreItemMemory.put(msgInner.getBornHostBytes());
      // 11 STORETIMESTAMP
      this.msgStoreItemMemory.putLong(msgInner.getStoreTimestamp());
      // 12 STOREHOSTADDRESS
      this.msgStoreItemMemory.put(msgInner.getStoreHostBytes());
      // 13 RECONSUMETIMES
      this.msgStoreItemMemory.putInt(msgInner.getReconsumeTimes());
      // 14 Prepared Transaction Offset
      this.msgStoreItemMemory.putLong(msgInner.getPreparedTransactionOffset());
      // 15 BODY
      this.msgStoreItemMemory.putInt(bodyLength);
      if (bodyLength > 0) this.msgStoreItemMemory.put(msgInner.getBody());
      // 16 TOPIC
      this.msgStoreItemMemory.put((byte) topicLength);
      this.msgStoreItemMemory.put(topicData);
      // 17 PROPERTIES
      this.msgStoreItemMemory.putShort((short) propertiesLength);
      if (propertiesLength > 0) this.msgStoreItemMemory.put(propertiesData);

      // 向队列缓冲区写入消息
      byteBuffer.put(this.msgStoreItemMemory.array(), 0, msgLen);

      AppendMessageResult result =
          new AppendMessageResult(
              AppendMessageStatus.PUT_OK,
              wroteOffset,
              msgLen,
              msgId,
              msgInner.getStoreTimestamp(),
              queueOffset);

      switch (tranType) {
        case MessageSysFlag.TransactionPreparedType:
          CommitLog.this
              .defaultMessageStore
              .getTransactionStateService()
              .getTranStateTableOffset()
              .incrementAndGet();
          break;
        case MessageSysFlag.TransactionRollbackType:
          break;
        case MessageSysFlag.TransactionNotType:
        case MessageSysFlag.TransactionCommitType:
          // 更新下一次的ConsumeQueue信息
          CommitLog.this.topicQueueTable.put(key, ++queueOffset);
          break;
        default:
          break;
      }

      // 返回结果
      return result;
    }
Пример #5
0
  public PutMessageResult putMessage(final MessageExtBrokerInner msg) {
    // 设置存储时间
    msg.setStoreTimestamp(System.currentTimeMillis());
    // 设置消息体BODY CRC(考虑在客户端设置最合适)
    msg.setBodyCRC(UtilAll.crc32(msg.getBody()));
    // 返回结果
    AppendMessageResult result = null;

    StoreStatsService storeStatsService = this.defaultMessageStore.getStoreStatsService();

    String topic = msg.getTopic();
    int queueId = msg.getQueueId();
    long tagsCode = msg.getTagsCode();

    final int tranType = MessageSysFlag.getTransactionValue(msg.getSysFlag());
    if (tranType == MessageSysFlag.TransactionNotType //
        || tranType == MessageSysFlag.TransactionCommitType) {
      // 延时投递
      if (msg.getDelayTimeLevel() > 0) {
        if (msg.getDelayTimeLevel()
            > this.defaultMessageStore.getScheduleMessageService().getMaxDelayLevel()) {
          msg.setDelayTimeLevel(
              this.defaultMessageStore.getScheduleMessageService().getMaxDelayLevel());
        }

        topic = ScheduleMessageService.SCHEDULE_TOPIC;
        queueId = ScheduleMessageService.delayLevel2QueueId(msg.getDelayTimeLevel());
        tagsCode =
            this.defaultMessageStore
                .getScheduleMessageService()
                .computeDeliverTimestamp(msg.getDelayTimeLevel(), msg.getStoreTimestamp());

        /** 备份真实的topic,queueId */
        msg.putProperty(MessageConst.PROPERTY_REAL_TOPIC, msg.getTopic());
        msg.putProperty(MessageConst.PROPERTY_REAL_QUEUE_ID, String.valueOf(msg.getQueueId()));
        msg.setPropertiesString(MessageDecoder.messageProperties2String(msg.getProperties()));

        msg.setTopic(topic);
        msg.setQueueId(queueId);
      }
    }

    // 写文件要加锁
    synchronized (this) {
      long beginLockTimestamp = this.defaultMessageStore.getSystemClock().now();

      // 这里设置存储时间戳,才能保证全局有序
      msg.setStoreTimestamp(beginLockTimestamp);

      // 尝试写入
      MapedFile mapedFile = this.mapedFileQueue.getLastMapedFile();
      if (null == mapedFile) {
        log.error(
            "create maped file1 error, topic: "
                + msg.getTopic()
                + " clientAddr: "
                + msg.getBornHostString());
        return new PutMessageResult(PutMessageStatus.CREATE_MAPEDFILE_FAILED, null);
      }
      result = mapedFile.appendMessage(msg, this.appendMessageCallback);
      switch (result.getStatus()) {
          // 成功追加消息
        case PUT_OK:
          break;
          // 走到文件末尾
        case END_OF_FILE:
          // 创建新文件,重新写消息
          mapedFile = this.mapedFileQueue.getLastMapedFile();
          if (null == mapedFile) {
            log.error(
                "create maped file2 error, topic: "
                    + msg.getTopic()
                    + " clientAddr: "
                    + msg.getBornHostString());
            return new PutMessageResult(PutMessageStatus.CREATE_MAPEDFILE_FAILED, result);
          }
          result = mapedFile.appendMessage(msg, this.appendMessageCallback);
          break;
          // 消息大小超限
        case MESSAGE_SIZE_EXCEEDED:
          return new PutMessageResult(PutMessageStatus.MESSAGE_ILLEGAL, result);
          // 未知错误
        case UNKNOWN_ERROR:
          return new PutMessageResult(PutMessageStatus.UNKNOWN_ERROR, result);
        default:
          return new PutMessageResult(PutMessageStatus.UNKNOWN_ERROR, result);
      }

      DispatchRequest dispatchRequest =
          new DispatchRequest( //
              topic, // 1
              queueId, // 2
              result.getWroteOffset(), // 3
              result.getWroteBytes(), // 4
              tagsCode, // 5
              msg.getStoreTimestamp(), // 6
              result.getLogicsOffset(), // 7
              msg.getKeys(), // 8
              /** 事务部分 */
              msg.getSysFlag(), // 9
              msg.getQueueOffset(), // 10
              msg.getPreparedTransactionOffset(), // 11
              msg.getProperty(MessageConst.PROPERTY_PRODUCER_GROUP) // 12
              );

      this.defaultMessageStore.putDispatchRequest(dispatchRequest);

      long eclipseTime = this.defaultMessageStore.getSystemClock().now() - beginLockTimestamp;
      if (eclipseTime > 1000) {
        log.warn("putMessage in lock eclipse time(ms) " + eclipseTime);
      }
    }

    // 返回结果
    PutMessageResult putMessageResult = new PutMessageResult(PutMessageStatus.PUT_OK, result);

    // 统计消息SIZE
    storeStatsService.getSinglePutMessageTopicSizeTotal(topic).addAndGet(result.getWroteBytes());

    GroupCommitRequest request = null;

    // 同步刷盘
    if (FlushDiskType.SYNC_FLUSH
        == this.defaultMessageStore.getMessageStoreConfig().getFlushDiskType()) {
      GroupCommitService service = (GroupCommitService) this.flushCommitLogService;
      if (msg.isWaitStoreMsgOK()) {
        request = new GroupCommitRequest(result.getWroteOffset() + result.getWroteBytes());
        service.putRequest(request);
        boolean flushOK =
            request.waitForFlush(
                this.defaultMessageStore.getMessageStoreConfig().getSyncFlushTimeout());
        if (!flushOK) {
          log.error(
              "do groupcommit, wait for flush failed, topic: "
                  + msg.getTopic()
                  + " tags: "
                  + msg.getTags()
                  + " client address: "
                  + msg.getBornHostString());
          putMessageResult.setPutMessageStatus(PutMessageStatus.FLUSH_DISK_TIMEOUT);
        }
      } else {
        service.wakeup();
      }
    }
    // 异步刷盘
    else {
      this.flushCommitLogService.wakeup();
    }

    // 同步双写
    if (BrokerRole.SYNC_MASTER
        == this.defaultMessageStore.getMessageStoreConfig().getBrokerRole()) {
      HAService service = this.defaultMessageStore.getHaService();
      if (msg.isWaitStoreMsgOK()) {
        // 判断是否要等待
        if (service.isSlaveOK(result.getWroteOffset() + result.getWroteBytes())) {
          if (null == request) {
            request = new GroupCommitRequest(result.getWroteOffset() + result.getWroteBytes());
          }
          service.putRequest(request);

          service.getWaitNotifyObject().wakeupAll();

          boolean flushOK =
              // TODO 此处参数与刷盘公用是否合适
              request.waitForFlush(
                  this.defaultMessageStore.getMessageStoreConfig().getSyncFlushTimeout());
          if (!flushOK) {
            log.error(
                "do sync transfer other node, wait return, but failed, topic: "
                    + msg.getTopic()
                    + " tags: "
                    + msg.getTags()
                    + " client address: "
                    + msg.getBornHostString());
            putMessageResult.setPutMessageStatus(PutMessageStatus.FLUSH_SLAVE_TIMEOUT);
          }
        }
        // Slave异常
        else {
          // 告诉发送方,Slave异常
          putMessageResult.setPutMessageStatus(PutMessageStatus.SLAVE_NOT_AVAILABLE);
        }
      }
    }

    // 向发送方返回结果
    return putMessageResult;
  }
Пример #6
0
  /**
   * 服务端使用 检查消息并返回消息大小
   *
   * @return 0 表示走到文件末尾 >0 正常消息 -1 消息校验失败
   */
  public DispatchRequest checkMessageAndReturnSize(
      java.nio.ByteBuffer byteBuffer, final boolean checkCRC, final boolean readBody) {
    try {
      java.nio.ByteBuffer byteBufferMessage =
          ((DefaultAppendMessageCallback) this.appendMessageCallback).getMsgStoreItemMemory();
      byte[] bytesContent = byteBufferMessage.array();

      // 1 TOTALSIZE
      int totalSize = byteBuffer.getInt();

      // 2 MAGICCODE
      int magicCode = byteBuffer.getInt();
      switch (magicCode) {
        case MessageMagicCode:
          break;
        case BlankMagicCode:
          return new DispatchRequest(0);
        default:
          log.warn("found a illegal magic code 0x" + Integer.toHexString(magicCode));
          return new DispatchRequest(-1);
      }

      // 3 BODYCRC
      int bodyCRC = byteBuffer.getInt();

      // 4 QUEUEID
      int queueId = byteBuffer.getInt();

      // 5 FLAG
      int flag = byteBuffer.getInt();
      flag = flag + 0;

      // 6 QUEUEOFFSET
      long queueOffset = byteBuffer.getLong();

      // 7 PHYSICALOFFSET
      long physicOffset = byteBuffer.getLong();

      // 8 SYSFLAG
      int sysFlag = byteBuffer.getInt();

      // 9 BORNTIMESTAMP
      long bornTimeStamp = byteBuffer.getLong();
      bornTimeStamp = bornTimeStamp + 0;

      // 10 BORNHOST(IP+PORT)
      byteBuffer.get(bytesContent, 0, 8);

      // 11 STORETIMESTAMP
      long storeTimestamp = byteBuffer.getLong();

      // 12 STOREHOST(IP+PORT)
      byteBuffer.get(bytesContent, 0, 8);

      // 13 RECONSUMETIMES
      int reconsumeTimes = byteBuffer.getInt();

      // 14 Prepared Transaction Offset
      long preparedTransactionOffset = byteBuffer.getLong();

      // 15 BODY
      int bodyLen = byteBuffer.getInt();
      if (bodyLen > 0) {
        if (readBody) {
          byteBuffer.get(bytesContent, 0, bodyLen);

          // 校验CRC
          if (checkCRC) {
            int crc = UtilAll.crc32(bytesContent, 0, bodyLen);
            if (crc != bodyCRC) {
              log.warn("CRC check failed " + crc + " " + bodyCRC);
              return new DispatchRequest(-1);
            }
          }
        } else {
          byteBuffer.position(byteBuffer.position() + bodyLen);
        }
      }

      // 16 TOPIC
      byte topicLen = byteBuffer.get();
      byteBuffer.get(bytesContent, 0, topicLen);
      String topic = new String(bytesContent, 0, topicLen);

      long tagsCode = 0;
      String keys = "";

      // 17 properties
      short propertiesLength = byteBuffer.getShort();
      if (propertiesLength > 0) {
        byteBuffer.get(bytesContent, 0, propertiesLength);
        String properties = new String(bytesContent, 0, propertiesLength);
        Map<String, String> propertiesMap = MessageDecoder.string2messageProperties(properties);

        keys = propertiesMap.get(MessageConst.PROPERTY_KEYS);
        String tags = propertiesMap.get(MessageConst.PROPERTY_TAGS);
        if (tags != null && tags.length() > 0) {
          tagsCode =
              MessageExtBrokerInner.tagsString2tagsCode(
                  MessageExt.parseTopicFilterType(sysFlag), tags);
        }
      }

      return new DispatchRequest( //
          topic, // 1
          queueId, // 2
          physicOffset, // 3
          totalSize, // 4
          tagsCode, // 5
          storeTimestamp, // 6
          queueOffset, // 7
          keys, // 8
          sysFlag, // 9
          0L, // 10
          preparedTransactionOffset, // 11
          null // 12
          );
    } catch (BufferUnderflowException e) {
      byteBuffer.position(byteBuffer.limit());
    } catch (Exception e) {
      byteBuffer.position(byteBuffer.limit());
    }

    return new DispatchRequest(-1);
  }
  private ByteBuffer messageToByteBuffer(final MessageExt msg) throws IOException {
    int sysFlag = MessageSysFlag.clearCompressedFlag(msg.getSysFlag());
    if (msg.getBody() != null) {
      if (msg.getBody().length
          >= this.filtersrvController.getFiltersrvConfig().getCompressMsgBodyOverHowmuch()) {
        byte[] data =
            UtilAll.compress(
                msg.getBody(), this.filtersrvController.getFiltersrvConfig().getZipCompressLevel());
        if (data != null) {
          msg.setBody(data);
          sysFlag |= MessageSysFlag.CompressedFlag;
        }
      }
    }

    final int bodyLength = msg.getBody() != null ? msg.getBody().length : 0;
    byte[] topicData = msg.getTopic().getBytes(MixAll.DEFAULT_CHARSET);
    final int topicLength = topicData.length;
    String properties = MessageDecoder.messageProperties2String(msg.getProperties());
    byte[] propertiesData = properties.getBytes(MixAll.DEFAULT_CHARSET);
    final int propertiesLength = propertiesData.length;
    final int msgLen =
        4 // 1 TOTALSIZE
            + 4 // 2 MAGICCODE
            + 4 // 3 BODYCRC
            + 4 // 4 QUEUEID
            + 4 // 5 FLAG
            + 8 // 6 QUEUEOFFSET
            + 8 // 7 PHYSICALOFFSET
            + 4 // 8 SYSFLAG
            + 8 // 9 BORNTIMESTAMP
            + 8 // 10 BORNHOST
            + 8 // 11 STORETIMESTAMP
            + 8 // 12 STOREHOSTADDRESS
            + 4 // 13 RECONSUMETIMES
            + 8 // 14 Prepared Transaction Offset
            + 4
            + bodyLength // 14 BODY
            + 1
            + topicLength // 15 TOPIC
            + 2
            + propertiesLength // 16 propertiesLength
            + 0;

    ByteBuffer msgStoreItemMemory = ByteBuffer.allocate(msgLen);

    final MessageExt msgInner = msg;

    // 1 TOTALSIZE
    msgStoreItemMemory.putInt(msgLen);
    // 2 MAGICCODE
    msgStoreItemMemory.putInt(CommitLog.MessageMagicCode);
    // 3 BODYCRC
    msgStoreItemMemory.putInt(UtilAll.crc32(msgInner.getBody()));
    // 4 QUEUEID
    msgStoreItemMemory.putInt(msgInner.getQueueId());
    // 5 FLAG
    msgStoreItemMemory.putInt(msgInner.getFlag());
    // 6 QUEUEOFFSET
    msgStoreItemMemory.putLong(msgInner.getQueueOffset());
    // 7 PHYSICALOFFSET
    msgStoreItemMemory.putLong(msgInner.getCommitLogOffset());
    // 8 SYSFLAG
    msgStoreItemMemory.putInt(sysFlag);
    // 9 BORNTIMESTAMP
    msgStoreItemMemory.putLong(msgInner.getBornTimestamp());
    // 10 BORNHOST
    msgStoreItemMemory.put(msgInner.getBornHostBytes());
    // 11 STORETIMESTAMP
    msgStoreItemMemory.putLong(msgInner.getStoreTimestamp());
    // 12 STOREHOSTADDRESS
    msgStoreItemMemory.put(msgInner.getStoreHostBytes());
    // 13 RECONSUMETIMES
    msgStoreItemMemory.putInt(msgInner.getReconsumeTimes());
    // 14 Prepared Transaction Offset
    msgStoreItemMemory.putLong(msgInner.getPreparedTransactionOffset());
    // 15 BODY
    msgStoreItemMemory.putInt(bodyLength);
    if (bodyLength > 0) msgStoreItemMemory.put(msgInner.getBody());
    // 16 TOPIC
    msgStoreItemMemory.put((byte) topicLength);
    msgStoreItemMemory.put(topicData);
    // 17 PROPERTIES
    msgStoreItemMemory.putShort((short) propertiesLength);
    if (propertiesLength > 0) msgStoreItemMemory.put(propertiesData);

    return msgStoreItemMemory;
  }