Part 08 · RabbitMQ · 8.1.02

Consumer acknowledgements và publisher confirms

Publisher confirm bảo vệ hop producer → broker; consumer acknowledgement bảo vệ hop broker → consumer. Hai cơ chế độc lập và không chứng minh side effect trong application database đã commit.

Failure-window rule: muốn không mất work thì phải chấp nhận khả năng duplicate ở ranh giới crash. At-least-once transport cần idempotent business processing, không chỉ manual ack.

1. Hai delivery lifecycles độc lập

producer -- publish + confirm --> exchange / queue
queue    -- delivery + ack ----> consumer / business database

Confirm trả lời broker đã xử lý publish đến mức nào theo queue/storage configuration. Ack trả lời consumer đã xử lý delivery và broker có thể quên nó. Không có transaction tự động xuyên cả producer DB, broker và consumer DB; mỗi boundary cần protocol hoặc pattern riêng.

EN interview answer · Confirm vs acknowledgement

Publisher confirms protect the producer-to-broker handoff, while consumer acknowledgements protect broker-to-consumer processing. They solve different failure windows. I still design consumers to be idempotent because redelivery can occur.

2. Consumer acknowledgement và redelivery

Mỗi delivery có delivery tag tăng dần và chỉ có ý nghĩa trong channel nhận nó. basic.ack, basic.nack hoặc basic.reject phải gửi trên cùng channel; ack bằng channel khác gây protocol exception. Multiple ack có thể xác nhận mọi tag đến một mốc, nên correlation sai có thể mất nhiều delivery.

Thời điểm ackCrash windowKết quả
Trước business commitCrash sau ack, trước commitBroker xóa delivery; work có thể mất
Sau business commitCrash sau commit, trước ackBroker redeliver; side effect có thể lặp
Auto ack khi dispatchConsumer chết khi đang xử lýKhông redelivery; phù hợp work có thể bỏ
Nack/reject requeuePoison message quay lại ngayHot loop nếu không có retry policy

redelivered chỉ là hint broker biết delivery có thể đã gửi trước đó; false không chứng minh business event chưa từng xử lý, và true không thay deduplication.

3. Publisher confirms và unknown outcome

Confirm mode gán sequence cho publishes; broker gửi ack/nack riêng lẻ hoặc theo batch. Producer throughput tốt hơn khi publish pipeline rồi correlate confirmations, thay vì chờ từng message synchronously. Cần giới hạn in-flight set, timeout, nack handling và recovery khi channel/connection đóng.

Timeout không bằng failure. Producer mất connection trước khi nhận confirm có thể không biết broker đã nhận message hay chưa. Retry mù có thể duplicate; không retry có thể mất. Dùng stable message/business ID, outbox và idempotent consumer để xử lý uncertainty.

Publisher confirms không atomic với application DB. AMQP transactions có overhead lớn và vẫn không gộp broker transaction với database transaction; transactional outbox giải quyết dual-write bằng cách commit business change + outbox record cùng DB transaction rồi relay ra broker.

4. Durability scope của confirm

Ý nghĩa durability phụ thuộc queue type, replication, durable declaration và persistent message. Confirm cho transient message hoặc non-durable queue không biến nó thành durable. Với replicated queue, confirm timing tuân theo implementation/queue semantics; application phải chọn cấu hình theo tolerated loss và latency.

5. Prefetch, throughput và fairness

Prefetch giới hạn số unacknowledged deliveries consumer/channel được giữ, tạo backpressure giữa broker và worker. Quá cao làm một consumer chiếm backlog, tăng memory và số work phải redeliver khi crash; quá thấp tăng round-trip và để worker nhàn.

Ước lượng ban đầu dựa processing latency × desired throughput/concurrency, rồi đo. Payload lớn, processing variance cao và strict fairness thường cần prefetch thấp hơn. Per-consumer và global channel limits có semantics/cost khác; kiểm client/broker version đang dùng.

6. Idempotency và bằng chứng vận hành

Lưu message ID hoặc business idempotency key bằng unique constraint trong cùng transaction với side effect. Pattern check-then-insert tách rời có race khi hai deliveries xử lý đồng thời. Với external side effect, truyền idempotency key xuống downstream hoặc thiết kế state transition conditional.

Pseudocode · Idempotent consumer: unique key và business change nằm trong cùng local transaction; ack/offset commit là bước sau đó.

begin transaction
  insert processed_message(event_id) -- unique
  apply business change
commit
ack/commit offset

Theo dõi publish confirms/nacks/timeouts, unconfirmed count/age, unacked deliveries, redelivery rate, consumer utilization, processing latency và duplicate suppression. Test bằng cách kill process ở từng điểm trước/sau DB commit và trước/sau ack/confirm.

Review checklist: ack sau durable business outcome; duplicate safe; nack/requeue không hot-loop; confirms asynchronous và bounded; unknown outcome có policy; prefetch được đo; channel ownership đúng; metrics tách publish, route, process và commit.
Tài liệu: Consumer Acknowledgements and Publisher Confirms · Consumer Prefetch · Publisher Confirms Tutorial · RabbitMQ Reliability Guide