Service Discovery — Finding Services Dynamically
Dynamically locate healthy service instances without hardcoded IPs — services register themselves, clients or load balancers query the registry.
When to use
- Any microservice environment where instances scale dynamically
- Client-side discovery when you need custom load balancing logic
Tradeoffs
- Registry is a critical dependency — must be HA or all service discovery fails
- DNS TTL caching can cause stale routing to failed instances
- Go
- Python
func registerService(client *consul.Client, addr string, port int) (string, error) {
id := fmt.Sprintf("payment-%s-%d", addr, port)
reg := &consul.AgentServiceRegistration{
ID: id,
Name: "payment-service",
Address: addr,
Port: port,
Check: &consul.AgentServiceCheck{
HTTP: fmt.Sprintf("http://%s:%d/healthz", addr, port),
Interval: "10s",
Timeout: "2s",
},
}
return id, client.Agent().ServiceRegister(reg)
}
func deregisterService(client *consul.Client, id string) error {
return client.Agent().ServiceDeregister(id)
}
import consul
def register_service(c: consul.Consul, addr: str, port: int) -> str:
service_id = f"payment-{addr}-{port}"
c.agent.service.register(
name="payment-service",
service_id=service_id,
address=addr,
port=port,
check=consul.Check.http(
f"http://{addr}:{port}/healthz",
interval="10s",
timeout="2s",
),
)
return service_id
def deregister_service(c: consul.Consul, service_id: str) -> None:
c.agent.service.deregister(service_id)
Gotcha: Kubernetes DNS-based service discovery works out of the box for in-cluster traffic. Don't add Consul or etcd unless you need cross-cluster or hybrid-cloud discovery.