← Home

Part 1 : Peer Aware Eureka Service Registry

29 January, 2026


New Series: Spring Cloud Microservice Architecture
(Service Discovery Β· Gateway Β· Nginx Β· Production Patterns)

This blog marks the beginning of a new series focused entirely on Spring Cloud–based microservice architecture and production-grade system design.

In this series, we will design and evolve a complete microservices ecosystem using:


About the Order System Used in This Series

To avoid reinventing the wheel, this series reuses an existing microservice from my earlier work:

πŸ‘‰ Production-Grade Spring Boot API Design : Part 1 : Web, JPA & What Really Happens at Startup

The order-system from that series is used only as a sample business service so we can focus purely on:

πŸ“Œ This Spring Cloud series is completely independent and does not require reading the previous series, although familiarity with the order-system API helps.

Source Code:


What This Part Covers

This Part 1 focuses on:


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:

πŸ“Œ In Spring Cloud, Eureka acts as the Service Registry.


Why Start with Eureka?

Before gateways, security, or scaling:

Services must be able to find each other reliably.

That is exactly what Eureka Service Registry solves β€” and it’s the foundation of every production-grade Spring Cloud system.


Let’s Begin πŸš€

In the next sections, we’ll set up a 3-node peer-aware Eureka cluster and use it as the backbone for all service communication in the system.


Why Service Discovery Is Mandatory in Production

In real production systems:

Hardcoding endpoints like:

http://localhost:8080/orders

❌ breaks scaling
❌ breaks failover
❌ tightly couples services


High-Level Architecture

Client
↓
Nginx (Reverse Proxy & LB)
↓
Spring Cloud Gateway (multiple instances)
↓
Eureka Cluster (3 peer-aware nodes)
↓
Order System (multiple instances)

Existing Order System

From the earlier series, the order-system already exposes:

GET http://localhost:8085/orders

{
  "status": 200,
  "message": "All orders fetch successfully",
  "data": [
    { "id": 1, "productName": "Mobile" },
    { "id": 2, "productName": "Mobile" },
    { "id": 3, "productName": "Mobile" },
    { "id": 4, "productName": "Smartwatch" }
  ],
  "errors": null
}

Now we make this production-grade using service discovery.

Step 1: Peer-Aware Eureka Service Registry (3 Nodes)

Why Peer-Aware Eureka?

πŸ‘‰ Minimum recommended: 3 nodes


Eureka Server Configuration

properties

spring.application.name=eureka-server
server.port=8760

eureka.client.service-url.defaultZone=\
http://EurekaInstance1IP:8760/eureka,\
http://EurekaInstance2IP:8761/eureka,\
http://EurekaInstance3IP:8762/eureka

eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true

Step 1: Peer-Aware Eureka Service Registry (3 Nodes)

Why Peer-Aware Eureka?

πŸ‘‰ Minimum recommended: 3 nodes


Eureka Server Configuration

spring.application.name=eureka-server
server.port=8760

eureka.client.service-url.defaultZone=\
http://EurekaInstance1IP:8760/eureka,\
http://EurekaInstance2IP:8761/eureka,\
http://EurekaInstance3IP:8762/eureka

eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true

Note:
This configuration represents one Eureka server instance.

For a peer-aware Eureka cluster, create multiple Eureka applications (for example, 3 instances) and modify:

so that each Eureka node points to all other Eureka nodes using their respective IPs and ports.

Eureka Server Application

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

What does @EnableEurekaServer do?

Step 2: Register Order System with Eureka

Order System Configuration

spring.application.name=order-system

eureka.client.service-url.defaultZone=\
http://localhost:8760/eureka,\
http://localhost:8761/eureka,\
http://localhost:8762/eureka

eureka.instance.prefer-ip-address=true

Result

ORDER-SYSTEM β†’ [instance-1, instance-2, instance-3]

Step 3: Create Order Consumer Microservice

This service consumes order-system data without knowing:

What Is RestTemplate?

RestTemplate is Spring’s synchronous HTTP client used for REST calls.

By default:

Why @LoadBalanced ?

@LoadBalanced enables:

Load-Balanced RestTemplate Configuration

@Configuration
public class RestConfig {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

Order Consumer Controller

@RestController
@RequestMapping("/consume")
public class OrderConsumerController {

    private final RestTemplate restTemplate;

    public OrderConsumerController(RestTemplate restTemplate){
        this.restTemplate = restTemplate;
    }

    @GetMapping("/orders")
    public String fetchOrders() {
        return restTemplate.getForObject(
                "http://order-system/orders",
                String.class
        );
    }
}

Key Point http://order-system/orders

βœ” No IP

βœ” No port

βœ” Logical service name

βœ” Resolved dynamically via Eureka

Order Consumer Configuration

spring:
  application:
    name: order-consumer

server:
  port: 8090

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8760/eureka, http://localhost:8761/eureka, http://localhost:8762/eureka
  instance:
    prefer-ip-address: true

Step 4: Service-to-Service Call

GET http://localhost:8090/consume/orders

What Happens Internally?

  1. Consumer calls http://order-system/orders
  2. @LoadBalanced RestTemplate intercepts the call
  3. Eureka returns all registered order-system instances
  4. One instance is selected
  5. Request is forwarded
  6. Response is returned

βœ” Load balanced

βœ” Fault tolerant

βœ” Zero hardcoding

Why This Architecture Is Production-Grade

Summary