Skip to content

Commit 3af4ce5

Browse files
author
Ritika Mathur
committed
feature-server-side-service-discovery
Signed-off-by: Ritika Mathur <ritika.mathur01@ad.infosys.com>
1 parent ede37bd commit 3af4ce5

File tree

35 files changed

+2763
-0
lines changed

35 files changed

+2763
-0
lines changed

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@
215215
<module>service-locator</module>
216216
<module>service-stub</module>
217217
<module>service-to-worker</module>
218+
<module>server-side-service-discovery</module>
218219
<module>session-facade</module>
219220
<module>sharding</module>
220221
<module>single-table-inheritance</module>
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# Server-Side Service Discovery Pattern
2+
3+
## Intent
4+
5+
The Server-Side Service Discovery pattern is a microservice architecture pattern that provides a centralized mechanism for services to register themselves and for consumers to discover available services dynamically. This pattern enhances system scalability and flexibility by decoupling service consumers from the physical locations of service providers.
6+
7+
## Explanation
8+
9+
Real-world example
10+
11+
> Consider a large e-commerce platform with multiple microservices like Product Service, Order Service, Payment Service, and Inventory Service. Instead of hardcoding the network locations of each service, they register themselves with a central Service Registry (like Netflix Eureka). When the Order Service needs to check product availability, it queries the Service Registry to discover available instances of the Product Service. The registry returns healthy instances, and a load balancer distributes the request among them. This approach allows services to scale up/down dynamically, fail gracefully, and be discovered automatically without manual configuration.
12+
13+
In plain words
14+
15+
> Server-Side Service Discovery provides a centralized registry where services register themselves and consumers can discover and communicate with available services dynamically.
16+
17+
Wikipedia says
18+
19+
> Service discovery is the automatic detection of devices and services offered by these devices on a computer network. In the context of microservices, service discovery refers to the mechanism by which services find and communicate with each other.
20+
21+
## Programmatic Example
22+
23+
This implementation demonstrates the Server-Side Service Discovery pattern using Spring Cloud Netflix Eureka. The example includes:
24+
25+
### 1. Service Registry (Eureka Server)
26+
27+
```java
28+
@SpringBootApplication
29+
@EnableEurekaServer
30+
public class ServiceRegistryApp {
31+
public static void main(String[] args) {
32+
SpringApplication.run(ServiceRegistryApp.class, args);
33+
}
34+
}
35+
```
36+
37+
### 2. Service Providers (Product Service & Order Service)
38+
39+
```java
40+
@SpringBootApplication
41+
@EnableEurekaClient
42+
public class ProductServiceApp {
43+
public static void main(String[] args) {
44+
SpringApplication.run(ProductServiceApp.class, args);
45+
}
46+
}
47+
```
48+
49+
### 3. Service Consumer with Load Balancing
50+
51+
```java
52+
@Configuration
53+
public class ServiceConsumerConfig {
54+
@Bean
55+
@LoadBalanced
56+
public RestTemplate restTemplate() {
57+
return new RestTemplate();
58+
}
59+
}
60+
61+
@Service
62+
public class ServiceDiscoveryService {
63+
private final RestTemplate restTemplate;
64+
private final EurekaClient eurekaClient;
65+
66+
public String callService(String serviceName, String endpoint) {
67+
try {
68+
String serviceUrl = "http://" + serviceName + endpoint;
69+
return restTemplate.getForObject(serviceUrl, String.class);
70+
} catch (Exception e) {
71+
return "Error calling service: " + e.getMessage();
72+
}
73+
}
74+
}
75+
```
76+
77+
## Key Components
78+
79+
### Service Registry
80+
- **Purpose**: Central repository for service instance information
81+
- **Implementation**: Netflix Eureka Server
82+
- **Features**: Service registration, health monitoring, instance management
83+
84+
### Service Provider
85+
- **Purpose**: Services that register themselves with the registry
86+
- **Examples**: Product Service, Order Service
87+
- **Features**: Auto-registration, health checks, graceful shutdown
88+
89+
### Service Consumer
90+
- **Purpose**: Applications that discover and consume services
91+
- **Features**: Service discovery, load balancing, fault tolerance
92+
- **Implementation**: Uses Eureka Client and Spring Cloud LoadBalancer
93+
94+
### Load Balancer
95+
- **Purpose**: Distributes requests among available service instances
96+
- **Implementation**: Spring Cloud LoadBalancer
97+
- **Strategies**: Round-robin, random, weighted
98+
99+
## Running the Example
100+
101+
### Prerequisites
102+
- Java 21+
103+
- Maven 3.8+
104+
105+
### Step 1: Start the Service Registry
106+
```bash
107+
cd service-registry
108+
mvn spring-boot:run
109+
```
110+
The Eureka dashboard will be available at: http://localhost:8761
111+
112+
### Step 2: Start Service Providers
113+
```bash
114+
# Terminal 1 - Product Service
115+
cd product-service
116+
mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=8081 --spring.application.name=product-service"
117+
118+
# Terminal 2 - Order Service
119+
cd order-service
120+
mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=8082 --spring.application.name=order-service"
121+
```
122+
123+
### Step 3: Start Service Consumer
124+
```bash
125+
cd service-consumer
126+
mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=8080 --spring.application.name=service-consumer"
127+
```
128+
129+
### Step 4: Test the Pattern
130+
```bash
131+
# Discover all services
132+
curl http://localhost:8080/api/services
133+
134+
# Get products through service discovery
135+
curl http://localhost:8080/api/products
136+
137+
# Get orders through service discovery
138+
curl http://localhost:8080/api/orders
139+
140+
# Check service health
141+
curl http://localhost:8080/api/services/product-service/health
142+
```
143+
144+
## Pattern Benefits
145+
146+
1. **Dynamic Service Discovery**: Services can be discovered at runtime without hardcoded configurations
147+
2. **Load Balancing**: Automatic distribution of requests across available instances
148+
3. **Fault Tolerance**: Failed instances are automatically removed from the registry
149+
4. **Scalability**: New service instances are automatically discovered and included
150+
5. **Health Monitoring**: Only healthy services participate in request handling
151+
6. **Decoupling**: Services are decoupled from physical network locations
152+
153+
## Pattern Drawbacks
154+
155+
1. **Single Point of Failure**: Service registry becomes critical infrastructure
156+
2. **Network Overhead**: Additional network calls for service discovery
157+
3. **Complexity**: Adds operational complexity to the system
158+
4. **Consistency**: Potential delays in service registry updates
159+
5. **Network Partitions**: Service registry unavailability affects all services
160+
161+
## Related Patterns
162+
163+
- **Client-Side Service Discovery**: Service consumers are responsible for discovering services
164+
- **Circuit Breaker**: Provides fault tolerance when calling discovered services
165+
- **API Gateway**: Often combined with service discovery for external access
166+
- **Health Check**: Essential for maintaining accurate service registry information
167+
168+
## Credits
169+
170+
- [Microservices Patterns by Chris Richardson](https://microservices.io/patterns/service-registry.html)
171+
- [Spring Cloud Netflix Documentation](https://spring.io/projects/spring-cloud-netflix)
172+
- [Building Microservices by Sam Newman](https://samnewman.io/books/building_microservices/)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Order Service Configuration for Server-Side Service Discovery
2+
3+
# Server Configuration
4+
server.port=8082
5+
spring.application.name=order-service
6+
7+
# Eureka Client Configuration
8+
eureka.client.service-url.default-zone=http://localhost:8761/eureka/
9+
eureka.client.register-with-eureka=true
10+
eureka.client.fetch-registry=true
11+
eureka.instance.prefer-ip-address=true
12+
eureka.instance.lease-renewal-interval-in-seconds=10
13+
eureka.instance.lease-expiration-duration-in-seconds=30
14+
15+
# Health Check Configuration
16+
management.endpoints.web.exposure.include=health,info,metrics
17+
management.endpoint.health.show-details=always
18+
19+
# Logging Configuration
20+
logging.level.com.netflix.eureka=DEBUG
21+
logging.level.com.netflix.discovery=DEBUG
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
5+
6+
The MIT License
7+
Copyright © 2014-2022 Ilkka Seppälä
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in
17+
all copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
THE SOFTWARE.
26+
27+
-->
28+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
29+
<parent>
30+
<artifactId>server-side-service-discovery</artifactId>
31+
<groupId>com.iluwatar</groupId>
32+
<version>1.26.0-SNAPSHOT</version>
33+
</parent>
34+
<modelVersion>4.0.0</modelVersion>
35+
<artifactId>order-service</artifactId>
36+
<packaging>jar</packaging>
37+
38+
<dependencies>
39+
<dependency>
40+
<groupId>org.springframework.boot</groupId>
41+
<artifactId>spring-boot-starter-web</artifactId>
42+
</dependency>
43+
<dependency>
44+
<groupId>org.springframework.boot</groupId>
45+
<artifactId>spring-boot-starter-actuator</artifactId>
46+
</dependency>
47+
<dependency>
48+
<groupId>org.springframework.cloud</groupId>
49+
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
50+
<version>4.1.3</version>
51+
</dependency>
52+
<dependency>
53+
<groupId>org.junit.jupiter</groupId>
54+
<artifactId>junit-jupiter-engine</artifactId>
55+
<scope>test</scope>
56+
</dependency>
57+
<dependency>
58+
<groupId>org.mockito</groupId>
59+
<artifactId>mockito-core</artifactId>
60+
<scope>test</scope>
61+
</dependency>
62+
</dependencies>
63+
64+
<build>
65+
<plugins>
66+
<plugin>
67+
<groupId>org.springframework.boot</groupId>
68+
<artifactId>spring-boot-maven-plugin</artifactId>
69+
<version>3.4.4</version>
70+
<executions>
71+
<execution>
72+
<goals>
73+
<goal>repackage</goal>
74+
</goals>
75+
</execution>
76+
</executions>
77+
</plugin>
78+
<plugin>
79+
<groupId>org.apache.maven.plugins</groupId>
80+
<artifactId>maven-assembly-plugin</artifactId>
81+
<executions>
82+
<execution>
83+
<configuration>
84+
<archive>
85+
<manifest>
86+
<mainClass>com.iluwatar.orderservice.OrderServiceApp</mainClass>
87+
</manifest>
88+
</archive>
89+
</configuration>
90+
</execution>
91+
</executions>
92+
</plugin>
93+
</plugins>
94+
</build>
95+
</project>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
3+
*
4+
* The MIT License
5+
* Copyright © 2014-2022 Ilkka Seppälä
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
26+
package com.iluwatar.orderservice;
27+
28+
import org.springframework.boot.SpringApplication;
29+
import org.springframework.boot.autoconfigure.SpringBootApplication;
30+
31+
/**
32+
* Order Service Application that registers itself with the Service Registry.
33+
* This demonstrates another Service Provider component of the Server-Side Service Discovery pattern.
34+
*/
35+
@SpringBootApplication
36+
public class OrderServiceApp {
37+
38+
/**
39+
* Main method to start the Order Service application.
40+
*
41+
* @param args command line arguments
42+
*/
43+
public static void main(String[] args) {
44+
SpringApplication.run(OrderServiceApp.class, args);
45+
}
46+
}

0 commit comments

Comments
 (0)