Reliability trong microservices là khả năng của hệ thống đảm bảo tính ổn định và khả năng đáp ứng ngay cả khi một hoặc nhiều thành phần gặp lỗi. Vì microservices là hệ thống phân tán, khả năng xảy ra sự cố là rất cao, nên việc thiết kế để đạt được reliability là yếu tố quan trọng để đảm bảo trải nghiệm người dùng và hiệu suất hoạt động.

Dưới đây là các khía cạnh và phương pháp để đạt được reliability trong microservices:
1. Redundancy (Dự phòng)
- Multiple Instances: Triển khai nhiều instance của từng microservice để dự phòng khi một instance gặp lỗi.
- Database Replication: Sử dụng replication database (master-slave hoặc master-master) để đảm bảo dữ liệu vẫn có thể truy cập được khi một node bị lỗi.
Ví dụ:
Nếu một service xử lý thanh toán gặp sự cố, một instance khác trong cluster sẽ thay thế ngay lập tức.
2. Retry và Backoff
- Retry: Khi một service không phản hồi, client hoặc hệ thống có thể thử lại một số lần trước khi thông báo lỗi.
- Backoff: Sử dụng cơ chế tăng dần thời gian giữa các lần retry để giảm tải cho hệ thống (Exponential Backoff).
Công cụ hỗ trợ: Spring Retry, Resilience4j.
3. Circuit Breaker
- Circuit breaker giúp ngăn các service tiếp tục gửi request đến một service đang lỗi, tránh tạo áp lực và “hiệu ứng domino”.
- Nếu service bị lỗi, circuit breaker chuyển sang trạng thái “open” và các request sẽ bị từ chối hoặc fallback.
Công cụ: Resilience4j, Netflix Hystrix.
4. Health Checks
- Microservices nên cung cấp các API hoặc endpoint để báo cáo tình trạng hiện tại (ví dụ:
/health
).
- Health check giúp Load Balancer hoặc Orchestrator (như Kubernetes) biết dịch vụ nào còn hoạt động và có thể phục vụ traffic.
Công cụ hỗ trợ: Spring Boot Actuator, Kubernetes Liveness/Readiness Probes.
5. Idempotency
- Đảm bảo các API idempotent, nghĩa là khi một request được gửi nhiều lần, kết quả vẫn giống nhau.
- Điều này đặc biệt quan trọng với các thao tác như thanh toán hoặc cập nhật dữ liệu.
6. Timeouts và Fallbacks
- Timeouts: Cấu hình thời gian chờ (timeout) cho các request để tránh treo nếu một service phản hồi chậm.
- Fallbacks: Nếu một service không hoạt động, trả về giá trị mặc định hoặc route request sang service thay thế.
Ví dụ:
Nếu service khuyến mãi không phản hồi, bạn có thể hiển thị thông báo “Không có khuyến mãi nào hiện tại.”
7. Distributed Tracing
- Khi nhiều microservice giao tiếp với nhau, việc theo dõi các lỗi trở nên khó khăn. Sử dụng distributed tracing để theo dõi toàn bộ request từ đầu đến cuối.
- Công cụ phổ biến: Jaeger, Zipkin.
8. Data Consistency
- Synchronous vs Asynchronous Communication:
- Khi consistency không quan trọng ngay lập tức, sử dụng giao tiếp bất đồng bộ (Kafka, RabbitMQ).
- Khi consistency cần được đảm bảo ngay lập tức, sử dụng giao tiếp đồng bộ (REST/gRPC).
- Eventual Consistency: Chấp nhận rằng dữ liệu có thể không đồng bộ ngay lập tức nhưng sẽ nhất quán theo thời gian.
9. Rate Limiting và Throttling
- Rate Limiting: Hạn chế số lượng request từ một client để tránh làm quá tải service.
- Throttling: Làm chậm hoặc giảm request nếu hệ thống đang chịu tải cao.
Công cụ: Kong API Gateway, NGINX, Spring Cloud Gateway.
10. Caching
- Cache dữ liệu phổ biến hoặc ít thay đổi để giảm tải cho hệ thống backend.
- Sử dụng caching ở nhiều lớp:
- Client-Side Cache (trên ứng dụng người dùng).
- Distributed Cache: Redis, Memcached.
Ví dụ:
Cache thông tin user profile để giảm số lần truy vấn database.