Discovery pattern
Discovery pattern
Discovery Pattern là một mẫu thiết kế trong kiến trúc microservices giúp các service có thể tìm thấy và giao tiếp với nhau một cách động. Thay vì các service gọi nhau bằng địa chỉ IP cố định, Discovery Pattern cho phép các service đăng ký và tra cứu thông tin của nhau thông qua một Service Registry (cơ sở dữ liệu lưu trữ danh sách các service), giúp ứng dụng mở rộng linh hoạt mà không cần cập nhật thủ công địa chỉ của từng service.
Các thành phần trong Service Discovery
Service Registry (Bộ đăng ký dịch vụ)
Là một cơ sở dữ liệu trung tâm chứa danh sách các service và địa chỉ của chúng.
Ví dụ: Eureka (Netflix), Consul (HashiCorp), Zookeeper (Apache)
Service Provider (Dịch vụ cung cấp)
Khi một service khởi động, nó tự động đăng ký vào Service Registry.
Khi bị shutdown hoặc gặp lỗi, nó sẽ bị xóa khỏi registry.
Service Consumer (Dịch vụ tiêu dùng)
- Khi muốn gọi một service khác, nó tra cứu danh sách trong Service Registry để lấy địa chỉ dịch vụ.
Cơ chế hoạt động
Discovery Pattern hoạt động dựa trên các thành phần chính sau:
Service Registry (Đăng ký dịch vụ)
Là trung tâm lưu trữ danh sách các service, bao gồm tên service, địa chỉ IP, cổng (port) và trạng thái.
Các service khi khởi động sẽ tự động đăng ký với registry này.
Ví dụ: Eureka Server (Spring Cloud), Consul, Zookeeper, etcd.
Service Registration (Dịch vụ đăng ký)
Mỗi microservice khi chạy lên sẽ gửi thông tin của nó đến Service Registry.
Khi tắt service, nó có thể tự xóa khỏi registry hoặc bị registry loại bỏ nếu không phản hồi trong một khoảng thời gian.
Service Discovery (Dịch vụ tìm kiếm)
Khi một service muốn gọi một service khác, nó sẽ tra cứu trong Service Registry để tìm địa chỉ của service mục tiêu.
Cách tra cứu có thể là Client-side Discovery hoặc Server-side Discovery.
Health Check (Kiểm tra sức khỏe)
Service Registry thường sẽ kiểm tra định kỳ (heartbeat) xem các service còn hoạt động không.
Nếu một service không phản hồi, nó sẽ bị xóa khỏi registry để tránh gọi vào các service bị lỗi.
Trường hợp sử dụng
Khi nào cần
Khi hệ thống có nhiều microservices động (có thể thay đổi số lượng instance theo thời gian).
Khi các service cần giao tiếp với nhau mà không có địa chỉ IP cố định.
Khi cần cân bằng tải (load balancing) động giữa các instance của một service.
Khi muốn có cơ chế tự động phát hiện lỗi và loại bỏ service bị lỗi.
Khi nào không cần
Nếu kiến trúc chỉ có 1-2 service cố định, có thể sử dụng địa chỉ IP tĩnh.
Nếu chỉ có một vài API Gateway làm trung gian, có thể sử dụng API Gateway thay vì Discovery Pattern.
Nếu dùng Kubernetes, có thể sử dụng Kubernetes Service thay vì triển khai riêng một Service Discovery.
Cách triển khai
Có 2 cách chính để triển khai Service Discovery trong microservices:
Client-side Service Discovery
Client trực tiếp truy vấn Service Registry để lấy danh sách các service khả dụng, sau đó chọn service để gửi request. Sau đó, client tự thực hiện Load Balancing và gửi request đến một instance phù hợp.
Công nghệ thường dùng:
Service Discovery (Eureka, Consul, Zookeeper)
Load Balancer trên client (Ribbon, Feign - Spring Cloud)
✅ Ưu điểm:
Giảm tải cho Load Balancer trung gian.
Tốc độ truy vấn nhanh hơn vì không có bottleneck.
Linh hoạt khi chọn thuật toán load balancing (Round-robin, Least Connections, v.v.).
❌ Nhược điểm:
Client phức tạp hơn vì phải quản lý logic tìm kiếm service.
Cần có một cơ chế cập nhật danh sách service liên tục.
Ví dụ: Spring Cloud LoadBalancer với Eureka
Cấu hình Eureka Server (application.yml
)
server:
port: 8761
eureka:
client:
registerWithEureka: false
fetchRegistry: false
Cấu hình service đăng ký vào Eureka:
spring:
application:
name: user-service
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
Tìm service bằng Eureka Client:
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Autowired
private RestTemplate restTemplate;
public String getUserData() {
return restTemplate.getForObject("http://user-service/users", String.class);
}
Khi sử dụng RestTemplate
hoặc WebClient
hoặc FeignClient
nó sẽ tự động lấy danh sách service từ Eureka để gọi API.
Server-side Service Discovery
Client không cần biết trực tiếp địa chỉ của service. Client sẽ gửi request đến một Load Balancer trung gian (ví dụ: AWS ELB, Nginx, HAProxy), Load Balancer sẽ truy vấn Service Registry và chuyển tiếp request đến một service backend.
Công nghệ thường dùng:
API Gateway (Kong, Traefik, Spring Cloud Gateway, Nginx)
Service Mesh (Istio, Linkerd)
✅ Ưu điểm:
Client đơn giản hơn, không cần biết danh sách service, không cần xử lý logic tìm kiếm service.
Load Balancer trung gian chịu trách nhiệm phân phối tải và tìm kiếm service.
Dễ kiểm soát và mở rộng hơn so với Client-side Discovery.
❌ Nhược điểm:
Cần một Load Balancer trung gian do đó tăng độ trễ vì phải qua một Load Balancer trung gian.
Load Balancer có thể trở thành bottleneck nếu không được cấu hình đúng.
Ví dụ: AWS Auto Scaling với ELB
AWS ELB tự động lấy danh sách service từ EC2 Auto Scaling hoặc ECS Service Discovery.
Khi có service mới, nó tự động thêm vào Load Balancer mà không cần client quan tâm.
Ví dụ: Server-side Discovery với Kubernetes Service
apiVersion: v1
kind: Service
metadata:
name: user-service
spec:
selector:
app: user-service
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
Client chỉ cần gọi http://user-service
mà không cần biết địa chỉ cụ thể của từng Pod.
Các công cụ Service Discovery phổ biến
Công cụ | Kiểu Discovery | Đặc điểm chính | Ưu điểm | Nhược điểm | |
Eureka (Netflix) | Client-side | Dùng trong Spring Cloud, hỗ trợ tự động đăng ký/xóa service | Dễ dùng với Spring Boot | Không hỗ trợ DNS-based discovery | |
Consul (HashiCorp) | Cả hai | Hỗ trợ health check, key-value store, DNS-based discovery | Hỗ trợ DNS & Key-Value Store | Cấu hình phức tạp hơn Eureka | |
Zookeeper (Apache) | Cả hai | Được Kafka, Hadoop, HBase sử dụng để quản lý cluster | Hỗ trợ phân tán mạnh | Quản lý phức tạp, cần ZNode | |
Kubernetes Service Discovery | Server-side | Tự động tạo DNS records cho mỗi service trong cluster | Tích hợp sẵn trong Kubernetes | Cấu hình security phức tạp hơn | |
etcd | Server-side | Hỗ trợ gRPC và Kubernetes | Chỉ phù hợp với hệ thống chạy Kubernetes | ||
AWS Route 53 + ECS Service Discovery | Server-side | Kết hợp DNS-based routing với ECS service | chưa dùng ko có đánh giá | chưa dùng ko có đánh giá |