All Products
Search
Document Center

ApsaraMQ for RocketMQ:Normal messages

Last Updated:Nov 14, 2023

Normal messages are messages that have no special features in ApsaraMQ for RocketMQ. Normal messages are different from featured messages such as ordered, scheduled, delayed, and transactional messages. This topic describes the scenarios, working mechanism, use methods, and usage notes of normal messages.

Scenarios

In most cases, normal messages are used in microservice decoupling, data integration, and event-driven scenarios. Most of the scenarios have high requirements on transmission reliability and general requirements on the timing and sequence of message processing.

Scenario 1: Asynchronous decoupling of microservices

在线消息处理

The preceding figure shows an online e-commerce transaction scenario. In this scenario, the upstream order system encapsulates order placement and payment as an independent normal message and sends the message to the ApsaraMQ for RocketMQ broker. Then, downstream systems subscribe to the message from the broker on demand and process tasks based on the local consumption logic. Messages are independent of each other and do not need to be associated.

Scenario 2: Data integration and transmission

数据传输

The preceding figure uses offline log collection as an example. An instrumentation component is used to collect operation logs from frontend applications and forward the logs to ApsaraMQ for RocketMQ. Each message is a piece of log data that requires no processing by ApsaraMQ for RocketMQ. ApsaraMQ for RocketMQ needs to only send the log data to the downstream storage system. Subsequent tasks are processed by backend applications.

Working mechanism

What is a normal message?

Normal messages are messages with the basic messaging feature in ApsaraMQ for RocketMQ. Normal messages support asynchronous decoupled communications between producers and consumers.

生命周期

Lifecycle of a normal message

  • Initialization

    The message is built and initialized by the producer and is ready to be sent to a broker.

  • Pending consumption

    The message is sent to the broker and is visible and available to the consumer.

  • Being consumed

    The message is obtained by the consumer and processed based on the local consumption logic of the consumer.

    In this process, the broker waits for the consumer to return the consumption result. If no response is received from the consumer in a specific period of time, ApsaraMQ for RocketMQ performs retries on the message. For more information, see Consumption retry.

  • Consumption commit

    The consumer completes the consumption and commits the consumption result to the broker. The broker marks whether the current message is consumed.

    By default, ApsaraMQ for RocketMQ retains all messages. When the consumption result is committed, the message is marked as consumed instead of being immediately deleted. Messages are deleted only if the retention period expires or the system has insufficient storage space. Before a message is deleted, the consumer can re-consume the message.

  • Message deletion

    If the retention period of message expires or the storage space is insufficient, ApsaraMQ for RocketMQ deletes the earliest stored messages from the physical file in a rolling manner. For more information, see Message storage and cleanup.

Limits

Normal messages support only topics whose MessageType is set to Normal.

Examples

You can specify message keys and tags to filter or search for normal messages. The following code provides an example on how to send and receive normal messages in Java.

For information about the complete sample code, see Apache RocketMQ 5.x SDKs (recommended).

// Send normal messages. 
MessageBuilder messageBuilder = new MessageBuilder();
Message message = messageBuilder.setTopic("topic")
    // The message key. The system can use the key to locate the message. 
    .setKeys("messageKey")
    // The message tag. The consumer can use the tag to filter the message. 
    .setTag("messageTag")
    // The message body. 
    .setBody("messageBody".getBytes())
    .build();
try {
    // Send the message. You need to take note of the sending result and capture exceptions such as failures. 
    SendReceipt sendReceipt = producer.send(message);
    System.out.println(sendReceipt.getMessageId());
} catch (ClientException e) {
    e.printStackTrace();
}

// Consumption example 1: When you consume a normal message in push mode, you need to only process the message in the message listener. 
MessageListener messageListener = new MessageListener() {
    @Override
    public ConsumeResult consume(MessageView messageView) {
        System.out.println(messageView);
        // Return the status based on the consumption result. 
        return ConsumeResult.SUCCESS;
    }
};

// Consumption example 2: When you consume a normal message in simple mode, you must actively pull the message for consumption and commit the consumption result. 
List<MessageView> messageViewList = null;
try {
    messageViewList = simpleConsumer.receive(10, Duration.ofSeconds(30));
    messageViewList.forEach(messageView -> {
        System.out.println(messageView);
        // After consumption is complete, you must invoke ACK to commit the consumption result. 
        try {
            simpleConsumer.ack(messageView);
        } catch (ClientException e) {
            e.printStackTrace();
        }
    });
} catch (ClientException e) {
    // If the message fails to be pulled due to throttling or other reasons, you must re-initiate the request to obtain the message. 
    e.printStackTrace();
}

Usage notes

Set a globally unique key for each message to facilitate troubleshooting

ApsaraMQ for RocketMQ allows you to specify custom message keys. You can use the key of a message to efficiently query the message and its trace.

Therefore, when you send a message, we recommend that you use the unique information about your business, such as the order ID or user ID, as the key. This helps you quickly locate the message in subsequent queries.