Bỏ qua, đến nội dung

Câu hỏi thường gặp — Queue Adapter RabbitMQ

Cài đặt

Không kết nối được đến RabbitMQ?

Kiểm tra lần lượt:

  1. RabbitMQ đang chạy: rabbitmqctl status hoặc truy cập Management UI tại http://host:15672
  2. Firewall cho phép kết nối từ server Digiforce đến RabbitMQ (mặc định port 5672 cho AMQP)
  3. URL đúng format: amqp://user:password@host:port
  4. Tài khoản và mật khẩu đúng (mặc định: guest:guest, chỉ hoạt động trên localhost)

Đã bật plugin nhưng queue không hoạt động?

Kiểm tra biến môi trường QUEUE_ADAPTER. Plugin bắt buộc QUEUE_ADAPTER=rabbitmq mới kích hoạt adapter. Nếu thiếu biến này, plugin thoát sớm trong load() mà không báo lỗi.

RabbitMQ và Redis queue adapter — nên chọn cái nào?

Tiêu chíRabbitMQRedis Streams
SetupCần cài riêngDùng chung Redis sẵn có
RoutingExchange routing phức tạp (direct, topic, fanout)Queue-based đơn giản
ReliabilityRất cao (persistent messages, cluster mirroring)Tốt (Streams persistence phụ thuộc Redis config)
MonitoringManagement UI built-inCần Redis Insight hoặc tự build
Phù hợpHigh throughput, mission-criticalSmall-medium workload, đã có Redis

Sử dụng

RabbitMQ restart thì message có bị mất không?

Phụ thuộc vào cấu hình queue durability:

  • Durable queue: Message persistent sẽ được phục hồi sau restart
  • Transient queue: Message mất khi restart

Plugin sử dụng assertQueue(name) — mặc định RabbitMQ tạo durable queue. Tuy nhiên, message chưa được ACK sẽ được re-deliver sau restart.

Retry hoạt động như thế nào?

Khi job thất bại:

  1. Plugin ACK message gốc (xóa khỏi queue)
  2. Nếu retried < maxRetries, plugin re-publish message mới với retried + 1
  3. Message mới được gửi lại queue và consumer xử lý lại
  4. Nếu đã hết lượt retry, message không được re-publish — job bị bỏ qua

Lưu ý: Đây không phải cơ chế NACK + requeue truyền thống của RabbitMQ. Plugin tự quản lý retry bằng cách ACK + re-publish.

Timeout job hoạt động thế nào?

Mỗi job được cấp AbortSignal.timeout(timeout). Nếu event.process() chạy quá lâu, signal sẽ abort. Handler cần kiểm tra signal.aborted để dừng đúng lúc.

Có hỗ trợ Dead Letter Queue không?

Plugin hiện tại không tự động cấu hình Dead Letter Queue. Khi hết lượt retry, message bị bỏ qua (ACK + không re-publish). Nếu cần DLQ, bạn có thể cấu hình trực tiếp trên RabbitMQ server bằng policy dead-letter-exchange.

Lỗi thường gặp

Lỗi "ECONNREFUSED"

RabbitMQ không chạy hoặc không lắng nghe trên port cấu hình. Kiểm tra:

  • rabbitmqctl status
  • Firewall rules cho port 5672

Lỗi "ACCESS_REFUSED - Login was refused"

Sai tài khoản hoặc mật khẩu. Lưu ý tài khoản guest mặc định chỉ cho phép kết nối từ localhost. Để kết nối remote, tạo tài khoản mới:

bash
rabbitmqctl add_user myuser mypassword
rabbitmqctl set_permissions -p / myuser ".*" ".*" ".*"

Lỗi "Channel closed" liên tục

RabbitMQ có thể đóng channel khi:

  • Consumer xử lý quá lâu (heartbeat timeout)
  • Message quá lớn (exceeds max frame size)
  • Queue bị xóa trong khi consumer đang chạy

Plugin tự động tạo lại channel khi bị đóng, nhưng nếu lỗi xảy ra liên tục, cần kiểm tra root cause.

Message bị xử lý trùng lặp

Có thể xảy ra khi:

  • Connection bị đóng giữa lúc xử lý job → RabbitMQ re-deliver message chưa ACK
  • Retry re-publish cùng lúc consumer đang xử lý

Thiết kế handler cần idempotent (xử lý nhiều lần cho kết quả giống nhau) để tránh side effect.