Skip to main content

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
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)
}

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.