Load Balancing Services with Eureka (2024) | TechGeekNext


Load Balancing Services with Eureka Example


What is Load Balancing?

Load balancing means efficient distribution of incoming network traffic across a backend servers. It distributes client requests or network traffic efficiently across multiple servers.

Eureka Load Balancing In Action

Eureka is a REST (Representational State Transfer) based service that is primarily used in the AWS cloud to locate services for load balancing and failure of middle-tier servers.

Eureka Load Balancing Flow

Eureka Load Balancing Flow

Eureka Server - Project Structure

Let's begin with creating Eureka Server and then will create services called Ticket Rate Service and it's UI Service.
Eureka Load Balancing Project Structure

Create Spring Boot Eureka Server Project

Create Spring Boot Project from Spring Initializer site https://start.spring.io/. Create Eureka Server

pom.xml

If you see, we added spring-cloud-starter-eureka-server dependencies in pom.xml.
<?xml version="1.0" encoding="UTF-8"?>
<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">
	<modelVersion>4.0.0</modelVersion>

	<groupId>techgeeknext.eureka.server</groupId>
	<artifactId>techgeeknext-eureka-server</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>techgeeknext-eureka-server</name>
	<description>Demo project for Spring Cloud Eureka</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.1.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<spring-cloud.version>Dalston.SR1</spring-cloud.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka-server</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-actuator</artifactId>
		</dependency>
	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

Properties

We don't want this service to register with Eureka, because this a Eureka Server, so make register-with-eureka flag false.
# set port
server.port=8761
# no need to register the server with the server
eureka.client.register-with-eureka=false
# don't need a local copy of the registry
eureka.client.fetch-registry=false

# value used for AWS, here can be anything
eureka.datacenter=techgeeknext-datacenter
eureka.environment=dev

Main Class

Add @EnableEurekaServer annotation in the main class to denote this service as Eureka Server.
package techgeeknext.eureka.server;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class TechgeeknextEurekaServerApplication {

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

Testing Eureka in Dashboard

Run this application, and goto http://localhost:8761/, and you can see Eureka Server up and running without any services register. Testing Eureka Server In this tutorial, will create two services called rate-service and other service to display rates from rate-service using Eureka Load Balancing. Let's start creating services.

techgeeknext-eureka-rate-service

Define your service name in bootstrap.properties
spring.application.name=techgeeknext-rate-service

Properties

Register this service as a client in Eureka Server.
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=false

eureka.instance.hostname=localhost

eureka.instance.instance-id=${spring.application.name}:${random.int}

eureka.client.healthcheck.enabled=true

server.port=0

pom.xml
Add spring-cloud-starter-netflix-eureka-client dependencies.
<?xml version="1.0" encoding="UTF-8"?>
<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">
	<modelVersion>4.0.0</modelVersion>

	<groupId>techgeeknext.rate</groupId>
	<artifactId>techgeeknext-eureka-rate-service</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>techgeeknext-eureka-rate-service</name>
	<description>Demo project for Spring Cloud Eureka</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.1.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<java.version>1.8</java.version>
		<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

Main class
We're going to add an annotation to the primary class so it's actually a client and pulls down that registry Add @EnableEurekaClient annotation to declare this service as Eureka Client.
package techgeeknext.rate;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@EnableEurekaClient
@SpringBootApplication
public class TechgeeknextEurekaRateServiceApplication {

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

Controller

Create Rest End point called GetTicketRate with the url /rate/{stationId}.
package techgeeknext.rate;

import java.math.BigDecimal;
import java.time.Instant;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TicketRateController {

	@RequestMapping("/rate/{stationId}")
	public TicketRate GetTicketRate(@PathVariable int stationId) {

		TicketRate ticketRate;

		System.out.println("Station Id : " + stationId);

		switch(stationId) {
		case 1:
			ticketRate = new TicketRate(stationId, new BigDecimal("0.32"), Instant.now().toString());
			break;
		case 2:
			ticketRate = new TicketRate(stationId, new BigDecimal("1.02"), Instant.now().toString());
			break;
		case 3:
			ticketRate = new TicketRate(stationId, new BigDecimal("0.40"), Instant.now().toString());
			break;
		default:
			ticketRate = new TicketRate(stationId, new BigDecimal("1.00"), Instant.now().toString());
			break;
		}

		return ticketRate;
	}
}

Testing Rate Service in Eureka Dashboard

Run this application, and goto http://localhost:8761/, and you can see rate services got register with Eureka Server. Testing Services in Eureka Server
Open and click on the register service and append the url parameter as given below. Rate Service

techgeeknext-eureka-rate-display

Define your service name in bootstrap.properties
spring.application.name=techgeeknext-rate-display-UI

Properties

Register this service as a client in Eureka Server.
server.port=8081
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
eureka.instance.instance-id=${spring.application.name}:${random.int}

pom.xml
Add spring-cloud-starter-netflix-eureka-client dependencies.
<?xml version="1.0" encoding="UTF-8"?>
<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">
	<modelVersion>4.0.0</modelVersion>

	<groupId>techgeeknext.rate</groupId>
	<artifactId>techgeeknext-eureka-rate-display</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>techgeeknext-eureka-rate-display</name>
	<description>Demo project for Spring Cloud Eureka Load Balancing</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.1.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

<properties>
		<java.version>1.8</java.version>
		<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

Main class
Add @EnableEurekaClient annotation to declare this service as Eureka Client.
package techgeeknext.rate;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@EnableEurekaClient
@SpringBootApplication
public class TechgeeknextEurekaRateDisplayApplication {

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

Controller

Create Rest End point called GetTicketRate with the url /dashboard. You can Load Balanced the RestTemplate using @LoadBalanced annotation. So it's actually going to use that information from the registry to figure out where to call the service. We have used techgeeknext-rate-service service registered in the eureka.
package techgeeknext.rate;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;

@Controller
public class RateController {

	@LoadBalanced
	@Bean
	public RestTemplate restTemplate(RestTemplateBuilder builder) {
		return builder.build();
	}

	@Autowired
	private RestTemplate restTemplate;

	@RequestMapping("/dashboard")
	public String GetTicketRate(@RequestParam int stationId, Model m) {

		TicketRate tr = restTemplate.getForObject("http://techgeeknext-rate-service/rate/" + stationId, TicketRate.class);
		m.addAttribute("rate", tr.getCurrentRate());
		return "dashboard";
	}
}

Testing Rate Service in Eureka Dashboard

Run this application, and goto http://localhost:8761/, and you can see rate services got register with Eureka Server. Testing Services in Eureka Server

Testing Load balancing Rate Service using Eureka

Goto http://localhost:8081/dashboard?stationId=2 (techgeeknext-rate-display-UI) url as given below and you can see it's fetching ticket rate from ticket rate service (techgeeknext-rate-service) using service registered in Eureka. Rate Service

Download Source Code

The full source code for this article can be found on below.
Download it here - Load Balancing Services With Eureka







Recommendation for Top Popular Post :