RabbitMQ toàn tập (Phần I): Một số khái niệm cần lưu ý

Title nghe nguy hiểm thế thôi chứ đây chỉ là tổng hợp những điều cần biết để có thể làm việc với RabbitMQ, còn toàn tập ở đây là đủ nhất . Mình sẽ chia thành 2 phần: phần I sẽ tổng hợp các khái niệm để hiểu và thao tác với RabbitMQ, phần II sẽ thực hành deploy RabbitMQ.

RabbitMQ là gì

With tens of thousands of users, RabbitMQ is one of the most popular open source message brokers.

RabbitMQ là một trong những message broker phổ biến nhất hiện nay. Giống như Kafka hay Redis thì RabbitMQ cũng hỗ trợ model pub/sub, trong đó publisher sẽ push các message và subscriber sẽ lắng nghe các message. Queue của RabbitMQ hoạt động theo cơ chế FIFO.

Một số điểm cần lưu ý ở RabbitMQ

  1. Hỗ trợ 2 kiểu "persistent và transient" data:

    persistent có nghĩa là khi RabbitMQ bị shutdown do lỗi hay một vấn đề gì dó, khi khởi động lại các dữ liệu cũ vẫn được giữ nguyên và tiếp tục hoạt động, còn với transient, dữ liệu sẽ bị xóa khi RabbitMQ mất kết nối.

    // Với durable = true, queue này sẽ được giữ khi RabbitMQ restart. channel.assertQueue(queue, { durable: true, }); // Với persistent = true, message này sẽ được giữ khi RabbitMQ restart. channel.sendToQueue(queue, Buffer.from(msg), { persistent: true, });
  2. Replication:

    Để tăng tính high availability, RabbitMQ cho phép tạo thêm các node, trong đó có 1 node chính là Master và các node còn lại là Slave. Lưu ý: client có thể kết nối đến bất kỳ node nào, nhưng các hoạt động publish và consume sẽ được chuyển đến node Master để thực hiện sau đó các message sẽ được replica đến các node Slave.

    Queue của RabbitMQ không thể chia nhỏ thành nhiều phần, do vậy để tăng performance của RabbitMQ chỉ có thể scale vertically tại node Master mà không thể sử dụng scale horizontally được.

  3. Exchanges:

    Publisher không push trực tiếp message vào queue mà thông qua một built-in component gọi là exchange. Các queue sẽ được link với exchange, message đẩy vào exchange sẽ được đẩy sang các queue tương ứng. Exchange có 4 type là: direct, topic, headers, fanout, chi tiết xem tại đây.

  4. Message acknowledgment:

    Khi consumer nhận được message, có thể đánh dấu là đã nhận được message và message này sẽ bị xóa hoàn toàn khỏi queue sau khi đã được acknowledgment, đây là một trong những điểm khác biệt so với Kafka. Có 2 mode của consumer acknowledgments: auto và manual.

    Với auto: khi consumer nhận được message, RabbitMQ sẽ công nhận và xóa message khỏi queue luôn kể cả khi consumer thực hiện logic code tiếp theo mà có xảy ra lỗi gì đi nữa.

    Với manual: client có thể đánh dấu đã nhận được message thủ công sau khi đã được hiện logic. Điều này có thể đảm bảo trong quá trình thực hiện logic gặp lỗi thì message sẽ không bị mất và vẫn được gửi lại cho consumer để thực hiện.

  5. Consumer Prefetch:

    RabbitMQ cho phép giới hạn số lượng messages chưa được công nhận(unacknowledged messages) ở consumer. Khi unacknowledged messages của consumer đạt ngưỡng, RabbitMQ sẽ đẩy message sang consumer khác nếu có, còn không thì vẫn giữ lại ở queue. Điều này sẽ giúp cho consumer không bị quá tải nhưng đôi khi sẽ làm queue bị đầy.

  6. Round-robin dispatching:

    Khi có nhiều consumer lắng nghe từ cùng 1 queue, RabbitMQ sẽ phân phối message lần lượt cho từng consumer. Ví dụ: một queue gồm 4 message là: 1, 2, 3, 4. Có 2 consumer A, B lắng nghe queue thì consumer A nhận được 2 message là: 1 và 3 còn lại consumer B nhận được 2 message là: 2 và 4.

  7. Consumer mode:

    Consumer trong RabbitMQ có 2 mode là: pull và push. Trong quá trình xử lý pull message, consumer có thể push message sang một queue khác. Ví dụ cụ thể tại đây. Điều này giúp RabbitMQ có thể sử dụng trong service integration.

Ref