Service Discovery and Registration Using Spring Cloud Eureka

unsplash-logoFo Fa

In past few microservices articles, We discuss different Spring Cloud features, Like Config Server , OpenFeign and Ribbon. In this Post, Let’s talk about Spring Cloud Netflix – Eureka.Why we need it ? How to configure the Eureka server , How to register service in Registry Server?

In cloud based microservices environment, Servers come and go. Unlike the traditional architecture which work with servers with well known IP addresses and host names. In cloud platform, It is not possible to know the IP and Host names of services. Also the containers use dynamic IPs for autoscaling moreover Load balancing requires much more sophistication in registering and de-registering servers for balancing.
So we can not have tight coupling between the services based of IP or Host Names. Spring Cloud Netflix – Eureka helps to solve that problem.

The code for this post is available for download here.

In typical Eureka setup we have
Eureka Server: Which acts as service registry.
Eureka Client REST services which registers itself at the registry.

let’s Setup Eureka Server & Client for our demo application.

Demo Application: Our Simple PricingService calculates Price for the Product. Pricing Service gets some dynamic discount details from DiscountService.

Setting Up Eureka Server

To Add Eureka Server in project, we need to use the spring-cloud-starter-netflix-eureka-server artifact id. and use @EnableEurekaServer on main class.
Eureka server can also register it’s self as a Eureka client. For the demo we will disable that using registerWithEureka flag. Eureka Server can be configured to read configuration from Config server that we discuss Here. this property can be set using fetchRegistry flag.

Eureka Server
1
2
3
4
5
6
7
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}

Eureka Server Properties
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#Server Specifics
server:
port: 8761
spring:
application:
name: eureka-server
#Eureka Specifics
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

Start the EurekaServerApplication and you should be able to see Eureka dashboard at http://localhost:8761/

Setting Up Eureka Clients - Discount Service

let’s Setup Discount Service to register with Eureka Server. To include the Eureka Client in project we need to use spring-cloud-starter-netflix-eureka-client artifact ID.Spring Boot will identify the client jar in classpath and will try to register with Server. We can also use @EnableDiscoveryClient to do that. We need to provide information about the Eureka Server, This can be done using serviceUrl property.
Discount service has simple endpoint that returns the discount for product.

Discount Service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@SpringBootApplication
@EnableDiscoveryClient
@Slf4j
public class DiscountServiceApplication {
public static void main(String[] args) {
SpringApplication.run(DiscountServiceApplication.class, args);
}
}
@RestController
@RequestMapping("/discount/{product}")
@Slf4j
class DiscountController{
@GetMapping
public int getDiscountPercentage(@PathVariable("product") String product){
log.info("Getting Discount for Product {}",product);
return 50;
}
}

Discount Service properties
1
2
3
4
5
6
7
8
9
10
11
12
13
spring:
application:
name: discount-service

server:
port: 8081

eureka:
client:
healthcheck:
enabled: true
serviceUrl:
defaultZone: http://localhost:8761/eureka/

Start the DiscountServiceApplication and you should be able to see DiscountService registered on Eureka dashboard http://localhost:8761/
Note Application Name is very important as it is used for server for lookups

Magic of Registry: Calling Service using Registry & Feign

Now Let’s Call DiscountService to calculate price. Now as DiscountService is registered with Registry so we don’t need to know the host details.I have already discusses in details about Feign and how to use to call service in this Post. Feign works with eureka-client and we can call service using application.name. In below code snippet DiscountServiceClient is a FeignClient Which is calling service using registered application name.

Pricing Service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class PricingServiceApplication {
public static void main(String[] args) {
SpringApplication.run(PricingServiceApplication.class, args);
}
}
@RestController
@Slf4j
class ServiceInstanceRestController {
@Autowired
private DiscountServiceClient discountServiceClient;
@GetMapping("/price/{product}")
public Int getPriceForProduct(@PathVariable("product") String product) {
int discount = discountServiceClient.getDiscountPercentage("Test");
int price = 100;
s = 100-discount
log.info("Discount is {}",discount);
return (s*price)/100;
}
}

@FeignClient("discount-service")
interface DiscountServiceClient {
@RequestMapping(method = RequestMethod.GET, value = "/discount/{product}")
int getDiscountPercentage(@PathVariable("product") String product);
}
Pricing Service properties
1
2
3
4
5
6
7
8
9
10
11
12
13
spring:
application:
name: pricing-service

server:
port: 8080

eureka:
client:
healthcheck:
enabled: true
serviceUrl:
defaultZone: http://localhost:8761/eureka/

What about Load Balancing ?

I have already discusses how to use and setup Ribbon for Client-side load balancing in this Post. Feign already uses Ribbon, so, if you use @FeignClient Ribbon will be used along with that. When Eureka is used in conjunction with Ribbon (that is, both are on the classpath), the ribbonServerList is overridden with an extension of DiscoveryEnabledNIWSServerList, which populates the list of servers from Eureka
if we start multiple instances of discount service then Ribbon will discount service in round robin algorithm.

Final Architecture of Application will be like this

The code for this post is available for download here.

Share Comments