What is Service Discovery in Microservices?
1. What is Service Discovery?
Service Discovery is a mechanism that allows Microservices, API Gateways, and other clients to automatically find the current network location of another service.
In Microservices, service instances can be created, removed, restarted, or moved. Therefore, their IP addresses and ports may change dynamically.
Instead of hardcoding:
Product Service = 10.0.0.21:7001
the caller asks a service registry or platform discovery mechanism:
“Where is Product Service currently running?”
The discovery system returns the available healthy service instances.
Simple definition
Service Discovery allows services to locate other services dynamically without hardcoding their IP addresses and ports.
2. Why Do We Need Service Discovery?
Consider an API Gateway with this configuration:
{
"Host": "10.0.0.21",
"Port": 7001
}
Architecture:
API Gateway
│
▼
10.0.0.21:7001
│
▼
Product Service
This works while Product Service remains at that address.
But in a real Microservices environment, Product Service may restart.
Before:
Product Service
10.0.0.21:7001
After restart:
Product Service
10.0.0.45:7001
Now the gateway's hardcoded configuration is wrong.
Gateway
│
│ 10.0.0.21
▼
X
You could manually update the configuration, but that becomes impractical when there are many services and instances.
3. Purpose of Service Discovery
The purpose is to decouple a service's logical identity from its physical network location.
Instead of saying:
Call:
10.0.0.21:7001
the application effectively says:
Call:
ProductService
The infrastructure/discovery mechanism determines where ProductService currently exists.
ProductService
│
▼
Service Discovery
│
├── 10.0.0.21:7001
├── 10.0.0.22:7001
└── 10.0.0.23:7001
4. Without Service Discovery
Imagine three Microservices:
Product Service
10.0.0.10:7001
Order Service
10.0.0.11:7002
Payment Service
10.0.0.12:7003
Order Service calls Product Service:
var client = new HttpClient();
var response =
await client.GetAsync(
"http://10.0.0.10:7001/api/products/10");
There are two problems here.
First, the address is hardcoded.
Second, in ASP.NET Core, you would normally prefer IHttpClientFactory over directly creating HttpClient repeatedly.
The bigger architectural problem is:
10.0.0.10
may change.
5. Dynamic Microservices Environment
Suppose Product Service is horizontally scaled:
Product Service
Instance 1
10.0.0.21:7001
Instance 2
10.0.0.22:7001
Instance 3
10.0.0.23:7001
Later, autoscaling adds another instance:
Instance 4
10.0.0.24:7001
Then Instance 2 fails:
Instance 2 ✗
10.0.0.22:7001
Available instances are now:
10.0.0.21:7001 ✓
10.0.0.23:7001 ✓
10.0.0.24:7001 ✓
Your applications should not require manual configuration every time this happens.
That's where Service Discovery becomes useful.
6. Service Registry
A common Service Discovery architecture uses a Service Registry.
Think of it as a directory containing:
Service Name
↓
Available Service Instances
Example:
┌─────────────────────────────────┐
│ Service Registry │
│ │
│ ProductService │
│ ├── 10.0.0.21:7001 │
│ ├── 10.0.0.22:7001 │
│ └── 10.0.0.23:7001 │
│ │
│ OrderService │
│ ├── 10.0.0.31:7002 │
│ └── 10.0.0.32:7002 │
│ │
│ PaymentService │
│ └── 10.0.0.41:7003 │
└─────────────────────────────────┘
The caller doesn't need to know those addresses permanently.
It asks:
Where is ProductService?
7. How Does Service Discovery Work?
A typical registry-based flow is:
Product Service
│
│ Register
▼
Service Registry
▲
│ Discover
│
API Gateway
Let's break this down.
Step 1 — Service starts
Product Service
10.0.0.21:7001
Step 2 — Service registers itself
Conceptually:
Register:
Name = ProductService
Address = 10.0.0.21
Port = 7001
Registry now knows:
ProductService
↓
10.0.0.21:7001
Step 3 — Another instance starts
ProductService
│
├── 10.0.0.21:7001
└── 10.0.0.22:7001
Step 4 — Gateway needs Product Service
Gateway asks:
Service Registry
"Give me available instances
of ProductService."
Registry returns:
10.0.0.21:7001
10.0.0.22:7001
Step 5 — An instance is selected
A load-balancing mechanism can select:
10.0.0.22:7001
Request becomes:
Gateway
│
▼
10.0.0.22:7001
│
▼
Product Service
8. Service Discovery + Load Balancing
These two concepts are closely related, but they are not the same thing.
Service Discovery
Answers:
What instances are currently available?
Example:
ProductService
│
├── Instance A
├── Instance B
└── Instance C
Load Balancer
Answers:
Which available instance should receive this request?
A
B ← selected
C
Therefore:
Service Discovery
↓
Find available instances
↓
Load Balancer
↓
Choose one instance
↓
Send request
This is a very important interview distinction.
9. Service Discovery vs Load Balancer vs API Gateway
Remember the responsibilities this way:
API Gateway
↓
Which SERVICE?
Service Discovery
↓
WHERE are its instances?
Load Balancer
↓
Which INSTANCE should receive this request?
Example:
Client
│
│ /products
▼
API Gateway
│
│ Need ProductService
▼
Service Discovery
│
│ Available:
│ A, B, C
▼
Load Balancer
│
│ Select B
▼
Product Instance B
In real platforms, these responsibilities may be combined into fewer infrastructure components.
10. Types of Service Discovery
There are two classic patterns:
- Client-Side Service Discovery
- Server-Side Service Discovery
11. Client-Side Service Discovery
The calling application queries the registry and chooses an instance.
Order Service
│
│ 1. Where is ProductService?
▼
Service Registry
│
│ 2. A, B, C
▼
Order Service
│
│ 3. Select B
▼
Product Instance B
The client/calling service participates directly in discovery and often load balancing.
Advantages
- Caller has direct control.
- Can implement custom selection logic.
- Avoids an additional routing proxy in some designs.
Disadvantages
- Discovery logic becomes part of callers.
- Every service/client may need appropriate discovery integration.
- More coupling to the discovery mechanism.
12. Server-Side Service Discovery
The client sends the request to an intermediary such as a gateway/load balancer/platform service.
Client
│
▼
Gateway / Load Balancer
│
│ Discover ProductService
▼
Service Discovery
│
▼
Product Instance B
The client doesn't directly participate in service discovery.
Advantages
- Simpler clients.
- Discovery logic is centralized/infrastructure-managed.
- Services can remain less aware of the discovery implementation.
Disadvantages
- Additional infrastructure.
- Gateway/load-balancer layer must be highly available.
- Infrastructure configuration becomes important.
13. Common Service Discovery Technologies
Service discovery can be implemented in several ways.
Examples include:
- Kubernetes Services + DNS
- HashiCorp Consul
- Cloud-native service discovery/platform networking
- Service meshes
- Custom service registries
The important point is that modern container platforms often provide service discovery as part of the platform.
14. Kubernetes Example
Kubernetes is a very important example because you often do not need to manually manage changing Pod IP addresses.
Suppose Product Service has three Pods:
Product Pods
10.244.1.10
10.244.2.15
10.244.3.20
These Pod addresses can change.
Kubernetes provides a stable Service abstraction.
Order Service
│
│
▼
product-service
│
├── Product Pod 1
├── Product Pod 2
└── Product Pod 3
The caller can use a stable service/DNS name such as:
http://product-service
instead of:
http://10.244.1.10
Conceptually:
Order Service
│
│ http://product-service
▼
Kubernetes DNS / Service
│
├─────────────┐
▼ ▼
Product Pod 1 Product Pod 2
This is service discovery handled largely by the orchestration platform.
15. Consul Example
Consul is another service-discovery system.
Conceptually:
Product Service
│
│ Register
▼
┌─────────────────┐
│ Consul │
│ │
│ ProductService │
│ → 10.0.0.21 │
│ → 10.0.0.22 │
│ → 10.0.0.23 │
└────────┬────────┘
▲
│ Discover
│
API Gateway
A service registers information such as:
Service Name
Service ID
IP Address
Port
Health Check
Conceptual registration:
{
"Name": "ProductService",
"Address": "10.0.0.21",
"Port": 7001
}
In real implementations, you'd normally use a Consul client/integration package or API rather than manually maintaining this information.
16. Health Checks and Service Discovery
Service discovery becomes much more useful when combined with health checking.
Suppose registry contains:
ProductService
Instance A ✓
Instance B ✓
Instance C ✗
The unhealthy instance should not normally receive traffic.
Flow:
Health Check
│
▼
Service Registry
│
├── A ✓
├── B ✓
└── C ✗
│
▼
Excluded
Gateway/load balancer receives healthy candidates:
A
B
instead of:
A
B
C
17. Service Registration
Another important interview concept is:
How does the registry know that a service exists?
Two common approaches are:
Self-registration
The Microservice registers itself.
Product Service
│
│ Register myself
▼
Service Registry
When it starts:
ProductService
10.0.0.21:7001
is registered.
When it shuts down cleanly, it may deregister.
Health checks/leases are still important because crashed services may not get a chance to deregister cleanly.
Third-party registration
The platform or another component manages registration.
Orchestrator / Registrar
│
▼
Service Registry
The application itself does not need to contain explicit registration code.
Container orchestration platforms commonly move much of this responsibility into infrastructure.
18. What Happens During Autoscaling?
This is one of the main reasons Service Discovery matters.
Initially:
ProductService
Instance 1
Instance 2
Traffic increases.
Autoscaling creates:
Instance 3
Instance 4
Instance 5
Discovery information becomes:
ProductService
Instance 1 ✓
Instance 2 ✓
Instance 3 ✓
Instance 4 ✓
Instance 5 ✓
The gateway/load-balancing infrastructure can start using the new instances without manually changing every calling application.
Later traffic decreases:
Instance 4 removed
Instance 5 removed
Discovery reflects the new available set.
This is much better than maintaining:
{
"Host": "10.0.0.21"
}
manually.
19. Service Discovery with Ocelot
Ocelot can integrate with service discovery providers.
Conceptually, instead of configuring:
"DownstreamHostAndPorts": [
{
"Host": "10.0.0.21",
"Port": 7001
}
]
you configure the route around a service identity and the appropriate discovery provider/integration.
Conceptually:
Ocelot
│
│ ProductService?
▼
Service Discovery Provider
│
├── Instance A
├── Instance B
└── Instance C
│
▼
Load Balancer
│
▼
Selected Instance
The exact Ocelot configuration and NuGet package depend on the discovery provider and Ocelot version, so provider-specific configuration should be verified against that version rather than copied from older examples.
20. Service Discovery with YARP
YARP uses:
Route
↓
Cluster
↓
Destinations
For example:
Product Route
↓
Product Cluster
↓
Destinations
├── Instance A
├── Instance B
└── Instance C
For static configuration:
"Destinations": {
"product1": {
"Address": "https://10.0.0.21:7001/"
},
"product2": {
"Address": "https://10.0.0.22:7001/"
}
}
For dynamic environments, YARP's configuration/extensibility model can be integrated with dynamically supplied destination information rather than requiring a permanently static list.
In Kubernetes, another common approach is simply to route YARP to the stable Kubernetes Service endpoint and let Kubernetes handle Pod discovery/load balancing.
21. Advantages of Service Discovery
1. No hardcoded service addresses
Instead of:
10.0.0.21:7001
applications can work with logical service identities.
2. Supports autoscaling
New instances can become available dynamically.
3. Handles changing addresses
Restarted/redeployed instances can have different locations.
4. Improves availability
Unhealthy instances can be removed from the usable discovery set when health integration is configured correctly.
5. Supports load balancing
Discovery provides the available instances; load balancing can select among them.
6. Reduces configuration maintenance
You don't manually update every caller whenever service topology changes.
7. Important for cloud/container environments
It fits dynamic platforms such as Kubernetes and cloud infrastructure.
22. Disadvantages
1. Additional infrastructure
A registry-based approach introduces another component.
2. More operational complexity
You need to understand registration, deregistration, health checks, caching and failure handling.
3. Registry availability matters
If a central discovery system becomes unavailable and clients have no cached information/fallback strategy, new discovery operations may fail.
4. Stale information
There can be a short delay between an instance failing and the discovery system recognizing that failure.
5. Troubleshooting becomes more complex
Instead of:
A calls B
you may now troubleshoot:
A
↓
Discovery
↓
Load balancing
↓
B
Key Points
For interview revision:
- Service Discovery dynamically locates Microservices.
- It avoids hardcoding IP addresses and ports.
- It is particularly useful when instances are dynamically created and removed.
- A Service Registry stores/discovers available service instances in registry-based designs.
- Services may register themselves or be registered by infrastructure.
- Health checks help identify unhealthy instances.
- Service Discovery and Load Balancing are related but different.
- Discovery finds available instances.
- Load balancing selects an instance.
- There are two classic patterns:
- Client-side discovery
- Server-side discovery
- Kubernetes provides service discovery through mechanisms such as Services and DNS.
- Consul is an example of a dedicated service-discovery technology.
- Ocelot can integrate with supported service-discovery providers.
- YARP can work with dynamic destination configuration or sit in front of platform-provided discovery.
Interview Questions & Answers
Q1. What is Service Discovery?
Answer:
Service Discovery is a mechanism that allows services, gateways, or clients to dynamically locate available instances of another Microservice without hardcoding IP addresses and ports.
Q2. Why do we need Service Discovery?
Answer:
In Microservices environments, service instances can restart, scale up, scale down or move, causing their addresses to change. Service Discovery allows callers to find the currently available instances dynamically.
Q3. What is a Service Registry?
Answer:
A Service Registry maintains information about available service instances, such as service name, address, port and health status.
Example:
ProductService
├── 10.0.0.21:7001
├── 10.0.0.22:7001
└── 10.0.0.23:7001
Q4. What is the difference between Service Discovery and Load Balancing?
Answer:
Service Discovery determines which service instances are available, while Load Balancing determines which available instance should receive a request.
Discovery
↓
A, B, C are available
Load Balancer
↓
Select B
Q5. What is client-side Service Discovery?
Answer:
The calling service directly queries the Service Registry, obtains available instances and participates in selecting the destination.
Q6. What is server-side Service Discovery?
Answer:
The caller sends the request to an intermediary such as a gateway or load balancer, and that infrastructure handles service discovery and destination selection.
Q7. How does Service Discovery work with autoscaling?
Answer:
When new service instances are created, they become discoverable through the registry/platform. When instances are removed or become unhealthy, they are removed from the usable set. This allows traffic to adapt dynamically without manually changing caller configuration.
Q8. Does Kubernetes support Service Discovery?
Yes.
Kubernetes commonly provides stable Service names and DNS so applications can call a service by name rather than directly tracking changing Pod IP addresses.
For example:
http://product-service
rather than:
http://10.244.2.15
Q9. What happens if the Service Registry goes down?
It depends on the implementation. Some clients/gateways can temporarily use cached discovery information, while new discoveries or topology updates may fail. For that reason, discovery infrastructure itself should be designed for high availability.
Q10. Is Service Discovery required for every Microservices application?
No.
For a small/static environment where service endpoints rarely change, static configuration may be sufficient.
Service Discovery becomes much more valuable when using:
Autoscaling
Containers
Kubernetes
Dynamic cloud infrastructure
Multiple service instances
Frequent deployments
Interview-Ready Answer
Service Discovery is a mechanism used in Microservices to dynamically locate available service instances without hardcoding their IP addresses and ports. When services are deployed, restarted or autoscaled, their network locations can change. A service registry or platform discovery mechanism maintains or exposes the currently available instances, and a gateway, load balancer or calling service uses that information to locate the target service. Service Discovery identifies available instances, while Load Balancing selects which instance should receive the request. Kubernetes Services/DNS and Consul are common examples of service-discovery approaches.