Microservices Service Discovery
In a microservices system, services move. A new instance of the Payment Service starts on a different server every time it scales up. Crashed instances disappear. Old IP addresses become invalid. Service Discovery solves the problem of services finding each other in this constantly changing environment.
The Problem: Dynamic IP Addresses
In a traditional system, you hard-code the server address of a service into a configuration file. That works when addresses never change. In a modern microservices deployment, services run in containers that start and stop constantly. Their addresses change every time.
WITHOUT SERVICE DISCOVERY ========================== Order Service config file: payment_service_url = "192.168.1.45:8080" Payment Service moves to a new container. New address: "192.168.1.89:8080" Order Service still points to 192.168.1.45 --> Connection failed. Requires manual config update + restart of Order Service.
At scale, with hundreds of services and thousands of instances, manual management is impossible.
How Service Discovery Works
Service Discovery uses a Service Registry — a database that tracks the current address of every running service instance.
SERVICE REGISTRY CONCEPT ========================= Registry is like a phone book that updates itself automatically. When Payment Service starts: --> Registers itself: "PaymentService at 192.168.1.89:8080" When Payment Service stops (or crashes): --> Automatically removed from registry after health check fails When Order Service needs Payment Service: --> Asks registry: "Where is PaymentService?" --> Registry responds: "192.168.1.89:8080" --> Order Service connects to correct address
Client-Side Discovery
The client (calling service) queries the registry directly and decides which instance to call. The client also performs load balancing across available instances.
CLIENT-SIDE DISCOVERY FLOW ============================ Order Service needs Payment Service. Step 1: Order Service queries Registry "Give me all instances of PaymentService" Registry returns: [192.168.1.89:8080, 192.168.1.90:8080, 192.168.1.91:8080] Step 2: Order Service picks one (round-robin, random, or fastest) Picks: 192.168.1.90:8080 Step 3: Order Service calls Payment Service directly POST http://192.168.1.90:8080/charge DIAGRAM: [Order Service] --1. query--> [Registry] [Order Service] <--2. list --- [Registry] [Order Service] --3. call---> [Payment Instance 2]
Netflix's Eureka is a widely used client-side discovery tool. The Netflix client library Ribbon handles the load balancing step.
Server-Side Discovery
The client sends the request to a load balancer or router. The router queries the registry and forwards the request to the correct instance. The client does not need to know anything about the registry.
SERVER-SIDE DISCOVERY FLOW
============================
Order Service sends request to a load balancer.
Load balancer queries the registry.
Load balancer picks an instance and forwards the request.
DIAGRAM:
[Order Service] ---> [Load Balancer / Router]
|
+--query--> [Registry]
|
+--forward--> [Payment Instance 2]
AWS Elastic Load Balancer and Kubernetes Services use server-side discovery. The client sends to one stable address. The infrastructure handles routing internally.
Self-Registration vs Third-Party Registration
Self-Registration
The service itself registers with the registry when it starts and deregisters when it stops. The service must include registration logic in its startup code.
Service starts up:
Code runs: registry.register("PaymentService", host, port)
Service receives SIGTERM (shutdown signal):
Code runs: registry.deregister("PaymentService", host, port)
Third-Party Registration
An external tool watches for new services starting (by watching the container platform) and registers them automatically. The service itself contains no registration code. Registrator and Kubernetes both do this automatically.
Health Checks in Service Discovery
Registries do not just trust that a service is alive because it registered. They actively check. If a service stops responding to health checks, the registry removes it from the list.
Registry pings each instance every 10 seconds: GET http://192.168.1.89:8080/health 3 consecutive failures --> instance removed from registry New requests no longer route to that instance Instance recovers --> re-registers itself Registry adds it back to the available list
Popular Service Discovery Tools
- Consul — feature-rich, built-in health checks, DNS and HTTP interfaces, widely used in production.
- Eureka — developed by Netflix, designed for cloud environments, integrates with Spring Boot.
- etcd — distributed key-value store used by Kubernetes internally for all service metadata.
- Kubernetes DNS — in Kubernetes, every Service gets a stable DNS name automatically; service discovery is built in.
Service Discovery in Kubernetes
Kubernetes makes service discovery almost invisible. When you create a Service object in Kubernetes, it gets a stable DNS name. Other pods call that name regardless of which pods are running behind it.
Payment Service Kubernetes Service name: payment-service Order Service calls: http://payment-service/charge Kubernetes routes the request to any healthy Payment Service pod. Pods come and go. The name stays the same. Order Service never notices.
For teams using Kubernetes, built-in DNS service discovery is usually sufficient without adding an external registry like Consul.
