What Is Service Discovery in Microservices?
October 21, 2022
Key Takeaways
- Service discovery maps a stable service identity to changing network endpoints. It removes the need for clients or operators to hardcode pod, container, or virtual-machine addresses.
- A complete design covers registration, health, lookup, selection, and removal. A registry that returns stale or unhealthy instances can amplify an outage.
- Discovery can happen in the client, an intermediary such as an API gateway, or the platform through DNS and Kubernetes Services. The right placement depends on language diversity, traffic path, and operational ownership.
- Consul, Eureka, Nacos, and Kubernetes solve overlapping but different problems. Compare their consistency, health model, interfaces, tenancy, and failure behavior instead of choosing by feature count alone.
- An API gateway can consume discovery data to build its upstream pool. It does not replace the registry, application-level readiness checks, or a service mesh for all east-west traffic.
What Is Service Discovery in Microservices?
Service discovery in microservices is the process of finding the current network locations of available instances for a named service. A caller asks for a logical identity such as payments, while the discovery system returns one or more usable addresses such as 10.42.7.19:8080.
That indirection is necessary because instance addresses are not stable. A deployment may replace pods, an autoscaler may add replicas, a failed node may remove several instances, or a release may run two versions at once. Hardcoded addresses turn every topology change into a configuration rollout. A service registry or platform directory keeps identity stable while endpoints change underneath it.
DNS is a familiar example of the same idea: a name is resolved to current records rather than forcing every user to remember an IP address. Microservice discovery extends the model with information such as ports, health state, metadata, zones, weights, or versions.
flowchart LR
Instance[Service instance] -->|register and renew| Registry[Service registry]
Health[Health signal] --> Registry
Client[Service consumer] -->|resolve payments| Resolver[Client, gateway, or platform resolver]
Resolver -->|query or subscribe| Registry
Registry -->|healthy endpoints| Resolver
Resolver -->|select endpoint| Instance
The registry is a source of endpoint information, not proof that every request will succeed. A passing health check may still miss a dependency failure, overload, or a business-level error. Callers still need bounded timeouts, safe retries, circuit breaking where appropriate, and observability.
How Service Discovery Works
A practical discovery lifecycle has five parts.
1. Registration
An instance must become known to the registry. Registration can be self-managed by the application, performed by an agent, or derived from a platform controller. The record normally contains a service name, address, port, and optional metadata such as zone or version.
Self-registration is flexible but adds a client library and lifecycle responsibility to every service. Platform-managed registration reduces application code but ties discovery to the orchestrator or deployment environment. Whichever model you choose, instance identity should be unique and deregistration should be automatic when a workload is removed.
2. Health and Liveness
The registry needs a rule for deciding whether an instance should remain discoverable. Common approaches include active HTTP, TCP, or gRPC checks; instance heartbeats; agent sessions; and platform readiness state.
Health semantics matter more than the check mechanism. A liveness check answers whether a process should be restarted. A readiness check answers whether it should receive traffic. A deep dependency check may be too fragile for either purpose if one optional dependency removes every instance from rotation.
For example, Consul health checks can associate multiple checks with a service and use their state during discovery. Kubernetes normally derives routable endpoints from Service selectors and workload readiness. Nacos distinguishes ephemeral and persistent service semantics in its service discovery model.
3. Lookup or Subscription
Consumers can resolve a service through DNS, an HTTP API, a language SDK, long polling, streaming, or a platform watch. Polling is simple but introduces a freshness interval. Push or watch models can reduce update delay, but they require reconnect, resynchronization, and backpressure behavior.
Caching is expected, not inherently wrong. The important questions are how long results remain valid, what happens after the registry becomes unavailable, and whether a client can continue using a last-known-good endpoint set without keeping removed instances indefinitely.
4. Endpoint Selection
Discovery returns candidates; a client, proxy, gateway, or load balancer selects an endpoint. Selection may use round robin, consistent hashing, weights, locality, priority, or health state. Registry metadata should not silently become an authorization boundary. A zone=internal tag is useful for routing, but identity and access policy still need explicit enforcement.
5. Removal and Failure Handling
Instances must be removed when they shut down, stop renewing, fail health checks, or lose platform readiness. Detection is never instantaneous. Graceful shutdown therefore needs coordination: stop accepting new traffic, become unready or deregister, drain existing work, and then terminate.
During a registry outage, fail-closed and fail-open choices have different risks. Keeping a last-known-good pool may preserve availability, but it can route to terminated instances. Returning no endpoints prevents stale routing but can cause a full outage. Set an explicit stale-data budget and alert when a resolver has stopped receiving updates.
Client-Side, Server-Side, and Platform Discovery
The most useful classification is where resolution and endpoint selection happen.
| Pattern | Resolver | Strengths | Trade-offs |
|---|---|---|---|
| Client-side discovery | Application library or SDK | Direct path; application can use rich metadata | Every language needs compatible logic; upgrades are distributed |
| Server-side discovery | API gateway, proxy, or load balancer | Centralized policy and a consistent client contract | Intermediary becomes part of the request path and failure domain |
| Platform-native discovery | DNS, Kubernetes Service, or orchestrator | Minimal application-specific integration | Metadata and routing options depend on the platform interface |
These patterns can coexist. A public request may enter through an API gateway that discovers a Kubernetes Service, while services inside the cluster use platform DNS. A legacy Java estate may keep Eureka client-side discovery during a gradual migration. The goal is not to force every call through one component; it is to make ownership and failure behavior predictable.
Consul, Eureka, Nacos, and Kubernetes
Discovery products should be compared in context rather than treated as interchangeable lists of features.
Consul
Consul service discovery maintains a catalog of services and health information. Consumers can query through DNS or HTTP APIs, and Consul also provides service-mesh and service-networking capabilities beyond basic discovery. It is useful across virtual machines, containers, and multiple runtimes, but operating its servers, agents, ACLs, TLS, and upgrade path is an explicit platform responsibility.
Eureka
Netflix Eureka provides a REST-based registry and a Java client commonly associated with Spring ecosystems. The current repository publishes both 1.x and 2.x tags, so version support should be checked against the framework and client used by the application rather than inferred from the old experimental 2.x-archive branch. Eureka's client behavior and self-preservation model favor availability during certain network failures, which is a design trade-off rather than a universal advantage.
Nacos
Nacos service discovery manages services, instances, clusters, health state, and subscriptions. It supports ephemeral and persistent service models and is often used alongside its configuration-management features. Current Nacos client APIs include service registration, renewal, deregistration, and instance lookup; gRPC-based client communication is not merely a future plan. Namespace, group, service, cluster, and instance boundaries should be designed deliberately so environments and tenants do not collide.
Kubernetes
Kubernetes already maintains workload and Service information. Cluster DNS gives applications a stable Service name, while controllers and proxies can watch Endpoints or EndpointSlice resources for individual backends. Kubernetes-native discovery is usually the simplest choice for workloads that live entirely in one cluster environment. Multi-cluster, virtual-machine, and cross-runtime requirements may still justify a separate registry or higher-level service-networking layer.
How an API Gateway Uses Service Discovery
An API gateway typically handles north-south API traffic. Instead of storing a static list of upstream IP addresses, it can resolve a service name and keep an upstream pool synchronized with the registry. The related guide to API gateways and service discovery explains where that integration belongs in the wider architecture.
Apache APISIX supports multiple discovery integrations, including DNS, Consul, Eureka, Nacos, and Kubernetes. The supported configuration and freshness model differ by integration, so operators should use the current documentation for the selected APISIX release rather than copying an old cross-registry example.
For a Consul-backed upstream, the route refers to a service name and discovery type instead of embedding nodes:
export ADMIN_API_KEY='replace-with-a-protected-admin-key' curl --fail "http://127.0.0.1:9180/apisix/admin/routes/orders" \ -H "X-API-KEY: ${ADMIN_API_KEY}" \ -H 'Content-Type: application/json' \ -X PUT \ -d '{ "uri": "/orders/*", "upstream": { "service_name": "orders", "discovery_type": "consul", "type": "roundrobin" } }'
The Consul client settings, ACL token, timeouts, and registry addresses belong in APISIX configuration and secret management. Current APISIX Consul discovery documentation configures http:// server addresses and does not expose a TLS verification field for this integration. Keep registry traffic on a trusted, protected network or provide the required transport protection outside this integration. Do not commit registry credentials or the Admin API key in a route example.
sequenceDiagram
participant Operator
participant Registry as Service Registry
participant Gateway as API Gateway
participant Client
participant Service as Eligible Service Instance
Service->>Registry: Register and renew
Operator->>Gateway: Configure upstream service name
Gateway->>Registry: Query, poll, or watch endpoints
Registry-->>Gateway: Current eligible endpoint set
Client->>Gateway: API request
Gateway->>Service: Route using local upstream pool
Service-->>Gateway: Response
Gateway-->>Client: Response
Discovery does not automatically provide authorization, mTLS, retries, or safe failover. Those are separate policies. It also does not mean the gateway should manage all east-west service traffic. A service mesh, direct platform DNS, or client library may remain the right path for internal calls.
Design Checklist for Production
Before selecting a registry or connecting it to a gateway, answer these questions:
- What is the service identity? Define naming, namespace, environment, tenant, and version rules.
- Who registers instances? Decide whether the application, an agent, or the orchestrator owns registration and deregistration.
- What makes an endpoint ready? Separate liveness, readiness, dependency health, and business-level correctness.
- How fresh must results be? Document polling intervals, watch reconnects, DNS TTLs, and cache expiration.
- What happens when the registry is unavailable? Set a last-known-good policy, stale-data limit, and alerts.
- Where is load balancing performed? Avoid unintentionally balancing once in a client and again in a gateway without understanding the effect.
- How are credentials protected? Use TLS, registry ACLs, least-privilege identities, and managed secrets.
- How will you observe the system? Monitor registration churn, lookup errors, stale caches, empty endpoint sets, rejected endpoints, and upstream failures.
- How will migration work? During a registry transition, prevent duplicate registrations, inconsistent service names, and two sources of truth.
- Which traffic belongs on this path? Keep gateway ingress, internal service calls, asynchronous messaging, and administrative traffic as explicit architectural decisions.
Conclusion
Service discovery gives microservices a stable way to find dynamic instances, but the registry alone is only one part of the solution. Registration, health, lookup, endpoint selection, caching, and removal must work together under normal operation and partial failure.
Consul, Eureka, Nacos, Kubernetes, and DNS each offer valid discovery paths with different operational models. An API gateway such as Apache APISIX can consume those paths for upstream routing, especially at an API boundary, while leaving registry ownership and internal service communication to the appropriate platform components.
Start by defining failure behavior and ownership, then choose the interface that fits your runtimes. That approach produces a more reliable design than selecting a discovery system first and trying to make every traffic path conform to it.


