Docker cho Microservices Architecture
Bạn có biết?
Hãy tưởng tượng bạn đang xây dựng một thành phố thông minh. Thay vì một tòa nhà khổng lồ chứa tất cả mọi thứ (công an, bưu điện, bệnh viện, trường học…), bạn sẽ xây dựng mỗi cơ quan tại một tòa nhà riêng biệt. Công an ở đồn công an, bưu điện ở bưu điện, bệnh viện ở bệnh viện. Docker giống như hệ thống đường xá, điện nước giúp các tòa nhà này kết nối và làm việc cùng nhau một cách trơn tru.
Microservices là gì?
Microservices là phương pháp chia nhỏ ứng dụng thành các services độc lập, mỗi service chịu trách nhiệm một chức năng cụ thể. Thay vì một ứng dụng monolithic (nguyên khối) với tất cả code trong một project, bạn tách ra thành nhiều service nhỏ có thể phát triển, deploy và scale độc lập.
So sánh Monolithic vs Microservices
| Tiêu chí | Monolithic | Microservices |
|---|---|---|
| Cấu trúc | Tất cả trong một project | Nhiều service độc lập |
| Deploy | Toàn bộ ứng dụng | Từng service riêng lẻ |
| Scale | Scale toàn bộ | Scale từng service |
| Phát triển | Phụ thuộc lẫn nhau | Team làm việc độc lập |
| Rủi ro | Lỗi một phần chết cả hệ thống | Lỗi một service không ảnh hưởng khác |
Kiến trúc Microservices với Docker
Sơ đồ kiến trúc
Trong kiến trúc microservices với Docker, thường có các thành phần sau:
- API Gateway – Điểm vào duy nhất, routing request đến các service tương ứng
- Auth Service – Xử lý authentication và authorization
- User Service – Quản lý thông tin user
- Order Service – Xử lý đơn hàng
- Notification Service – Gửi email, push notification
- Database – Mỗi service có database riêng hoặc schema riêng
- Message Queue – RabbitMQ để giao tiếp bất đồng bộ giữa các services
Mỗi Service một Container
Với Docker, mỗi microservice được đóng gói trong một container riêng biệt:
- Service riêng, Docker image riêng
- Database riêng (hoặc schema riêng trong shared database)
- Network riêng để giao tiếp nội bộ
- Có thể scale từng service theo nhu cầu
Docker Compose cho Microservices
Cấu trúc project
myapp/
├── api-gateway/
│ └── Dockerfile
├── auth-service/
│ └── Dockerfile
├── user-service/
│ └── Dockerfile
├── order-service/
│ └── Dockerfile
└── docker-compose.yml
docker-compose.yml
version: "3.8"
services:
api-gateway:
build: ./api-gateway
ports:
- "3000:3000"
networks:
- frontend
- backend
auth-service:
build: ./auth-service
environment:
- JWT_SECRET=secret
- DB_HOST=postgres
depends_on:
- postgres
- redis
networks:
- backend
user-service:
build: ./user-service
environment:
- DB_HOST=postgres
depends_on:
- postgres
networks:
- backend
order-service:
build: ./order-service
environment:
- DB_HOST=postgres
- RABBITMQ_HOST=rabbitmq
depends_on:
- postgres
- rabbitmq
networks:
- backend
postgres:
image: postgres:15
environment:
POSTGRES_PASSWORD: secret
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- backend
redis:
image: redis:7
networks:
- backend
rabbitmq:
image: rabbitmq:3-management
ports:
- "15672:15672"
networks:
- backend
volumes:
postgres-data:
networks:
frontend:
driver: bridge
backend:
driver: bridge
Giao tiếp giữa Services
1. REST API
Các service giao tiếp với nhau qua HTTP REST API. Ví dụ: User Service expose API, các service khác gọi qua HTTP để lấy thông tin user.
2. Message Queue (RabbitMQ)
Giao tiếp bất đồng bộ qua message queue, phù hợp cho event-driven architecture. Các event phổ biến:
- user.created – User mới đăng ký
- order.created – Order mới được tạo
- order.completed – Order hoàn thành
3. Service Discovery
Trong Docker Compose, bạn có thể dùng service name để gọi trực tiếp. Ví dụ: auth-service gọi user-service qua URL http://user-service:3001 thay vì IP address.
Use Cases thực tế
1. User đăng ký
- Client gọi API:
POST /api-gateway/auth/register - API Gateway chuyển request đến Auth Service
- Auth Service xử lý, lưu user vào database
- Auth Service gửi event
user.createdlên RabbitMQ - Notification Service nhận event, gửi email chào mừng
2. Tạo order
- Client gọi API:
POST /api-gateway/orders - API Gateway chuyển đến Order Service
- Order Service lưu order vào database
- Order Service gửi event
order.createdlên RabbitMQ - Các service quan tâm (notification, inventory) nhận event xử lý tiếp
Best Practices
1. Mỗi Service một repo
Tách biệt code của mỗi service thành repository riêng. Điều này giúp dễ quản lý, independent deploy và team làm việc độc lập.
2. Dùng API Gateway
API Gateway là điểm vào duy nhất cho tất cả các services. Nó xử lý routing, authentication, rate limiting và logging tập trung.
3. Dùng Message Queue
Sử dụng message queue (RabbitMQ, Kafka) để decouple các services. Điều này cho phép xử lý bất đồng bộ, giảm phụ thuộc trực tiếp giữa các services.
4. Health checks
Mỗi service cần implement health check endpoint (thường là /health) để Docker có thể kiểm tra trạng thái và tự động restart khi cần.
5. Logging tập trung
Sử dụng ELK stack (Elasticsearch, Logstash, Kibana) hoặc Loki để thu thập và phân tích logs từ tất cả các services ở một nơi.
Bước tiếp theo
Sau khi đã hiểu cách xây dựng microservices với Docker Compose, bước tiếp theo là tìm hiểu về Docker Swarm – giải pháp orchestration tích hợp sẵn trong Docker để quản lý cluster và scale services.