В чём разница между client-side и server-side discovery
least-connections, по зонам доступности). При server-side discovery это решение принимает LB, и клиент не может на него повлиять.
🟢 Junior Level
Client-side discovery:
Сервис A сам спрашивает Registry и вызывает Сервис B
Сервис A → Registry: "Где сервис B?" → 10.0.0.5:8080 → вызов
Server-side discovery:
Сервис A вызывает Load Balancer, а LB сам находит Сервис B
Сервис A → Load Balancer → Registry → Сервис B
Разница: кто делает запрос к Registry — клиент или сервер (LB).
🟡 Middle Level
Client-side
// Сервис A сам ищет сервис B
ServiceRegistry registry = new ConsulRegistry("consul:8500");
ServiceInstance instance = registry.getInstance("service-b");
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(5))
.build();
HttpResponse<String> response = client.send(
HttpRequest.newBuilder(URI.create("http://" + instance.getAddress() + "/api"))
.GET().build(),
BodyHandlers.ofString()
);
Плюсы:
- Больше контроля: сервис сам решает, какой инстанс выбрать (round-robin, least-connections, по зонам доступности). При server-side discovery это решение принимает LB, и клиент не может на него повлиять.
- Нет дополнительного hop через LB
Минусы:
- Нужно реализовать discovery logic в каждом сервисе
- Зависимость от Registry SDK
Server-side
Сервис A → Load Balancer (Nginx/HAProxy) → Service B
# Nginx config
# В production Nginx Plus или consul-template динамически обновляют upstreams.
# Статические IP — упрощение для примера.
upstream service_b {
server 10.0.0.5:8080;
server 10.0.0.6:8080;
}
Плюсы:
- Проще для клиентов
- LB берёт на себя discovery и balancing
Минусы:
- Дополнительный hop (latency)
- LB — single point of failure
Типичные ошибки
- Client-side: кэширование без TTL:
Сервис A закэшировал IP сервиса B Сервис B переехал на новый IP Сервис A стучится на старый IP
🔴 Senior Level
Архитектурные Trade-offs
| Client-side | Server-side |
|---|---|
| No single point of failure | LB может упасть |
| Сложнее реализовать | Проще |
| Меньше latency | +1 hop |
| Гибкость (retry, circuit breaker) | Меньше контроля |
Production Experience
Kubernetes (server-side):
K8s Services → kube-proxy → Endpoints
Сервис A → my-service:8080 → kube-proxy → Pod B
Netflix Ribbon (client-side): ⚠️ Netflix Ribbon устарел (в maintenance mode с 2018). В современных проектах используйте Spring Cloud LoadBalancer или K8s Service.
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
// Ribbon сам делает discovery + load balancing
restTemplate.getForObject("http://service-b/api", String.class);
Best Practices
✅ Client-side: caching с TTL
✅ Server-side: multiple LB для HA
✅ Health checks в обоих случаях
✅ Fallback при недоступности Registry
❌ Без caching (too many Registry calls)
❌ Без fallback при недоступности LB
🎯 Шпаргалка для интервью
Обязательно знать:
- Client-side: сервис сам спрашивает Registry и выбирает инстанс (round-robin, least-connections)
- Server-side: LB берёт discovery и balancing на себя (Nginx, K8s Service)
- Client-side: нет extra hop, но нужно реализовать логику в каждом сервисе
- Server-side: проще для клиентов, но +1 hop и LB — потенциальный SPOF
- Netflix Ribbon устарел (maintenance mode с 2018) — используйте Spring Cloud LoadBalancer
- Client-side caching ОБЯЗАТЕЛЕН с TTL, иначе stale IP
- K8s использует server-side: kube-proxy → Endpoints
Частые уточняющие вопросы:
- Когда выбрать client-side? Нужна гибкость (retry, circuit breaker), минимальная latency.
- Когда выбрать server-side? Проще, когда команда не хочет писать discovery logic.
- Что будет без TTL в кэше? Сервис переехал на новый IP — клиент стучится на старый.
- K8s это какой тип? Server-side: Service → DNS → kube-proxy → Pod.
Красные флаги (НЕ говорить):
- “Netflix Ribbon — лучший выбор” — устарел, используйте Spring Cloud LoadBalancer
- “Caching не нужен, Registry быстрый” — лишняя нагрузка на Registry при каждом вызове
- “Server-side всегда лучше” — зависит от требований к гибкости
- “LB никогда не падает” — нужен HA (multiple LB)
Связанные темы:
- [[7. Что такое Service Discovery и зачем он нужен]]
- [[9. Что такое API Gateway и какие задачи он решает]]
- [[12. Как реализовать горизонтальное масштабирование микросервисов]]
- [[26. Какие инструменты используются для оркестрации микросервисов]]
- [[16. В чём разница между синхронной и асинхронной коммуникацией]]