RabbitMQ classic, quorum hay stream: chọn queue type nào? Trung cấp
Thời gian đọc ước tính: 6 phút
Cần đọc trước
Vấn đề
Phần tiêu đề “Vấn đề”Dự án mới có ba luồng: email xác nhận đơn (một worker một job, chịu được mất một node), reply queue tạm cho một request nội bộ, và audit feed mà nhiều service cần đọc lại. Dùng cùng một loại queue cho cả ba thì ít nhất một yêu cầu bị sai.
RabbitMQ 4.x có classic, quorum và stream. Chúng khác nhau về cơ chế lưu, replication và cách đọc, không phải ba nấc “nhanh, vừa, chậm”.
Chọn nhanh
Phần tiêu đề “Chọn nhanh”Mặc định: quorum queue cho mọi queue durable chứa job. Docs RabbitMQ mô tả quorum là lựa chọn khi cần queue replicated, highly available. Classic chỉ cho queue tạm hoặc khi chấp nhận rủi ro mất node. Stream khi cần đọc lại.
Đang tải diagram…
Ma trận tính năng
Phần tiêu đề “Ma trận tính năng”| Tính năng | Classic | Quorum | Stream |
|---|---|---|---|
| Mô hình đọc | Message bị xóa sau ack | Message bị xóa sau ack | Log append-only, đọc theo offset, không xóa khi đọc |
| Replication (4.x) | Không | Có (Raft, mặc định 3 replica) | Có |
| Confirm gửi khi | Message đã ghi đĩa (persistent, durable queue) | Đã replicate tới đa số | Đã tới đa số replica |
| Replay | Không | Không | Có, trong cửa sổ retention |
| Exclusive / transient | Có | Không (luôn durable, không exclusive) | Không |
| Priority | Có | Có từ 4.3 (0 đến 31); x-max-priority bị bỏ qua |
Không |
| Message TTL | Có | Có | Không (dùng retention) |
| Dead-letter | Có | Có, gồm at-least-once | Không |
Poison message (x-delivery-limit) |
Không | Có, mặc định 20 | Không |
| Global QoS | Có | Không | Không |
| Giữ message trong RAM | Một phần (CQv2 nạp từ đĩa khi cần) | Không bao giờ | Không bao giờ |
Ba điểm đã đối chiếu docs: classic là non-replicated từ 4.0; quorum và stream đều lỗi channel với global QoS; stream retention đánh giá theo segment, và không đặt age hay size thì log lớn dần tới khi đầy đĩa.
Cấu hình và argument đã xác minh
Phần tiêu đề “Cấu hình và argument đã xác minh”Quorum queue x-queue-type = quorum x-quorum-initial-group-size = 3 # mặc định 3, nên là số lẻ x-delivery-limit = 20 # mặc định 20 từ 4.0, -1 là tắt (không khuyến nghị) policy dead-letter-strategy = at-least-once # kèm overflow=reject-publish
Stream x-queue-type = stream x-max-age = 7D # mặc định: không đặt x-max-length-bytes = ... # mặc định: không đặt x-stream-max-segment-size-bytes = 500000000 # mặc định 500 MBConsumer AMQP 0-9-1 của stream phải manual ack, đặt prefetch, và chọn điểm bắt đầu bằng argument x-stream-offset (không đặt thì đọc từ offset ghi sau khi attach). Docs khuyến nghị dùng stream protocol client để có đủ tính năng và throughput tốt nhất.
Ba tình huống, ba lựa chọn
Phần tiêu đề “Ba tình huống, ba lựa chọn”Nếu bài toán thật sự là log phân vùng, throughput rất lớn và hệ sinh thái stream processing, hãy cân nhắc Kafka: xem Kafka hay RabbitMQ và Kafka distributed log.
Chạy bảng chọn mô phỏng
Phần tiêu đề “Chạy bảng chọn mô phỏng”npx --prefix examples ts-node examples/src/rabbitmq-queue-types/selection-model.tsScript in ba gợi ý: email job → quorum, audit feed → stream, temporary reply → classic. Đây chỉ là decision aid, không kết nối RabbitMQ và không kiểm chứng replication.
Muốn kiểm chứng thật cần cluster nhiều node. Quorum: publish persistent có confirm, tắt một node, quan sát publish/consume; rồi mất đa số node để thấy availability giảm. Stream: hai consumer với offset riêng đọc lại cùng record, rồi quan sát khi retention xóa dữ liệu cũ. Một broker local không chứng minh failover.
Migration từ 3.x sang 4.x
Phần tiêu đề “Migration từ 3.x sang 4.x”Classic mirrored queue đã bị gỡ ở 4.0. Queue declare cùng tên khác x-queue-type bị từ chối vì khác thuộc tính, nên không đổi type tại chỗ.
- Liệt kê queue đang dùng mirroring policy (
ha-mode) và coi chúng là chưa replicated sau 4.0. - Tạo quorum queue mới (tên mới), cùng binding.
- Chuyển producer sang exchange/binding mới hoặc dual publish; drain queue cũ bằng consumer hiện có.
- Bỏ phụ thuộc vào tính năng quorum không có: exclusive, transient, global QoS, server-named queue.
- Đặt
x-delivery-limit, DLX và at-least-once dead-lettering cho queue mới. - Consumer idempotent, vì lúc cutover cùng message có thể xuất hiện ở cả hai queue.
Danh sách trên là quy trình tổng quát suy ra từ hành vi đã xác minh của queue declare và tính năng quorum, chưa đối chiếu với trang migration chính thức; hãy đọc hướng dẫn migration của đúng phiên bản bạn dùng.
Khi nào dùng / không dùng
Phần tiêu đề “Khi nào dùng / không dùng”| Loại | Dùng khi | Không dùng khi |
|---|---|---|
| Classic | Queue tạm, reply, cần exclusive hoặc priority cũ | Job quan trọng, cần sống sót khi mất node |
| Quorum | Work queue durable, cần HA và poison handling | Queue tạm, churn cao, cần exclusive |
| Stream | Fan-out, audit, replay trong retention | Work queue cạnh tranh, cần DLX hoặc TTL per-message |
Checklist production
Phần tiêu đề “Checklist production”- Mọi work queue durable: quorum, số node lẻ (ít nhất 3).
- Publisher confirm và manual ack, xem ba ranh giới xác nhận.
- Đặt
x-delivery-limitvà DLX, đừng để poison message quay vòng. - Stream: đặt
x-max-agehoặcx-max-length-bytesngay từ đầu, và giám sát đĩa. - Queue tạm:
exclusive, không dùng quorum. - Declare topology bằng code có version; đổi type nghĩa là tạo queue mới.
- Chuẩn bị backup và runbook: replication không bảo vệ khỏi xóa nhầm.
Sai lầm thường gặp
Phần tiêu đề “Sai lầm thường gặp”Tóm tắt
Phần tiêu đề “Tóm tắt”Tự kiểm tra: (1) Classic durable có chịu được mất hẳn node lưu queue không? (2) Vì sao audit feed hợp stream hơn quorum? (3) Vì sao không đổi x-queue-type của queue đang chạy?