Spring cloud eureka feign ribbon

Ribbon provides a client-side load balancing technology that communicates with services in the cluster. Contains three components
  • Rule A logical component used to determine which service to get from the list of services
  • Ping a component that runs in the background to determine if a service is available
  • ServerList A background thread that refreshes and filters services at a specific frequency, either static or dynamic


These components can be set either through the API or in the configuration file and created through reflection.

1. Common rules
  • RoundRobinRule This strategy selects services through a simple round-robin strategy, often used as a default strategy or a fallback strategy for advanced strategies
  • AvailabilityFilteringRule This strategy will skip server instances that are considered disconnected or have high concurrent connections.
  • WeightedResponseTimeRule This strategy obtains a weight by using the average response time of the service. The longer the response time, the smaller the weight. According to the weight, a strategy is randomly selected.


  • 2.ServerList
  • Adhoc static server list Use BaseLoadBalancer.setServersList() API to set a static service list
  • The default ServerList implementation of ConfigurationBasedServerList can be set in the following ways
  • sample-client.ribbon.listOfServers=www.microsoft.com:80,www.yahoo.com:80,www.google.com:80
  • DiscoveryEnabledNIWSServerList The ServerList implementation method obtains the service list from the Eureka client. In the spring boot program, when the corresponding jar of Eureka exists in the classpath, this strategy will be adopted by default.

  • 3.ServerListFilter
    This component is a component used by DynamicServerListLoadBalancer to filter services in ServerList. There are two implementations as follows
  • ZoneAffinityServerListFilter filters out those services that are not in the same zone as the client, unless there is no server available in the zone where the client is located, which can be enabled in the following ways
  • myclient.ribbon.EnableZoneAffinity=true
  • ServerListSubsetFilter This filter ensures that clients can only access a specific subset of the service set, and can periodically replace unusable services, which can be enabled in the following ways
  • myClient.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
    # the server must register itself with Eureka server with VipAddress "myservice"
    myClient.ribbon.DeploymentContextBasedVipAddresses=myservice
    myClient.ribbon.NIWSServerListFilterClassName=com.netflix.loadbalancer.ServerListSubsetFilter
    # only show client 5 servers. default is 20.
    myClient.ribbon.ServerListSubsetFilter.size=5
    




    example
  • 1. Eureka server
  • The core is to add the spring-cloud-starter-eureka-server dependency to the normal Spring boot program, and add the @EnableEurekaServer annotation to the startup class
  • Code structure:



  • startup class
  • package hello;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    @EnableEurekaServer
    @SpringBootApplication
    public class EurekaServiceApplication {
        
        public static void main(String[] args) {
            SpringApplication.run(EurekaServiceApplication.class, args);
        }
    }
    
    

  • pom file
  • <?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>com.example</groupId>
    	<artifactId>eureka-service</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<packaging>jar</packaging>
    
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>1.5.1.RELEASE</version>
    		<relativePath/> <!-- lookup parent from repository -->
    	</parent>
    
    	<properties>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<java.version>1.8</java.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>
    	</dependencies>
    
    	<dependencyManagement>
    		<dependencies>
    			<dependency>
    				<groupId>org.springframework.cloud</groupId>
    				<artifactId>spring-cloud-dependencies</artifactId>
    				<version>Camden.SR5</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>
    
    	<repositories>
    		<repository>
    			<id>spring-snapshots</id>
    			<name>Spring Snapshots</name>
    			<url>https://repo.spring.io/libs-snapshot</url>
    			<snapshots>
    				<enabled>true</enabled>
    			</snapshots>
    		</repository>
    	</repositories>
    
    </project>
    
    

  • Application configuration information
  • server.port=8761
    
    eureka.client.register-with-eureka=false
    eureka.client.fetch-registry=false
    
    logging.level.com.netflix.eureka=OFF
    logging.level.com.netflix.discovery=OFF
    

  • 2. Eureka client (ie user server side)
  • The core is to add the spring-cloud-starter-eureka dependency to the normal Spring boot program, and add the @EnableDiscoveryClient annotation to the startup class
  • Code structure:



  • startup class
  • package hello;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Random;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @EnableDiscoveryClient
    @SpringBootApplication
    public class SayHelloApplication {
    
      private static Logger log = LoggerFactory.getLogger(SayHelloApplication.class);
    
      @RequestMapping(value = "/greeting")
      public String greet() {
        log.info("Access /greeting");
    
        List<String> greetings = Arrays.asList("Hi there", "Greetings", "Salutations");
        Random rand = new Random();
    
        int randomNum = rand.nextInt(greetings.size());
        return greetings.get(randomNum);
      }
    
      public static void main(String[] args) {
        SpringApplication.run(SayHelloApplication.class, args);
      }
    }
    
    

  • pom file
  • <?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>hello</groupId>
    	<artifactId>say-hello</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<packaging>jar</packaging>
    
    	<name>say-hello</name>
    	<description>Demo project for Spring Boot</description>
    
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>1.5.1.RELEASE</version>
    		<relativePath /> <!-- lookup parent from repository -->
    	</parent>
    	<dependencyManagement>
    		<dependencies>
    			<dependency>
    				<groupId>org.springframework.cloud</groupId>
    				<artifactId>spring-cloud-dependencies</artifactId>
    				<version>Camden.SR5</version>
    				<type>pom</type>
    				<scope>import</scope>
    			</dependency>
    		</dependencies>
    	</dependencyManagement>
    
    	<properties>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<java.version>1.8</java.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</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-starter-actuator</artifactId>
    		</dependency>
    
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-starter-eureka</artifactId>
    		</dependency>
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    		</plugins>
    	</build>
    
    
    </project>
    
    
    

  • Application configuration information (because the server cluster is simulated on one machine, three profiles are used corresponding to three ports respectively)
  • eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
      instance:
        leaseRenewalIntervalInSeconds: 10
        metadataMap:
          instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${server.port}}}
    
    endpoints:
      restart:
        enabled: true
      shutdown:
        enabled: true
      health:
        sensitive: false
    
    ---
    spring:
      application:
        name: say-hello
      profiles: one
    server:
      port: 8090
    
    ---
    spring:
      application:
        name: say-hello
      profiles: two
    server:
      port: 9092
    
    ---
    spring:
      application:
        name: say-hello
      profiles: three
    server:
      port: 9999
    
    

  • 3. User client (calls the Eureka client registered in the Eureka server)
  • The core is to add spring-cloud-starter-eureka, spring-cloud-starter-feign, spring-cloud-starter-ribbon dependencies to the normal Spring boot program, and add @EnableFeignClients, @RibbonClient(name = "say -hello") annotation
  • Code structure:




  • startup class
  • package hello;
    
    import static org.springframework.web.bind.annotation.RequestMethod.GET;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.feign.EnableFeignClients;
    import org.springframework.cloud.netflix.feign.FeignClient;
    import org.springframework.cloud.netflix.ribbon.RibbonClient;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @SpringBootApplication
    @RestController
    @RibbonClient(name = "say-hello")
    @EnableFeignClients
    public class UserApplication {
    
    	@Autowired
    	HelloClient client;
    
    	@RequestMapping("/greeting")
    	public String hello() {
    		return client.greet();
    	}
    
    	public static void main(String[] args) {
    		SpringApplication.run(UserApplication.class, args);
    	}
    
    	@FeignClient(name = "say-hello")
    	interface HelloClient {
    		@RequestMapping(value = "/greeting", method = GET)
    		String greet();
    	}
    }
    
    


    The service id in FeignClient and RibbonClient should be consistent with the value of spring.application.name in the Eureka client configuration information


  • pom file
  • <?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>hello</groupId>
    	<artifactId>user</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<packaging>jar</packaging>
    
    	<name>user</name>
    	<description>Demo project for Spring Boot</description>
    
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>1.5.1.RELEASE</version>
    		<relativePath /> <!-- lookup parent from repository -->
    	</parent>
    
    	<properties>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<java.version>1.8</java.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-starter-ribbon</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-actuator</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-starter-feign</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-starter-eureka</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-test</artifactId>
    			<scope>test</scope>
    		</dependency>
    	</dependencies>
    
    	<dependencyManagement>
    		<dependencies>
    			<dependency>
    				<groupId>org.springframework.cloud</groupId>
    				<artifactId>spring-cloud-dependencies</artifactId>
    				<version>Camden.SR5</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>
    
    	<repositories>
    		<repository>
    			<id>spring-snapshots</id>
    			<name>Spring Snapshots</name>
    			<url>https://repo.spring.io/snapshot</url>
    			<snapshots>
    				<enabled>true</enabled>
    			</snapshots>
    		</repository>
    		<repository>
    			<id>spring-milestones</id>
    			<name>Spring Milestones</name>
    			<url>https://repo.spring.io/milestone</url>
    			<snapshots>
    				<enabled>false</enabled>
    			</snapshots>
    		</repository>
    	</repositories>
    
    </project>
    
    

  • Application configuration information
  • spring:
      application:
        name: user
    
    server:
      port: 8888
    
    say-hello:
      ribbon:
        ServerListRefreshInterval: 15000
    
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
      instance:
        leaseRenewalIntervalInSeconds: 10
        metadataMap:
          instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${server.port}}}
    



    3.
    Start Start
    Eureka server -> Eureka client (say-hello) -> user client (user) in the following order,
    where Eureka client starts with
    --spring.profiles.active=one
    --spring.profiles.active= two
    --spring.profiles.active=three
    Start three services and register them in eureka

    . After all applications are started, visit http://localhost:8888/greeting through the interface, and you can access the return value of the method in the Eureka client normally. The process is the interface to access the hello method in the user client project. The user client obtains the registered say-hello instance from the Eureka server through the service id specified in @FeignClient, because there are three say-hello instances registered in Eureka. It will use Ribbon's RoundRobinRule rule to get an instance, call the corresponding greet() method, return the call result to the user client, and finally return to the interface


    Guess you like

    Origin http://43.154.161.224:23101/article/api/json?id=326455170&siteId=291194637