Bài 1: Tại sao cần Service Discovery và các mô hình cốt lõi
Trong kiến trúc Monolith (nguyên khối), mọi module của ứng dụng chạy chung trong một tiến trình duy nhất. Khi module A muốn gọi module B, nó chỉ đơn giản là gọi hàm qua lại trong bộ nhớ (funcB()).
Nhưng khi bạn chuyển dịch sang Microservices, ứng dụng bị xé nhỏ thành hàng chục service độc lập chạy trên các container (Docker/Kubernetes) khác nhau, phân bố trên nhiều máy chủ khác nhau. Lúc này, bài toán "làm thế nào để các service tìm thấy nhau" trở thành một thách thức hóc búa.
1. Nỗi đau của cấu hình tĩnh (Static Configuration)
Ở giai đoạn đầu khi mới làm quen với microservices, nhiều lập trình viên thường lưu địa chỉ của các service vào file cấu hình (config.yaml hoặc biến môi trường):
Đoạn mã
PAYMENT_SERVICE_URL=http://192.168.1.50:8080
ORDER_SERVICE_URL=http://192.168.1.51:9090
Cách làm này nhanh gọn nhưng lập tức sụp đổ khi hệ thống Scale (mở rộng quy mô):
-
Dynamic IP & Auto-scaling: Trong môi trường cloud (như AWS, Kubernetes), các service container liên tục được tạo mới, thay thế hoặc chết đi (scale up/down). Địa chỉ IP và Port thay đổi liên tục theo thời gian thực. File config cứng sẽ bị "lỗi thời" ngay lập tức.
-
Load Balancing thủ công: Khi một service có tới 5 instance chạy song song để gánh tải, việc cấu hình một IP cố định sẽ khiến 4 instance còn lại bị bỏ phí hoặc gây nghẽn cổ chai.
Đó là lúc Service Discovery (Khám phá dịch vụ) ra đời, đóng vai trò như một "danh bạ điện thoại trung tâm" tự động cập nhật trạng thái sống/chết của mọi service trong mạng nội bộ.
2. Các thành phần cốt lõi của Service Discovery
Một hệ thống Service Discovery hoàn chỉnh bao gồm 3 thực thể chính:
-
Service Registry (Kho lưu trữ dịch vụ): Cơ sở dữ liệu trung tâm (như Consul, Etcd, hoặc ZooKeeper) lưu danh sách địa chỉ IP và Port của tất cả các service đang hoạt động.
-
Service Provider (Bên cung cấp): Mỗi khi một service instance khởi động, nó sẽ tự động gửi yêu cầu Register (Đăng ký) thông tin của mình lên Service Registry, và gửi tín hiệu định kỳ để báo rằng mình vẫn sống. Khi tắt, nó sẽ gửi lệnh Deregister.
-
Service Consumer (Bên tiêu thụ): Khi cần gọi một service khác, thay vì gọi một IP cứng, nó sẽ hỏi Service Registry: "Cho tôi xin danh sách các IP đang chạy của Payment Service".
3. Hai mô hình kiến trúc cốt lõi
Tùy thuộc vào cách client tương tác với registry, hệ thống phân tán được chia thành 2 mô hình chính:
Mô hình 1: Client-side Discovery (Khám phá phía Client)
Trong mô hình này, Client tự chịu trách nhiệm liên lạc trực tiếp với Service Registry để tra cứu địa chỉ, sau đó tự áp dụng thuật toán cân bằng tải (như Round-Robin) để chọn ra một instance cụ thể và gửi request.
-
Luồng hoạt động:
-
Client hỏi Service Registry: "Payment Service ở đâu?"
-
Registry trả về danh sách IP:
[10.0.0.1, 10.0.0.2] -
Client tự chọn
10.0.0.1và bắn HTTP/gRPC request thẳng đến đó.
-
-
Ưu điểm: Giảm bớt mộthop trung gian, kiến trúc phi tập trung (decentralized).
-
Nhược điểm: Client phải cài đặt logic tích hợp với từng loại Registry (tốn code client-side, khó viết đa ngôn ngữ).
Mô hình 2: Server-side Discovery (Khám phá phía Server)
Client không cần biết gì về Service Registry hay danh sách IP. Nó chỉ cần gửi request đến một Load Balancer (hoặc API Gateway / Reverse Proxy) trung gian.
-
Luồng hoạt động:
-
Client gửi request tới Load Balancer chung (
api.internal.local/payment). -
Load Balancer tự động tra cứu Service Registry, chọn một instance đang rảnh, và chuyển tiếp (proxy) request tới đó.
-
-
Ưu điểm: Client cực kỳ tinh gọn, không bị ràng buộc công nghệ.
-
Nhược điểm: Thêm một điểm trung gian (Load Balancer), có thể trở thành điểm nghẽn hoặc điểm lỗi đơn lẻ (Single Point of Failure) nếu không cấu hình dự phòng.
Tổng kết
Service Discovery là chiếc "cầu nối động" giúp các microservices không bao giờ bị lạc nhau trong mạng nội bộ biến động khôn lường.
Tuy nhiên, có một câu hỏi lớn đặt ra: Làm thế nào để Service Registry biết chắc chắn rằng một service instance đã "chết đột ngột" (do mất mạng hoặc crash nguồn) để lập tức xóa nó khỏi danh bạ, tránh việc định tuyến request vào hư không?
Đó chính là nội dung cốt lõi của bài học tiếp theo.
All rights reserved