Service discovery là phương pháp nhận diện và truy cập các thiết bị và dịch vụ một cách tự động trên một mạng. Nó là một mô hình phổ biến được sử dụng trong các hệ thống phân tán (distributed system) và kiến trúc microservice. Bởi vì các servers trong một môi trường có thể bị ngắt và việc dựa vào các địa chỉ IP tĩnh trong hệ thống là không tin cậy (not reliable) và có thể dẫn tới sự cố và lỗi hệ thống.
Service Discovery thực sự là gì?
Hãy tìm hiểu service discovery qua một ví dụ thực tế nhé.
Ví dụ bạn có một ứng dụng được deploy trên nhiều servers và một database cluster gồm 6 servers. Ứng dụng cần kết nối tới database để lưu trữ và đọc data.
Để tạo được kết nối này, ứng dụng cần biết vị trí mạng (địa chỉ IP và port) của database cluster. Một cách để làm việc này là viết địa chỉ IP và port vào file giá trị của ứng dụng. Tuy nhiên cách này có các nhược điểm:
Không scalable: Nếu database cluster được tự động hóa hoàn toàn, địa chỉ IP của các database servers có thể thay đổi trong quá trình patching hoặc failover. Hoặc nhiều servers có thể được thêm vào cluster để scale up cluster, trong trường hợp này, bạn sẽ cần cập nhật giá trị của ứng dụng trên từng server trong cluster của ứng dụng.
Error-prone: Nếu bạn nhập sai địa chỉ IP hoặc port, ứng dụng có thể không kết nối được tới database.
Không flexible: Nếu bạn cần thêm hoặc bớt database nodes với các địa chỉ IP khác nhau, bạn cần cập nhật code của cả ứng dụng.
Bạn có thể dùng DNS endpoint cho các servers. Tuy nhiên nếu IP thay đổi, bạn cần cập nhật thủ công địa chỉ IP của DNS.
Vì vậy, cần có một kĩ thuật hiệu quả cho ứng dụng để truy cập các database servers đang hoạt động trong mọi thời điểm cần thiết.
Và đó là lúc bạn có thể sử dụng service discovery. Một hệ thống service discovery là một công cụ cho phép các servers hay dịch vụ đăng ký bản thân chúng và khám phá các dịch vụ khác.
Trong ví dụ của chúng ta, các node (server) trong database cluster sẽ đăng ký bản thân chúng với hệ thống service discovery (service registry), và các server ứng dụng sẽ dùng hệ thống service discovery để tìm các địa chỉ IP của các database servers.
Giờ hãy tìm hiểu các thành phần quan trọng nhất của service discovery nhé.
Service Registry
Nó là một service registry tập trung lưu trữ thông tin về các dịch vụ khả dụng. Trong đa số các trường hợp, Nó là một database dạng khóa-giá trị. Hình ảnh bên dưới hiển thị dashboard của một service registry của một công cụ service discovery tên là consul.
Dưới đây là cách nó hoạt động trong ví dụ của chúng ta.
Khi database server lên, nó đăng ký nó như một dịch vụ khả dụng với service registry. Nó cung cấp địa chỉ IP của nó, port, và health check URLs của ứng dụng. Việc này diễn ra thông qua một thư viện code hoặc một service discovery agent chạy trên node database server đó.
Server của ứng dụng cần kết nối tới database sẽ dùng service discovery agent để kết nối tới service registry thông qua API/DNS và query tới các database server IP khả dụng.
Vì database server đã đăng ký bản thân nó, các server của ứng dụng sẽ có thể đọc thông tin IP và port của database từ service registry và dùng nó trong cấu hình của ứng dụng để đọc và lưu trữ data.
Dưới đây là ví dụ về việc các node tự đăng ký bản thân vào backend service registry của service discovery.
Chuyện gì xảy ra nếu server đã đăng ký bị fail?
Nếu một database server fail, service registry sẽ nhận biết nó vì nó có thông tin về health check của từng node. Service registry sẽ đánh dấu node đó là unhealthy. Agent chạy trong server ứng dụng sẽ liên tục quản lý thay đổi của service registry từ đó biết rằng node nào đó có fail hay không. Vì vậy các server ứng dụng sẽ bỏ địa chỉ IP của node unhealthy khỏi cấu hình của nó. Tất cả những việc này chỉ diễn ra trong vòng vài giây.
What Happens if a New Server is Registered? Vậy nếu một server mới được đăng ký?
Chu trình sẽ tương tự như trên. Server mới đăng ký bản thân nó. Ứng dụng nhận biết nó thông qua service registry và thêm nó vào cấu hình.
Các loại service discovery
Có 2 mô hình service discovery.
1. Mô hình Client-Side Service Discovery
Trong mô hình này, giả dụ client là một ứng dụng chịu trách nhiệm tương tác với service registry để lấy thông tin về dịch vụ.
Ví dụ, client query service registry để lấy thông tin về các dịch vụ backend khả dụng.
Trong mô hình này, client cần phát triển logic của service discovery query trong ứng dụng. Ví dụ nếu ứng dụng muốn có thông tin của các server database khả dụng, ứng dụng nên query dùng thư viện service discovery client để query service registry.
Mô hình Server-Side Service Discovery
Trong mô hình này, request tới load balancer (server) và load balancer kết nối tới service registry để lấy địa chỉ IP của các node healthy.
Một ví dụ cổ điển của mô hình này là Nginx load balancing sử dụng service discovery. Clients giao tiếp trực tiếp với Nginx load balancer và load balancer query service registry để lấy danh sách các node để route traffic.
Dưới đây hiển thị server-side service discovery dùng consul.
Các công cụ service discovery
Để phát triển service registry bạn cần các công cụ cụ thể. Đây là 2 công cụ thông dụng mã nguồn mở cho việc này:
Hashicorp Consul
etcd (chủ yếu dùng cho Kubernetes Service Discovery)
Bạn có thể dùng REST API, DNS và gRPC cùng các công cụ trên
Service Discovery Hands-On
Nếu bạn muốn hiểu rõ hơn về concept này, hãy thử set up Nginx reverse proxy dùng consul.
Hãy xem qua bài viết này:
Kết luận
Service discovery là một concept bắt buộc phải biết với mọi developers và devops engineers. Hầu hết các hệ thống phân tán (distributed system) và kiến trúc microservice đều dùng nó.