Learn SpringCloud Ribbon take you from 0-1

First, the role of service in the micro-Ribbon

1. What is the Ribbon

1.Ribbon is based on HTTP and TCP client load balancing tool , which is based implementation Netflix Ribbon

2. It is not like Spring Cloud service registration center, distribution center, API gateway as stand-alone deployment, but it exists in almost every Spring Cloud micro service. Declarative service call Feign is provided based implementation Ribbon.

3.Ribbon offers a variety of load balancing algorithms, for example: polling, random, and so on. Even includes a custom load balancing algorithm.

2.Ribbon solve the problem

It addresses and provides a micro-service load balancing problem

Second, within a centralized process and load balancing difference

1. Classification load balancing solution

The industry mainstream load balancing scheme can be divided into two categories:

  • Centralized Load balancing: the use of a separate load balancing facility in consumer and intermediate provider (either hardware, such as F5, can be software, such as: Nginx), access to the facility by the request is forwarded to the provider through a strategy

  • In-process load balancing: The load balancing logic integrated into consumer, consumer service registry learn from what address is available, then myself and then select an appropriate provider from these addresses

    Ribbon latter, it is just a class library, integrated in the consumer, consumer to obtain an appropriate provider address it.

2. State Chart load balancing methods

Three, Ribbon entry case

Ribbon strategy for load balancing cluster service uses the default polling

1.Consumer

@Service
public class UserService {

    @Autowired
    private LoadBalancerClient loadBalancerClient;  //ribbon:负载均衡器

    public List<User> getUsers(){

        //选择调用的服务的名称
            //ServiceInstance:封装了服务的基本信息,如:ip、端口号
        ServiceInstance si = loadBalancerClient.choose("eureka-provider");
        //拼接访问服务的url
        StringBuffer sb = new StringBuffer();

        //http://localhost:9090/user
        sb.append("http://").append(si.getHost()).append(":").append(si.getPort()).append("/user");
        System.out.println(sb.toString());
        //SpringMVC RestTemplate
        RestTemplate restTemplate = new RestTemplate();
        ParameterizedTypeReference<List<User>> type = new ParameterizedTypeReference<List<User>>() {
        };

        //ResponseEntity:封装了返回值信息
        ResponseEntity<List<User>> entity = restTemplate.exchange(sb.toString(), HttpMethod.GET, null, type);
        return entity.getBody();
    }
}
复制代码

2.Consumer profile

spring.application.name=eureka-consumer
server.port=9091

#设置服务注册中心地址,向所有注册中心做注册
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
复制代码

3.Provider cluster deployment

3.1 The Provider packaged, deployed to linux environment
3.2 Creating a Startup Script
#!/bin/bash
 
cd `dirname $0`
 
CUR_SHELL_DIR=`pwd`
CUR_SHELL_NAME=`basename ${BASH_SOURCE}`
 
JAR_NAME="springcloud-eureka-provider-0.0.1-SNAPSHOT.jar"
JAR_PATH=$CUR_SHELL_DIR/$JAR_NAME
 
#JAVA_MEM_OPTS=" -server -Xms1024m -Xmx1024m -XX:PermSize=128m"
JAVA_MEM_OPTS=""
 
#SPRING_PROFILES_ACTIV="-Dspring.profiles.active=eureka2"
SPRING_PROFILES_ACTIV=""
LOG_DIR=$CUR_SHELL_DIR/logs
LOG_PATH=$LOG_DIR/${JAR_NAME%..log
 
echo_help()
{
    echo -e "syntax: sh $CUR_SHELL_NAME start|stop"
}
 
if [ -z $1 ];then
    echo_help
    exit 1
fi
 
if [ ! -d "$LOG_DIR" ];then
    mkdir "$LOG_DIR"
fi
 
if [ ! -f "$LOG_PATH" ];then
    touch "$LOG_DIR"
fi
 
if [ "$1" == "start" ];then
 
    # check server
    PIDS=`ps --no-heading -C java -f --width 1000 | grep $JAR_NAME | awk '{print $2}'`
    if [ -n "$PIDS" ]; then
        echo -e "ERROR: The $JAR_NAME already started and the PID is ${PIDS}."
        exit 1
    fi
 
    echo "Starting the $JAR_NAME..."
 
    # start
    nohup java $JAVA_MEM_OPTS -jar $SPRING_PROFILES_ACTIV $JAR_PATH >> $LOG_PATH 2>&1 &
 
    COUNT=0
    while [ $COUNT -lt 1 ]; do
        sleep 1
        COUNT=`ps  --no-heading -C java -f --width 1000 | grep "$JAR_NAME" | awk '{print $2}' | wc -l`
        if [ $COUNT -gt 0 ]; then
            break
        fi
    done
    PIDS=`ps  --no-heading -C java -f --width 1000 | grep "$JAR_NAME" | awk '{print $2}'`
    echo "${JAR_NAME} Started and the PID is ${PIDS}."
    echo "You can check the log file in ${LOG_PATH} for details."
 
elif [ "$1" == "stop" ];then
 
    PIDS=`ps --no-heading -C java -f --width 1000 | grep $JAR_NAME | awk '{print $2}'`
    if [ -z "$PIDS" ]; then
        echo "ERROR:The $JAR_NAME does not started!"
        exit 1
    fi
 
    echo -e "Stopping the $JAR_NAME..."
 
    for PID in $PIDS; do
        kill $PID > /dev/null 2>&1
    done
 
    COUNT=0
    while [ $COUNT -lt 1 ]; do
        sleep 1
        COUNT=1
        for PID in $PIDS ; do
            PID_EXIST=`ps --no-heading -p $PID`
            if [ -n "$PID_EXIST" ]; then
                COUNT=0
                break
            fi
        done
    done
 
    echo -e "${JAR_NAME} Stopped and the PID is ${PIDS}."
else
    echo_help
    exit 1
fi
复制代码

4. Start consumer

Four, Ribbon common load balancing strategy

1. Polling Policy (default):

The use of RoundRobinRuleclasses, each time the polling policy sequence indicates a Provider removed, such as Provider 5 has, for the first time to take the first, the second to take a second, a third take the third, and so on .

2. Weight polling policies:

The use of WeightedResponseTimeRuleclasses, according to each Provider's response time assigned a weight, the weight increase response time smaller, less likely to be selected.

Principle: a start polling policy, and start a timer, collected once every 30s on average each provider's response time , when the information is sufficient to add a weight for each provider, and press weights randomly selected, the higher the weight is the higher the probability selected.

3. random strategy:

Use RandomRuleclass provider from the list of randomly selecting a provider

4. The minimum number of concurrent strategies:

Use BestAvailableRule, select the request is a small number of concurrent of provider, unless the provider in the fuse.

5. retry mechanism in selected "load balancing policy" on the basis of

Use RetryRuleclass, "the selected load balancing strategy" The strategy is polling policy RoundRobinRule

The retry strategy to set a threshold period of time , if the selected provider is not successful in this period of time, has been trying to adopt the "Selected load balancing strategy: Polling Policy" last select an available provider

6. Availability sensitive policy

The use of AvailabilityFilteringRuleclasses, poor filtration performance provider There are two:

The first: Eureka has been filtered out connection fails provider of

The second: to filter out high concurrency provider of

7. Regional Strategy sensitivity

Use ZoneAvoidanceRuleclass,

To examine the availability of a regional basis, to discard the whole area is not available, from the remaining region of the selected provider is available

If there is within the area of one or more instances ip unreachable or slow response, both decreases within the region other ip ip selected weights .

Five, Ribbon specify a different load balancing strategy

1. Modify the code to replace the load balancing strategy

1.1 Creating project

springcloud-eureka-consumer-LB

1.2 Add method to create a load balancing policy object in the startup class
/**
 * Author: LuYi
 * Date: 2019/11/5 17:32
 * Description: 描述
 */
@EnableEurekaClient
@SpringBootApplication
public class ConsumerApplication {

    @Bean
    public RandomRule createRule() {
        return new RandomRule();
    }

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}
复制代码

2. Modify the configuration file to replace the load balancing policy

#设置负载均衡策略 eureka-provider 为调用的服务的名称
eureka-provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
复制代码

Six, Ribbon peer Direct Connect

1. Create a project

springcloud-eureka-consumer-direct

2. Remove the Eureka coordinates, the coordinates added Ribbon

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.13.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.luyi</groupId>
    <artifactId>springcloud-eureka-consumer-direct</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springcloud-eureka-consumer-direct</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <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.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <!--ribbon坐标-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>
    </dependencies>

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

</project>
复制代码

3. Modify the configuration file to remove the related Eureka configuration, add a new configuration item

spring.application.name=eureka-consumer-direct
server.port=9091

#禁用 eureka
ribbon.eureka.enabled=false
#指定具体的服务实例清单
eureka-provider.ribbon.listOfServers=192.168.234.132:9090
复制代码

4. Modify the startup class, an error code is removed

@SpringBootApplication
public class ConsumerApplication {

//    @Bean
//    public RandomRule createRule() {
//        return new RandomRule();
//    }

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}
复制代码

Guess you like

Origin juejin.im/post/5dc8dad2f265da4d4176577d