Đầu tiên phải phân biệt hai tình huống, vì cách xử lý khác hẳn nhau.
Chậm tạm thời (đợt cao điểm) — queue chính là bộ đệm, đó là công dụng của nó. Chỉ cần đủ dung lượng lưu trữ và giám sát để biết khi nào backlog tiêu hết. Không cần làm gì thêm.
Chậm kéo dài (công suất consumer < tốc độ producer) — queue không cứu được, chỉ làm độ trễ tăng vô hạn. Backlog càng lớn thì càng khó tiêu vì message mới xếp sau backlog, và khi hết dung lượng thì broker chặn producer hoặc bắt đầu loại message.
Các hướng xử lý:
- Tăng công suất tiêu thụ: thêm consumer (Kafka: tối đa bằng số partition; RabbitMQ: thêm consumer trên cùng queue là được), gom lô ghi DB, bỏ các lệnh gọi đồng bộ không cần thiết.
- Giới hạn nhận vào:
prefetch/max.poll.recordsgiữ số message in-flight ở mức consumer thật sự xử lý nổi, để broker không đẩy quá tay và message không bị timeout khi nằm chờ trong bộ nhớ consumer. - Tách hàng đợi theo mức ưu tiên: đơn hàng và email khuyến mãi không nên chung queue. Khi backlog lớn, luồng quan trọng vẫn phải chạy được.
- Loại bỏ có chủ đích (load shedding): message quá hạn ý nghĩa (thông báo real-time cũ 30 phút) thì bỏ, đừng xử lý cho đủ. Đặt TTL cho loại message này.
- Giảm tải đầu vào: rate limit hoặc chặn tạm ở tầng API khi backlog vượt ngưỡng, có kiểm soát vẫn hơn để broker tự đầy.
Có một hàng đợi backlog dài mà không có kế hoạch tiêu thụ thì chỉ là dời sự cố sang tương lai.