Bài 6: Giao Tiếp Nâng Cao Trong Microserivce với RabbitMQ

Bài 6: Giao Tiếp Nâng Cao: Sử Dụng Message Queue Với RabbitMQ

rabbitmq-exchange

Ở bài trước, bạn đã học cách microservices giao tiếp với nhau qua API – một cách rất phổ biến. Hôm nay, chúng ta sẽ tìm hiểu một cách giao tiếp khác: dùng message queue với RabbitMQ. Mình nhớ lúc mới học về message queue, mình hơi bối rối vì không hiểu nó khác API ở điểm nào. Nhưng sau khi làm thử, mình thấy nó rất hữu ích, đặc biệt khi bạn muốn xử lý các tác vụ không cần phản hồi ngay lập tức. Mình sẽ hướng dẫn bạn từng bước để tạo hai microservices giao tiếp qua RabbitMQ, và giải thích mọi thứ thật rõ ràng. Sẵn sàng chưa nào?

Message Queue Là Gì? Hãy Nghĩ Về Việc Gửi Tin Nhắn Qua Zalo

Trước tiên, mình muốn bạn hiểu message queue là gì một cách đơn giản. Hãy tưởng tượng bạn gửi một tin nhắn qua Zalo cho một người bạn: “Tối nay đi ăn không?” Bạn không cần bạn mình trả lời ngay lập tức – bạn gửi tin nhắn, và bạn ấy sẽ đọc, xử lý, rồi trả lời sau. Trong microservices, message queue cũng hoạt động tương tự: một microservice gửi một “tin nhắn” (message) vào hàng đợi (queue), và microservice khác sẽ lấy tin nhắn đó để xử lý khi nó sẵn sàng.

Nói kỹ thuật hơn, message queue là một hệ thống giúp microservices giao tiếp bất đồng bộ (asynchronous). Thay vì gọi API và chờ phản hồi ngay, microservice gửi message vào queue, và microservice khác sẽ xử lý message đó sau. Điều này rất hữu ích khi bạn có các tác vụ tốn thời gian (VD: gửi email, xử lý thanh toán).

Mình sẽ dùng RabbitMQ, một công cụ message queue phổ biến, để bạn làm quen.

Bước 1: Cài Đặt RabbitMQ Trên Máy Của Bạn

Hãy bắt đầu bằng cách cài RabbitMQ trên Ubuntu. Nếu bạn dùng Windows hoặc Mac, mình gợi ý chạy RabbitMQ trong Docker (mình sẽ hướng dẫn ở bài sau về Docker), nhưng hiện tại, chúng ta sẽ cài trực tiếp trên Ubuntu.

  1. Mở terminal và chạy các lệnh sau để cài RabbitMQ:
    sudo apt update
    sudo apt install -y rabbitmq-server
  2. Khởi động RabbitMQ:
    sudo systemctl enable rabbitmq-server
    sudo systemctl start rabbitmq-server
  3. Kiểm tra xem RabbitMQ đã chạy chưa:
    sudo systemctl status rabbitmq-server

    Nếu bạn thấy dòng Active: active (running), RabbitMQ đã chạy thành công.

  4. Kích hoạt giao diện quản lý của RabbitMQ (để bạn xem queue qua trình duyệt):
    sudo rabbitmq-plugins enable rabbitmq_management

    Sau đó, mở trình duyệt và truy cập: http://localhost:15672. Bạn sẽ thấy giao diện RabbitMQ với thông tin đăng nhập mặc định:

    • Username: guest
    • Password: guest
      Nếu thấy giao diện, bạn đã cài thành công!

Bước 2: Tạo Microservice Gửi Message – Order Service

Bây giờ, chúng ta sẽ tạo lại Order Service (tương tự bài trước), nhưng lần này, nó sẽ gửi một message vào RabbitMQ thay vì gọi API. Message này sẽ chứa thông tin đơn hàng, để một microservice khác xử lý (VD: gửi thông báo).

  1. Tạo thư mục cho Order Service:
    mkdir order-service
    cd order-service
    npm init -y
    npm install express amqplib

    Lưu ý: Mình cài thêm amqplib – thư viện để kết nối với RabbitMQ.

  2. Tạo file app.js trong thư mục order-service và dán đoạn code sau:

    const express = require('express');
    const amqp = require('amqplib');
    const app = express();
    
    app.use(express.json());
    
    app.post('/order', async (req, res) => {
       const order = { id: 1, item: 'Phở bò', price: 50000 };
    
       try {
           const connection = await amqp.connect('amqp://localhost');
           const channel = await connection.createChannel();
           const queue = 'order_queue';
    
           await channel.assertQueue(queue, { durable: false });
           channel.sendToQueue(queue, Buffer.from(JSON.stringify(order)));
           console.log('Đã gửi đơn hàng:', order);
    
           await channel.close();
           await connection.close();
    
           res.send('Đơn hàng đã được gửi để xử lý');
       } catch (error) {
           res.status(500).send('Có lỗi khi gửi đơn hàng');
       }
    });
    
    app.listen(3002, () => {
       console.log('Order Service chạy trên cổng 3002');
    });

    Giải thích code:

    • amqp.connect('amqp://localhost'): Kết nối đến RabbitMQ.
    • channel.assertQueue('order_queue'): Tạo một queue tên order_queue.
    • channel.sendToQueue(...): Gửi đơn hàng (dạng JSON) vào queue.
    • app.post('/order', ...): Tạo API endpoint để gửi đơn hàng.

Bước 3: Tạo Microservice Nhận Message – Notification Service

Tiếp theo, chúng ta tạo một microservice để nhận message từ queue và xử lý (VD: in ra thông báo).

  1. Mở terminal mới, tạo thư mục cho Notification Service:
    mkdir notification-service
    cd notification-service
    npm init -y
    npm install amqplib
  2. Tạo file app.js trong thư mục notification-service và dán đoạn code sau:

    const amqp = require('amqplib');
    
    async function start() {
       try {
           const connection = await amqp.connect('amqp://localhost');
           const channel = await connection.createChannel();
           const queue = 'order_queue';
    
           await channel.assertQueue(queue, { durable: false });
           console.log('Notification Service đang chờ đơn hàng...');
    
           channel.consume(queue, (msg) => {
               const order = JSON.parse(msg.content.toString());
               console.log('Nhận được đơn hàng:', order);
               console.log('Gửi thông báo: Đơn hàng của bạn đã được xác nhận!');
               channel.ack(msg);
           });
       } catch (error) {
           console.error('Có lỗi:', error);
       }
    }
    
    start();

    Giải thích code:

    • channel.consume(queue, ...): Lắng nghe queue order_queue và nhận message.
    • JSON.parse(msg.content.toString()): Chuyển message thành object để xử lý.
    • In ra thông báo giả lập (sau này bạn có thể gửi email thật).

Bước 4: Kiểm Tra Giao Tiếp Qua RabbitMQ

Đã đến lúc kiểm tra xem hai microservices có giao tiếp được qua RabbitMQ không:

  1. Đảm bảo RabbitMQ đang chạy (xem Bước 1).
  2. Chạy Notification Service trước (vì nó cần lắng nghe queue):
    cd notification-service
    node app.js

    Bạn sẽ thấy thông báo: Notification Service đang chờ đơn hàng....

  3. Mở terminal mới, chạy Order Service:
    cd order-service
    node app.js

    Bạn sẽ thấy thông báo: Order Service chạy trên cổng 3002.

  4. Dùng Postman để gửi đơn hàng:
    • Tạo request POST với URL: http://localhost:3002/order.
    • Chọn tab “Body”, chọn “raw”, nhập JSON: {} (hiện tại không cần dữ liệu, vì đơn hàng đã được hardcode).
    • Nhấn “Send”, bạn sẽ thấy kết quả: Đơn hàng đã được gửi để xử lý.
  5. Quay lại terminal của Notification Service, bạn sẽ thấy:
    Nhận được đơn hàng: { id: 1, item: 'Phở bò', price: 50000 }
    Gửi thông báo: Đơn hàng của bạn đã được xác nhận!

Nếu bạn thấy kết quả như trên, xin chúc mừng! Bạn đã làm được giao tiếp bất đồng bộ qua RabbitMQ.

Nhật Ký Thử Nghiệm: Khó Khăn Và Cách Vượt Qua

Lần đầu làm với RabbitMQ, mình gặp vài vấn đề, và mình nghĩ bạn cũng có thể gặp. Dưới đây là một số khó khăn và cách xử lý:

  • Lỗi “Connection refused”: Kiểm tra xem RabbitMQ có chạy không (sudo systemctl status rabbitmq-server). Nếu không, khởi động lại: sudo systemctl start rabbitmq-server.
  • Không thấy message trong Notification Service: Đảm bảo queue tên order_queue được dùng đúng ở cả hai microservices. Nếu vẫn không được, kiểm tra xem Order Service đã gửi message thành công chưa (nhìn log).
  • RabbitMQ không truy cập được giao diện: Đảm bảo bạn đã bật plugin quản lý (sudo rabbitmq-plugins enable rabbitmq_management) và truy cập đúng URL (http://localhost:15672).

Mình từng quên bật RabbitMQ, nên Order Service không gửi được message. Sau khi kiểm tra lại, mình mới nhận ra vấn đề.

Kết Thúc: Bạn Đã Làm Được Giao Tiếp Bất Đồng Bộ

Hôm nay, bạn đã học cách microservices giao tiếp bất đồng bộ qua message queue với RabbitMQ – một kỹ năng rất hữu ích. Bạn đã tạo hai microservices và kết nối chúng thành công. Ở bài tiếp theo, chúng ta sẽ học cách container hóa microservices với Docker, để chạy chúng dễ dàng hơn. Hẹn gặp bạn ở bài sau nhé!

Điều hướng chuỗi bài viết<< Bài 5: Giao Tiếp Giữa Microservices
>> Bài 7: Container Hóa Microservices Với Docker
Article Thumbnail
Datadog Webinar: Modernize AWS Logs at Scale
Chia sẻ bài viết:
Theo dõi
Thông báo của
0 Góp ý
Được bỏ phiếu nhiều nhất
Mới nhất Cũ nhất
Phản hồi nội tuyến
Xem tất cả bình luận