How RocketMQ Handles Concurrency: Deep Dive into Its Design Principles
This article dissects RocketMQ's concurrency mechanisms, explaining why it uses ReentrantReadWriteLock with HashMaps, how Semaphore controls async send rates, the SemaphoreReleaseOnlyOnce wrapper, the CountDownLatch‑based sync‑to‑async pattern, and the CompletableFuture redesign that reduces blocking in message replication.
RocketMQ is a high‑performance distributed messaging system that employs several advanced concurrency techniques. The article first examines the read‑write lock usage for routing metadata stored in three HashMaps within the Nameserver. Because read requests far outnumber writes, a JDK ReentrantReadWriteLock protects the HashMaps, with write locks for updates and read locks for queries.
Why Not Use ConcurrentHashMap?
The Nameserver cannot rely on ConcurrentHashMap alone because updates must modify multiple maps atomically; a simple concurrent container only guarantees thread‑safety for its own structure. In JDK 8 and earlier, ConcurrentHashMap used segment‑level locks, making its read concurrency lower than the read‑write lock approach. After JDK 8, CAS‑based optimizations give ConcurrentHashMap some advantages, but the lock‑based design remains necessary for consistency across the three maps.
Semaphore Usage Tricks
RocketMQ controls the concurrency of asynchronous sends with a Semaphore. The example creates a semaphore with 10 permits and spawns 100 threads, each attempting to acquire a permit for up to 3000 ms. If acquisition succeeds, the business logic runs; otherwise, a fallback path executes. The article highlights two key points:
tryAcquire returns false after the timeout if no permits remain; release must be called only when acquisition succeeded, otherwise permits are over‑issued.
Repeated release calls cause the effective concurrency to exceed the intended limit, as demonstrated by a test where two threads obtained permits, raising the concurrency from the planned 5 to 6.
To prevent duplicate releases, RocketMQ wraps the semaphore in a SemaphoreReleaseOnlyOnce class that uses an AtomicBoolean and CAS to ensure release is invoked at most once per business thread.
public class SemaphoreReleaseOnlyOnce {
private final AtomicBoolean released = new AtomicBoolean(false);
private final Semaphore semaphore;
public SemaphoreReleaseOnlyOnce(Semaphore semaphore) {
this.semaphore = semaphore;
}
public void release() {
if (this.semaphore != null) {
if (this.released.compareAndSet(false, true)) {
this.semaphore.release();
}
}
}
public Semaphore getSemaphore() {
return semaphore;
}
}Synchronous‑to‑Asynchronous Programming Technique
RocketMQ replaces the classic Future pattern with a lighter CountDownLatch to decouple the main thread from the flush thread. The GroupCommitService receives a commit request without blocking; the main thread later calls waitForFlush, which internally awaits the latch with a timeout. The flush thread signals completion via countDown(), unblocking the main thread.
CompletableFuture Programming Tricks
Since JDK 8, RocketMQ leverages CompletableFuture to achieve true asynchronous processing in its message replication path. Prior to version 4.7.0, the SendMessageProcessor blocked while waiting for the slave node to replicate data. The redesign returns a CompletableFuture from HaService; the async replication thread completes the future, allowing the main thread to continue handling other requests.
The key code registers a callback with thenApply, which sends the replication result back to the client once the future completes, effectively decoupling message sending from replication and improving throughput.
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.
Code Farming
Senior engineer at a top internet giant, sharing Java, AI, tech knowledge, growth insights, and interview experiences.
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.
