Preventing Message Loss in RocketMQ: Scenarios and Solutions
This article analyzes the possible message loss scenarios in RocketMQ—including producer network issues, broker persistence failures, and consumer acknowledgment problems—and presents practical solutions such as transactional messaging, synchronous disk flushing, and proper consumer handling to achieve zero message loss.
When using a message queue (MQ) in a project, message loss can be fatal, especially in financial transaction scenarios; this article examines the various situations in which RocketMQ may lose messages.
It first shows a simple consumption flow diagram and then identifies three main stages where loss can occur: the producer sending messages to RocketMQ, the broker persisting messages to disk, and the consumer acknowledging successful consumption.
Scenario 1: Network jitter or communication exceptions while the producer sends a message can cause the message to be lost.
Scenario 2: Message loss can happen in two ways: (a) RocketMQ writes messages to the OS cache first and flushes them to disk asynchronously; if the broker crashes before the async flush completes, the messages are lost, and (b) even after being flushed to disk, a lack of backup means a disk failure will also lose the messages.
Scenario 3: If a consumer reports successful consumption to RocketMQ before actually finishing processing and then crashes, RocketMQ assumes the message is consumed and the data is lost.
To achieve zero message loss, the article proposes solutions for each scenario:
For scenario 1, use RocketMQ's built‑in transaction mechanism: send a half message, execute the core business logic, and commit the half message only if the logic succeeds; otherwise roll back and delete the half message.
For scenario 2, change the broker’s flushDiskType configuration from ASYNC_FLUSH to SYNC_FLUSH to ensure synchronous disk writes, and deploy RocketMQ in a master‑slave cluster so that data is replicated across followers, protecting against disk failures.
For scenario 3, ensure the consumer only acknowledges ConsumeConcurrentlyStatus.CONSUME_SUCCESS after the business processing is truly completed; if the consumer crashes before acknowledging, RocketMQ will automatically fail‑over the message to another consumer in the group.
// Register a message listener to process messages
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
// Process the message
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});The article also warns that employing these zero‑loss strategies can significantly impact performance and throughput due to additional transaction steps, synchronous flushing, and replication overhead.
Source: https://blog.csdn.net/LO_YUN/article/details/103949317
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
