Service Discovery¶
Service Discovery - механизм, которым gateway находит сетевой адрес нужного сервиса через service registry.
Service registry¶
Service registry - база живых инстансов: имя сервиса -> список адресов.
- Self-registration - сервис при старте сам регистрируется в registry и шлёт heartbeat. Так работает Eureka-клиент в Spring Cloud
- Third-party registration - инстансы регистрирует платформа, сервис про registry не знает. Так делает Kubernetes
- Health check и TTL - инстанс, который не ответил на проверку или не прислал heartbeat, выпадает из registry
Registry - отдельный сервис или часть платформы (см. Технологии). В Kubernetes его роль играют объекты
Service и EndpointSlice в API-сервере плюс DNS (CoreDNS).
Технологии¶
| Реестры | Как устроен | Когда брать |
|---|---|---|
| Consul | Реестр HashiCorp: health checks, DNS-интерфейс, KV-хранилище, встроенный mesh, несколько дата-центров | Сервисы вне Kubernetes или вперемешку: виртуальные машины и Kubernetes |
| Eureka | Реестр из Netflix OSS на Java: self-registration и heartbeat, доступность важнее согласованности (AP) | Spring Cloud без Kubernetes, легаси на Netflix OSS |
| Apache ZooKeeper | Сервис координации, discovery на эфемерных узлах (Curator Service Discovery), согласованный (CP) | ZooKeeper уже стоит: Dubbo, старые Kafka и Hadoop |
| etcd | Согласованное KV-хранилище на Raft, discovery через ключи с TTL. Хранилище самого Kubernetes | Свой discovery поверх KV, если etcd уже стоит |
| Nacos | Реестр и конфиги в одном, от Alibaba | Spring Cloud Alibaba, Dubbo |
| Встроено в платформу | Как устроен | Когда брать |
|---|---|---|
| Kubernetes | Service и EndpointSlice плюс CoreDNS, kube-proxy раскидывает запросы по живым подам |
Дефолт в Kubernetes, отдельный реестр не нужен |
| Docker Compose, Docker Swarm | Встроенный DNS: сервис доступен по имени в общей сети | Локальная разработка, небольшие стенды |
| AWS Cloud Map, ECS Service Connect | Managed-реестр и discovery для сервисов в AWS | Бэкенд в AWS без Kubernetes |
| Google Service Directory | Managed-реестр сервисов в GCP | Бэкенд в GCP |
На стороне клиента в Spring Cloud работает абстракция DiscoveryClient с реализациями для Eureka, Consul, ZooKeeper и
Kubernetes, а балансирует Spring Cloud LoadBalancer (сменил Netflix Ribbon). В service mesh
discovery делает control plane: берёт живые инстансы из реестра платформы и раздаёт их sidecar-прокси.
Client-side и server-side discovery¶
Client-side - клиент сам спрашивает registry, получает список инстансов и сам выбирает, куда идти: Eureka и Spring Cloud LoadBalancer, Consul. Хопов меньше, клиент идёт прямо в инстанс, но логика discovery живёт в каждом клиенте и в каждом языке.
Server-side - клиент идёт на стабильный адрес, а load balancer или DNS за ним берёт адреса
инстансов из registry: Kubernetes Service, AWS ELB, DNS-интерфейс Consul. Клиент простой, но появляется лишний хоп
и ещё один компонент. Так же работает API Gateway: маршрут знает имя сервиса, а адрес спрашивает у
registry.
Грабли¶
- Registry тоже падает. Без репликации и кэша адресов на клиенте он становится single point of failure для всего кластера.
- Мёртвые записи. Инстанс умер, а в registry ещё «жив». Спасают health checks и TTL, иначе трафик льётся в мёртвый под.