Backend Development 41 min read

Why Use Message Queues? Exploring RocketMQ’s Architecture, Features & Best Practices

This article explains the three main reasons for using message queues—decoupling, asynchrony, and peak‑shaving—then compares popular MQ products, dives deep into RocketMQ’s components, models, reliability, ordering, filtering, delay, transactions, dead‑letter handling, high‑availability, storage, load balancing, and long‑polling, providing a comprehensive guide for backend engineers.

macrozheng
macrozheng
macrozheng
Why Use Message Queues? Exploring RocketMQ’s Architecture, Features & Best Practices

1. Why Use a Message Queue?

Message queues have three major purposes, illustrated with an e‑commerce order scenario:

Decoupling : Before a queue, the order service must call inventory, marketing, etc., directly. After introducing a queue, the order service publishes a message and downstream services consume it independently, achieving decoupling.

Asynchrony : After payment, tasks such as inventory deduction, points addition, and notifications can be processed asynchronously, reducing response time. Only the order‑status update remains synchronous.

Peak Shaving : During flash‑sale spikes, traffic can overwhelm servers. By queuing requests and releasing them at a rate the service can handle, the system can absorb short‑term high loads.

2. Why Choose RocketMQ?

A comparison of major message‑queue products shows that RocketMQ offers high performance, high throughput, strong reliability, and an active Chinese community, making it suitable for high‑concurrency, low‑latency scenarios.

RabbitMQ : Lightweight and easy to deploy, but lower throughput and limited extensibility.

RocketMQ : Excellent performance, high throughput, stable, with a vibrant community; however, client language support is limited (Java and C++).

Kafka : Very high throughput and good compatibility, but higher latency due to batch processing.

Our user‑facing system requires low latency and high throughput, so we selected RocketMQ.

3. Advantages and Disadvantages of RocketMQ

Single‑machine throughput: up to 100k TPS.

High availability with distributed architecture.

Zero message loss after parameter tuning.

Rich MQ features, good extensibility.

Supports billions of messages without performance degradation.

Java source code simplifies custom business extensions.

Designed for high‑reliability financial‑Internet scenarios.

Disadvantages : Limited client language support; lacks native JMS implementation, requiring code changes for migration.

4. Message Queue Models

Two models exist: the Queue model (point‑to‑point) and the Publish/Subscribe model (topic‑based).

5. RocketMQ’s Message Model

RocketMQ uses the standard publish/subscribe model. A message consists of:

Message : the payload.

Topic : the first‑level classification (e.g., order, logistics).

Tag : optional second‑level classification for finer filtering.

Group : consumer group ensuring each group receives a full copy of the topic.

Message Queue : multiple queues under a topic for parallel consumption.

Offset : the index of a message within a queue (conceptually an array index).

6. Consumption Modes

Two modes are available:

Clustering (load‑balanced): a consumer group shares queues; each queue is consumed by only one consumer in the group.

Broadcasting : every consumer in the group receives all messages.

7. Basic Architecture of RocketMQ

RocketMQ consists of four parts: NameServer (service discovery), Broker (store and forward), Producer (message publisher), and Consumer (message subscriber). All parts are typically deployed in clusters for high availability.

8. Detailed Roles

NameServer

A stateless server similar to Zookeeper but lighter. It registers brokers, provides routing information to producers and consumers, and maintains heartbeat connections.

Broker

Responsible for storing and forwarding messages. It maintains consumer queues (indexes) and a commit log (actual message data).

Producer

Publishes messages. Supports synchronous, asynchronous, and one‑way sending modes.

Synchronous : waits for broker acknowledgment before proceeding.

Asynchronous : sends without waiting, using callbacks for success/failure.

One‑way : fire‑and‑forget, suitable for low‑reliability scenarios like log collection.

Consumer

Consumes messages, supporting push or pull modes, and both clustering and broadcasting consumption.

9. Ensuring Message Availability, Reliability, and No Loss

Message loss can occur during production, storage, or consumption. Mitigation strategies:

Production : use request‑acknowledgment, retry on failure, and check logs for timeouts.

Storage : configure brokers for synchronous flush, enable master‑slave replication, and ensure messages are persisted to the commit log.

Consumption : acknowledge only after business logic succeeds.

10. Handling Duplicate Messages

Achieving exactly‑once delivery is hard. RocketMQ guarantees delivery but may produce duplicates. Solutions:

Idempotent business logic : make repeated processing harmless.

Message deduplication : store a unique identifier (e.g., order ID) in a database with a unique constraint; duplicate inserts are rejected.

11. Dealing with Message Backlog

Two approaches to clear backlog:

Scale out consumers when the number of queues exceeds consumer count.

Increase the number of queues (or create a temporary topic) and migrate messages, then consume from the expanded set.

12. Ordered Messages

Two types:

Global order : all messages of a topic must be consumed in order; requires a single queue and single‑threaded producer/consumer.

Partial order : only messages with the same key (e.g., order ID) need ordering; the producer sends them to the same queue, and the consumer processes that queue sequentially.

13. Message Filtering

Two filtering strategies:

Broker‑side filtering based on consumer logic (higher overhead).

Consumer‑side filtering using tags (simpler, but unnecessary messages travel over the network).

Common methods:

Tag filtering (e.g., subscribe to TAGA || TAGB).

SQL expression filtering (e.g., a BETWEEN 0 AND 3).

Custom filter server for complex logic.

14. Delayed Messages

Use cases include order timeout cancellation. RocketMQ supports delayed delivery by setting a delay level on the message. Supported levels are fixed (e.g., 1s, 5s, 10s, up to 2h).

<code>DefaultMQProducer producer = new DefaultMQProducer("ExampleProducerGroup");
producer.start();
int totalMessagesToSend = 100;
for (int i = 0; i < totalMessagesToSend; i++) {
    Message message = new Message("TestTopic", ("Hello scheduled message " + i).getBytes());
    // Delay level 3 = 10 seconds
    message.setDelayTimeLevel(3);
    producer.send(message);
}
</code>

15. Distributed Transactional Messages (Half Messages)

Half messages are stored in the broker but not delivered to consumers until the producer confirms the local transaction outcome. The flow:

Producer sends a half message.

Broker stores it as non‑deliverable.

Producer executes local transaction.

Producer sends commit or rollback to broker.

If broker does not receive confirmation, it periodically checks the producer for transaction status and then commits or discards accordingly.

16. Dead‑Letter Queue

Messages that repeatedly fail consumption are moved to a special dead‑letter queue after exceeding retry limits. Each consumer group has its own dead‑letter queue, which retains messages for three days before automatic deletion.

17. High Availability of RocketMQ

NameServer clusters provide stateless high availability. Broker HA is achieved via clustering and master‑slave replication. Producers write to masters; consumers can read from either master or slave. Automatic failover ensures continuity when a master becomes unavailable.

18. Overall Working Process

Brokers register with all NameServers and send heartbeats.

Producers obtain broker addresses from NameServers and send messages using load‑balancing.

Consumers also fetch broker info from NameServers and pull messages.

19. Why RocketMQ Does Not Use Zookeeper

Reasons include:

Zookeeper follows CP semantics, which can cause unavailability during leader election.

Performance limitations: Zookeeper writes are not horizontally scalable.

Heavy persistence mechanisms unnecessary for simple service discovery.

Producers cache routing info, reducing dependence on the registry.

20. Broker Data Storage

RocketMQ uses three file types:

CommitLog : sequential log of message bodies and metadata (default 1 GB per file).

ConsumeQueue : logical index files per topic/queue, storing offset, size, and tag hash for fast lookup.

IndexFile : hash‑based index for key or time‑range queries.

21. File Read/Write Mechanisms

RocketMQ leverages OS page cache, sequential I/O, and zero‑copy via

MappedByteBuffer

. ConsumeQueue reads are mostly sequential and benefit from page‑cache prefetching, while CommitLog writes use memory‑mapped files to reduce copy overhead.

22. Message Flushing

Two flushing strategies:

Synchronous flush : broker waits for data to be persisted to disk before acknowledging the producer.

Asynchronous flush : broker acknowledges immediately and a background thread flushes data later.

23. Load Balancing

Load balancing is performed on the client side:

Producer : selects a MessageQueue from TopicPublishInfo, optionally filtering out unavailable brokers based on latency‑fault tolerance.

Consumer : periodically runs a rebalance service that assigns MessageQueues to consumers within a group using an average‑allocation algorithm, handling both clustering and broadcasting modes.

24. Long‑Polling

If a pull request finds no messages, the broker can suspend the request (long‑polling) for a configurable timeout, releasing it when new messages arrive or the timeout expires.

<code>if (ResponseCode.PULL_NOT_FOUND) {
    if (brokerAllowSuspend && hasSuspendFlag) {
        long pollingTimeMills = suspendTimeoutMillisLong;
        // create PullRequest and hold it
        brokerController.getPullRequestHoldService().suspendPullRequest(topic, queueId, pullRequest);
    }
}
</code>
distributed systemsbackend developmentMessage QueuerocketmqMessaging Architecture
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.