[Bug] Bare lock busy-wait without yield in ack/changeInvisibleTime processors pins ack executor threads
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 35/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Đình trệ
- Công nghệ
- java
- Lĩnh vực
- backend, distributed-systems
Hướng nghiên cứu
Read the listed lock loops in AckMessageProcessor.java and ChangeInvisibleTimeProcessor.java, then compare them with PopConsumerService#tryLockForPop and the ackMessageExecutor registration in BrokerController.java. Check the linked pull request #11384 for current work. Done means the listed contended paths yield while preserving their lock behavior.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Before Creating the Bug Report
- I found a bug. The issue list contains no issue matching my bug.
Your Environment
- RocketMQ version: 5.4.x (current develop)
Describe the Bug
Several pop/ack paths acquire the consumer/queue lock with a bare busy-wait that has no Thread.yield():
AckMessageProcessor#ackOrderly—while (!queueLockManager.tryLock(lockKey)) {}(broker/src/main/java/org/apache/rocketmq/broker/processor/AckMessageProcessor.java:405)AckMessageProcessor#ackOrderly(KV service path) —while (!consumerLockService.tryLock(consumeGroup, topic)) {}(AckMessageProcessor.java:448)AckMessageProcessor#ackLite—while (!consumerLockService.tryLock(lockKey)) {}(AckMessageProcessor.java:538)ChangeInvisibleTimeProcessor#changeInvisibilityDuration— same shape (ChangeInvisibleTimeProcessor.java:203, :235, :389)
All of these are registered on the shared ackMessageExecutor (BrokerController.java:1204-1213), so each contending request pins one worker thread at 100% CPU for the entire contention window:
- Under a
(group, topic)contention burst, several executor workers can be stuck spinning at once, cutting the executor's effective parallelism for every other ack / changeInvisibleTime request on the broker. - On core-saturated brokers the spinning threads compete for CPU with the very lock holders that must finish for the spin to exit, extending the wait beyond the actual critical-section length.
The codebase already establishes the correct pattern for this lock service: PopConsumerService#tryLockForPop (added by #10828) spins with Thread.yield() and a comment explaining why the spin is kept — same consumerLockService, same contention shape, but it yields.
Steps to Reproduce
Code inspection + any workload where two consumers of the same group ack/changeInvisibleTime concurrently for the same topic: the losing request's thread spins in the while loop with no yield until the holder releases (or PopConsumerLockService.removeTimeout() self-heals a stale entry).
What Did You Expect to See?
The spin semantics preserved (these paths must hold the lock to commit offsets atomically) but with Thread.yield() in the loop, matching tryLockForPop — so a contending worker yields its core to the holder instead of burning it.
Additional Context
None
- Ngôn ngữ chính
- Java
- Star
- 22.7k
- Fork
- 12k
- Merge trung bình
- 4 ngày 20 giờ
- Pull request đã merge (30 ngày)
- 11
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của apache/rocketmq
-
[Bug] RemotingHelper.connect swaps the socket send and receive buffer configurationCó thể đã có người làm @amalsaidov đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
CompressionType.of fails under the Turkish localeCó thể đã có người làm @sharanggupta đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 83/100
Maintainer thường phản hồi trong vòng 1 ngày
-
[rocketmq-client-python] TransactionMQProducer allocates an unused producer during initializationĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug] notifyMasterOnline aborts the long-polling wake-up with a NullPointerException when an arrival drains a bucket firstCó thể đã có người làm @iloveeyjafjalla đã nhận 30 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
apache/rocketmq#11441 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Enhancement] FilterFactory duplicate-registration and unregister semantics lack testsCó thể đã có người làm @chennaji9 đã nhận 34 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
apache/rocketmq#11340 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của apache/rocketmq
Issue tương tự
-
bug emitter:client:csharp
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
microsoft/typespec#12572 · 1 bình luận · 1 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
GCC 15.2: -Wcast-qual warning - cast discards const qualifier from pointer target type (H5trace.c)Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 73/100
Maintainer thường phản hồi trong vòng 1 ngày
-
needs-area-label
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 2 ngày
-
area/ai area/backend component/zeebe kind/task
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
spAnser/reacharound#38 ·