This blog mark the beginning of a new series focused entirely on the Microservice design pattern.
In this series we will see how Microservice design pattern are used to overcome the challenges in the distriubuted environment.
๐ซ Challenges :-
How to locate service when host changes(IP address) as service get updated or scaled in cloud environment. [Eureka server]
How to identify available service instance to make the request [Load balancer]
How to identify certain information about the microservice [Actuators]
How to identify latency causing service in request life cycle [Distributed Tracking]
How to provide single point of entry for authentication & authorization [API Gateway]
How to make external configuration for common properties [Config server]
How to avoid cascading or repeated failure [Circuit Breaker]
How to perform analysis of log [Centralized logging]
How to secure spring application [Spring security & OAuth 2.0]
๐ What This Part Covers:
- Why service discovery is mandatory in production
- Why a single Eureka server is not enough
- How microservices register themselves using logical names
- How this eliminates hardcoded IPs and ports
What Is a Service Registry?
A Service Registry is a centralized system that keeps track of all running microservice instances in a distributed system.
Instead of services communicating using fixed IP addresses and ports, they:
- Register themselves with the registry
- Discover other services dynamically using logical names
๐ In Spring Cloud, Eureka acts as the Service Registry.
Why Start with Eureka?
Before gateway, security or scaling:
Services must be able to find each other reliably.
Eureka server is service discovery and registration design implementation.
Why Service Discovery Is Mandatory in Production
In real production systems:
- Services scale dynamically
- Instances come and go
- IPs and ports must never be hardcoded
- Load balancing must be automatic
- Failure of one node must not break the system
Hardcoding endpoints like:
โ breaks scaling
โ breaks failover
โ tightly couples services
## High level Flow
๐ Example Flow: Order Service โ User Service
Weโll use:
- user-service
- order-service
- Eureka Server
โ Step 1: Problem (Without Service Discovery)
Hardcoded communication
Order Service calling User Service:
@RestController
public class OrderController {
@GetMapping("/order")
public String getOrder() {
RestTemplate restTemplate = new RestTemplate();
// โ Hardcoded URL
String user = restTemplate.getForObject(
"http://localhost:8081/user", String.class
);
return "Order created for " + user;
}
}
โ Step 2: Introduce Eureka Server
1. Add Dependency
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2. Enable Eureka Server
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
What does @EnableEurekaServer do?
- Turns a Spring Boot application into a Service Registry
- Accepts service registrations from microservices
- Tracks heartbeats to detect unhealthy instances
3. ๐ง Eureka Server (application.properties)
server.port=8761
spring.application.name=eureka-server
# Disable self-registration
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
๐ Step 3: Register Services to Eureka
In user-service
Dependency
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
User-service : application.properties
spring.application.name=USER-SERVICE
server.port=8081
# Register to Eureka
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
In order-service
spring.application.name=ORDER-SERVICE
server.port=8082
# Register to Eureka
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
๐ Step 4: Eureka in Action
USER-SERVICE registers itself
ORDER-SERVICE registers itself
Eureka keeps track of all instances
๐ฅ Step 5: Service Discovery (No Hardcoding)
Use Service Name Instead of URL
@RestController
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/order")
public String getOrder() {
// โ
Using service name instead of hardcoded URL
**String user = restTemplate.getForObject(
"http://USER-SERVICE/user", String.class
);**
return "Order created for " + user;
}
}
Step 6: Add Load Balancing
Config
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
Why @LoadBalanced ?
@LoadBalanced enables:
- Service name resolution
- Instance lookup from Eureka
- Client-side load balancing
๐ Now if multiple USER-SERVICE instances exist:
Eureka + LoadBalancer distributes traffic automatically
๐งช Step 7: Scale It
Run:
USER-SERVICE โ port 8081
USER-SERVICE โ port 8083 (second instance)
๐ Eureka will show:
USER-SERVICE (2 instances)
๐ Calls from ORDER-SERVICE will:
Automatically load balance ๐ฏ
Why This Architecture Is Production-Grade
- No hardcoded IPs or ports
- Automatic scaling
- High availability
- Fault tolerance
- Clean separation of concerns
- Gateway + Nginx hide internal topology
๐ง Final Flow Summary
1. Client โ ORDER-SERVICE
2. ORDER-SERVICE โ Eureka (Where is USER-SERVICE?)
3. Eureka โ Returns available instances
4. ORDER-SERVICE โ Calls USER-SERVICE
5. Response โ Client
Summary
- Eureka provides service discovery
- @EnableEurekaServer creates the registry
- @LoadBalanced RestTemplate enables dynamic routing
- Services communicate using logical names
- Scaling requires no code changes

Top comments (0)