Tuyệt chiêu giám sát RabbitMQ: Đừng để Cluster ‘sập’ mới lo đi tìm lỗi

Monitoring tutorial - IT technology blog
Monitoring tutorial - IT technology blog

Chuyện lúc 2 giờ sáng: Khi hệ thống ‘ngỏm’ vì một Queue nghẽn

Tiếng chuông PagerDuty réo liên hồi lúc nửa đêm là nỗi ám ảnh của mọi kỹ sư vận hành. Một lần nọ, hệ thống thanh toán của bên mình bỗng dưng đứng hình. Đơn hàng không đổ về database, log chỉ toàn lỗi Gateway Timeout. Sau 30 phút vã mồ hôi hột SSH vào từng node để gõ rabbitmqctl list_queues, mình mới tá hỏa: một queue đang tồn đọng hơn 1.5 triệu tin nhắn. Lượng message này chiếm sạch 8GB RAM, khiến toàn bộ Cluster rơi vào trạng thái treo cứng.

Trước khi có hệ thống monitoring chuẩn chỉ, mình thường xuyên phải làm “thợ đụng” như vậy. Cứ có lỗi là lại thủ công kiểm tra từng dòng lệnh. Giờ đây, chỉ cần nhìn vào dashboard Grafana, mình có thể biết ngay worker nào đang chậm hoặc queue nào đang phình to. Nếu bạn muốn kê cao gối ngủ ngon, hãy cùng mình triển khai bộ đôi Prometheus và Grafana để kiểm soát RabbitMQ một cách chủ động.

Triển khai nhanh trong 5 phút

Từ phiên bản 3.8, RabbitMQ đã tích hợp sẵn endpoint cho Prometheus. Bạn không cần cài thêm các exporter bên thứ ba như trước, giúp giảm bớt một layer trung gian dễ gây lỗi.

Bước 1: Kích hoạt plugin nội tại

Bật plugin giám sát bằng lệnh sau ngay trên server RabbitMQ:

rabbitmq-plugins enable rabbitmq_prometheus

Sau khi kích hoạt, RabbitMQ sẽ mở cổng 15692. Bạn hãy kiểm tra bằng lệnh curl để xác nhận dữ liệu đang được đổ ra:

curl http://localhost:15692/metrics

Nếu màn hình hiện ra các dòng như rabbitmq_queue_messages_ready kèm theo con số cụ thể là bạn đã thành công bước đầu.

Bước 2: Khai báo với Prometheus

Thêm đoạn cấu hình sau vào file prometheus.yml để hệ thống bắt đầu thu thập dữ liệu định kỳ (scrape):

scrape_configs:
  - job_name: 'rabbitmq-production'
    scrape_interval: 15s # Quá dày sẽ tốn tài nguyên, quá thưa sẽ mất dấu sự cố
    static_configs:
      - targets: ['10.0.1.50:15692'] # Thay bằng IP server của bạn

Bước 3: Thiết lập Dashboard Grafana

Thay vì tự tay vẽ từng biểu đồ, bạn hãy sử dụng template tiêu chuẩn từ đội ngũ RabbitMQ:

  1. Truy cập Grafana chọn Dashboards > Import.
  2. Nhập ID 10991 (đây là bản chuẩn nhất hiện nay).
  3. Chọn Data Source là Prometheus bạn vừa cấu hình và nhấn Import.

4 chỉ số “sống còn” cần đặc biệt lưu tâm

Dashboard có rất nhiều thông số, nhưng khi hệ thống gặp tải cao, bạn chỉ cần tập trung vào các chỉ số trọng yếu sau:

1. Trạng thái Message: Ready vs Unacknowledged

  • Ready: Message đang nằm chờ. Nếu con số này vượt ngưỡng 100.000 (tùy cấu hình RAM), đó là dấu hiệu Consumer đang xử lý quá chậm.
  • Unacknowledged: Message đã gửi đi nhưng chưa được xác nhận xong. Nếu chỉ số này cao, khả năng cao là code Worker đang bị treo hoặc dính lỗi logic dẫn đến không thể hoàn tất tác vụ.

2. Lưu lượng Message (Publish vs Deliver Rate)

Đây là biểu đồ thể hiện sự cân bằng của hệ thống. Nếu tốc độ Publish liên tục cao hơn Deliver trong 10-15 phút, queue của bạn chắc chắn sẽ bị tràn. Một hệ thống khỏe mạnh là khi hai đường tiệm cận sát nhau.

3. File Descriptors (FD)

Mỗi kết nối từ ứng dụng đến RabbitMQ sẽ mở một File Descriptor. Mặc định Linux thường giới hạn ở mức 1024, con số này quá thấp cho một hệ thống Messaging. Hãy đảm bảo Dashboard của bạn hiển thị mức sử dụng FD dưới 80% để tránh việc RabbitMQ từ chối kết nối mới đột ngột.

4. Erlang Memory Alarm

Khi RAM chạm ngưỡng 40% (mặc định), RabbitMQ sẽ kích hoạt chế độ “đóng băng” (Memory Alarm) và ngừng nhận message để bảo vệ hệ thống. Đừng để biểu đồ chạm mức này nếu bạn không muốn ứng dụng bị lỗi 500 hàng loạt.

Cấu hình cảnh báo tự động qua Telegram

Dashboard chỉ phát huy tác dụng khi bạn ngồi nhìn màn hình. Để thực sự rảnh tay, bạn cần Alertmanager. Dưới đây là mẫu rule cảnh báo khi một queue bị tồn đọng quá 50.000 tin nhắn:

- alert: RabbitMQQueueBacklog
  expr: rabbitmq_queue_messages_ready > 50000
  for: 2m
  labels:
    severity: warning
  annotations:
    summary: "Queue {{ $labels.queue }} đang bị nghẽn!"
    description: "Hiện có {{ $value }} tin nhắn chưa xử lý trên vhost {{ $labels.vhost }}."

Bài học thực chiến: Đừng để Disk Space ‘phản chủ’

RabbitMQ có một cơ chế cực kỳ gắt gao: Disk Alarm. Chỉ cần dung lượng ổ cứng còn trống dưới 50MB, nó sẽ chặn toàn bộ luồng dữ liệu vào. Mình từng gặp ca code không lỗi, RAM còn dư nhưng hệ thống không thể gửi tin nhắn chỉ vì file log chiếm hết ổ cứng.

Lời khuyên: Hãy luôn monitor cả dung lượng Disk của server RabbitMQ. Ngoài ra, với các hệ thống có hàng nghìn queue động, bạn nên giới hạn việc scrape metrics để tránh làm quá tải Prometheus (hiện tượng High Cardinality). Chỉ nên tập trung vào các queue quan trọng nhất của nghiệp vụ.

Việc thiết lập giám sát không chỉ giúp bạn xử lý sự cố nhanh hơn, mà còn giúp bạn nhìn ra xu hướng tăng trưởng traffic. Từ đó, bạn có thể chủ động scale thêm Worker trước khi hệ thống kịp “hắt hơi”. Chúc bạn có những đêm ngon giấc với hệ thống RabbitMQ ổn định!

Share: