Help Center> Distributed Message Service for RocketMQ> Best Practices> Deduplicating Messages Through Message Idempotence
Updated on 2023-10-24 GMT+08:00

Deduplicating Messages Through Message Idempotence

Overview

In RocketMQ service processes, an idempotent message process refers to a situation where a message is re-sent and consumed for multiple times and each consumption result is the same, having no negative effects on services. Idempotent messages ensure consistency in the final processing results. Services are not affected no matter how many times a message is re-sent.

Message Repetition Scenarios

In actual applications, messages are re-sent because of intermittent network disconnections and client faults during message production or consumption. Message repetition can be classified into two scenarios.

  • A producer repeatedly sends a message:

    If a producer successfully sends a message to the server but does not receive a successful response due to an intermittent network disconnection, the producer determines that the message failed to be sent and tries resending the message. In this case, the server receives two messages of the same content. Consumers consume two messages of different IDs but the same content.

  • A consumer repeatedly consumes a message:

    A message is successfully delivered to a consumer and processed. If the consumer fails to commit an updated offset to the server due to an intermittent network disconnection, the server determines that the message failed to be delivered. To ensure that the message is consumed at least once, the server retries delivering the message. As a result, the consumer receives the same message (ID and content) as the previously processed one.

Take payment as an example. Assume that a customer makes payment and receives multiple bills due to unstable Internet connection. However, the billing should take place only once and the merchant should generate only one order placement.

Procedure

Messages with different IDs may have the same content, so the ID cannot be used as the unique identifier. RocketMQ supports idempotent messages by using the message key (unique service identifier) to identify messages. The sample code for configuring a message key is as follows:

Message message = new Message();
message.setKey("Order_id");    // Set the message key, which can be the unique service identifier such as the order placement ID.
SentResult sendResult = mqProducer.send(message);

When a producer sends a message, the message has a unique key. When consuming the message, a consumer reads the unique message identifier (such as the order placement ID) with getKeys(). The service logic can implement idempotence with the unique identifier.