Danh sách bài viết trong series Học microservice cơ bản
- Bài 1: Microservices Là Gì?
- Bài 2: Chuẩn Bị Môi Trường Để Học Microservices
- Bài 3: Viết Microservice Đầu Tiên
- Bài 4: Microservices Và Monolith
- Bài 5: Giao Tiếp Giữa Microservices
- Bài 6: Giao Tiếp Nâng Cao Trong Microserivce với RabbitMQ
- Bài 7: Container Hóa Microservices Với Docker
- Bài 8: Quản Lý Nhiều Microservices Với Docker Compose
- Bài 9: Học microservices cơ bản với minikube
Bài 6: Giao Tiếp Nâng Cao: Sử Dụng Message Queue Với RabbitMQ

Ở 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.
- Mở terminal và chạy các lệnh sau để cài RabbitMQ:
sudo apt update sudo apt install -y rabbitmq-server
- Khởi động RabbitMQ:
sudo systemctl enable rabbitmq-server sudo systemctl start rabbitmq-server
- 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. - 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!
- Username:
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).
- 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. -
Tạo file
app.js
trong thư mụcorder-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ênorder_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).
- Mở terminal mới, tạo thư mục cho
Notification Service
:mkdir notification-service cd notification-service npm init -y npm install amqplib
-
Tạo file
app.js
trong thư mụcnotification-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 queueorder_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:
- Đảm bảo RabbitMQ đang chạy (xem Bước 1).
- 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...
. - 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
. - 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ý
.
- Tạo request
- 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ênorder_queue
được dùng đúng ở cả hai microservices. Nếu vẫn không được, kiểm tra xemOrder 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é!