Питання 8 · Розділ 17

У чому різниця між client-side та server-side discovery

least-connections, по зонах доступності). При server-side discovery це рішення приймає LB, і клієнт не може на нього вплинути.

Мовні версії: English Russian Ukrainian

🟢 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

Типові помилки

  1. 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 (занадто багато 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. У чому різниця між синхронною та асинхронною комунікацією]]