Spring Cloud+eureka+feign for microservices and load balancing

In this example, we use eureka and feign to build a simple distributed system based on microservices under the spring boot cloud framework. The service system has only four modules, namely four micro services:

Two production modules, ProviderModule and ProviderModule2, simulate service providers, such as order services;

One InvokeModule calls two production modules to simulate service consumption.

A registration service module, Eureka server module, is used to provide registration and discovery of microservices.

eureka is used for system service registration and discovery. Feign is called remotely, and feign integrates load balancing function. The specific implementation steps and codes are as follows.

The project name is service Eureka feign. There are four modules (subprojects) below, and the structure is shown in the figure below

 

The pom.xml of the main project is as follows

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.springframework</groupId>
    <artifactId>service-eureka-feign</artifactId>
    <version>0.1.0</version>
    <packaging>pom</packaging> 

    <modules>
	    <module>InvokerModule</module>
    	<module>ProviderModule</module>
    	<module>ProviderModule2</module>
    	<module>eurekaServerModule</module>
    </modules>
</project>

(1) eurekaServerModule module  

  Key dependency packages in pom.xml

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

  application.properties configuration file

server.port=8761
spring.application.name=server
eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

  Start class EurekaServerApplication  

package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {

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

(2) Service provider module

pom.xml

         <groupId>my.com</groupId>
	     <artifactId>ProviderModule</artifactId>
	     <version>0.0.1-SNAPSHOT</version>
	    <name>ProviderModule</name>
	    <description>ProviderModule</description>
        <dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>		
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-openfeign</artifactId>
		</dependency>

configuration file   application.properties

server.port=9000
spring.application.name=provider
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

Start class ProviderApp  

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@EnableEurekaClient
@SpringBootApplication
public class ProviderApp {
	public static void main(String[] args) {
		SpringApplication.run(ProviderApp.class, args);
	}
}

The service provider class is ProviderController. The controller is used to model the interface provided. The service provider method is showProvider()

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
class ProviderController {

	@RequestMapping("/list/provider")
	public String showProvider(@RequestParam String name) {
		System.out.println("from provider port 9000");
		return "hello "+name + " from provider ";
	}
	
	@RequestMapping("/list/test/{name}")
	public String showTest(@PathVariable String name) {
		return "hello 2 "+name;
	}
}

(3) Service provider module ProviderModule2

This module is very similar to the java code of ProviderModule, except that the configuration file is different from pom.xml

pom.xml

    <groupId>my.com</groupId>
	<artifactId>ProviderModule2</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>ProviderModule2</name>
	<description>ProviderModule2</description>
       <dependency>
		 <groupId>org.springframework.cloud</groupId>
		 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>		
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-openfeign</artifactId>
		</dependency>

configuration file   application.properties

server.port=9002
spring.application.name=provider #The name is the same as that of the first service providing module, which is convenient for feign to call uniformly
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

Service provider class ProviderController. Note that this method is very similar to the ProviderController method in ProviderModule. Generally speaking, similar functions should be improved, such as ticket ordering service, but the resources involved in accessing are different, such as accessing different databases.

@RestController
class ProviderController {

	@RequestMapping("/list/provider")
	public String showProvider(@RequestParam String name) {
		System.out.println("from provider2 port 9002");
		return "hello "+name + " from provider2 ";
	}
	
	@RequestMapping("/list/test/{name}")
	public String showTest(@PathVariable String name) {
		return "hello 2 "+name;
	}
}

  (4) Service consumer module InvokeModule

 pom.xml

	<groupId>com.example</groupId>
	<artifactId>InvokeModule</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>InvokeModule</name>
	<description>InvokeModule</description>
     <dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-openfeign</artifactId>
		</dependency>

configuration file   application.properties  

server.port=8000
spring.application.name=invoker
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

Start class InvokerAPP

@EnableFeignClients
@EnableEurekaClient
@SpringBootApplication
public class InvokerAPP {
	public static void main(String[] args) {
		SpringApplication.run(InvokerAPP.class, args);
	}
}

Remote service call interface (feign call). The service name registered in eureka is "PROVIDER"  , There are two service providers with the same name.

@FeignClient("PROVIDER") //Open Feign client. PROVIDER is the serviceId of two ProviderModule and ProviderModule2 microservices
public interface FeignService {
    //Corresponding to the request method of ProviderModule and ProviderModule2 micro service control layer to be called
    @RequestMapping("/list/provider")
    String getUser(@RequestParam String name);
}

Use the remote interface call, and use the controller to simulate calling feign remote call interface  . Called 10 times with loop simulation.

@RestController
public class InvokerController {
	@Autowired
	private FeignService feignService;

	@RequestMapping("/feign")
	public String testInvoke(@RequestParam String name) {

        String result = "";
        //Call user micro service 10 times
        for (int i = 1; i <= 10; i++) {
        	//Call to define Feign client method
            System.out.println(i);
            result = feignService.getUser("invoker "+name);		
        }
        return result;
	}
}

Start test:

Start eurekaServerModule, ProviderModule, ProviderModule2 and InvokerModule respectively. Enter the eureka server address in the browser: http://localhost:8761/ , the following results are obtained.

 

In the figure above, there are two provider services with the same name in the eureka server.  

Enter the calling address in the browser http://localhost:8000/feign?name= Zhang San , there are the following outputs

 

The above figure outputs the results returned to the browser  

   Console output of ProviderModule module

  Console output of ProviderModule2 module

 

As can be seen from the above two figures,   InvokerModule called a total of 10 services with the same name PROVIDER. These 10 services were evaluated and allocated to two microservice providing modules, which played a role in load balancing.

Complete project code address: link: https://pan.baidu.com/s/1UzoktQkFieMQ4Tm-tydhkA  
Extraction code: 72sy

 

 

 

 

 

 

 

 

 

 

 

 

Tags: Spring Microservices eureka

Posted on Wed, 13 Oct 2021 09:41:51 -0400 by Aro