Back to Javatutorial

SpringCloudRibbon

docs/Spring全家桶/SpringCloud/SpringCloudRibbon.md

1.0.018.1 KB
Original Source

Spring Cloud Ribbon һ׻ Netflix Ribbon ʵֵĿͻ˸ؾͷùߡ

Netflix Ribbon Netflix ˾ĿԴҪṩͻ˵ĸؾ㷨ͷáSpring Cloud Netflix еԴ EurekaFeign Լ Hystrix ȣһϽ Spring Cloud Netflix ģУϺȫΪ Spring Cloud Netflix Ribbon

Ribbon Spring Cloud Netflix ģģ飬 Spring Cloud Netflix Ribbon ĶηװͨǿԽ REST ģ壨RestTemplateתΪͻ˸ؾķá

Ribbon Spring Cloud ϵġҪ֮һȻֻһ͵Ŀܣ Eureka ServerעģҪ𣬵ÿһʹ Spring Cloud ΢С

Spring Cloud ΢֮ĵãAPI صתݣʵ϶ͨ Spring Cloud Ribbon ʵֵģҪܵ OpenFeign Ҳǻʵֵġ

ؾ

κһϵͳУؾⶼһʮҪҲòȥʵʩݣϵͳ߲ѹͷݵҪֶ֮һ

ؾ⣨Load Balance 򵥵˵ǽûƽ̯䵽УԴﵽչǿݴĿԺԵĿġ

ĸؾⷽʽ֣

  • ˸ؾ
  • ͻ˸ؾ

˸ؾ

˸ؾĸؾⷽʽ乤ԭͼ

ͼ1˸ؾ⹤ԭ

˸ؾڿͻ˺ͷ֮佨һĸؾ÷ȿӲ豸 F5Ҳ Nginxؾάһݿ÷嵥Ȼͨɾϵķ˽ڵ㣬Ա֤嵥езڵ㶼ǿʵġ

ͻ˷ʱ󲻻ֱӷ͵˽дȫؾɸؾij㷨ѯȣάĿ÷嵥ѡһˣȻת

˸ؾص㣺

  • Ҫһĸؾ
  • ؾڿͻ˷еģ˿ͻ˲֪ĸṩķ
  • ÷嵥洢ڸؾϡ

ͻ˸ؾ

ڷ˸ؾ⣬ͻ˷ھһȽСڵĸ

ͻ˸ؾĹԭͼ

ͼ2ͻ˸ؾ⹤ԭ

ͻ˸ؾǽؾ߼Դʽװͻϣؾλڿͻˡͻͨעģ Eureka ServerȡһݷṩĿ÷嵥˷嵥󣬸ؾڿͻ˷ǰͨؾ㷨ѡһʵٽзʣԴﵽؾĿģ

ͻ˸ؾҲҪȥά嵥ЧԣҪϷעһɡ

ͻ˸ؾص㣺

  • ؾλڿͻˣҪһؾ
  • ؾڿͻ˷ǰеģ˿ͻ֪ĸṩķ
  • ͻ˶άһݿ÷嵥嵥ǴӷעĻȡġ

Ribbon һ HTTP TCP Ŀͻ˸ؾǽ Ribbon Eureka һʹʱRibbon Eureka ServerעģлȡбȻͨؾԽ̯ṩߣӶﵽؾĿġ

˸ؾ VS ͻ˸ؾ

ǾԱ£˸ؾͿͻ˸ؾ⵽ʲô±

ͬ˸ؾͻ˸ؾ
ǷҪؾҪڿͻ˺ͷ֮佨һĸؾؾ߼Դʽװͻϣ˲Ҫؾ
ǷҪעҪעġҪעġڿͻ˸ؾУеĿͻ˺ͷ˶Ҫṩķעᵽעϡ
÷嵥洢λ÷嵥洢λڿͻ֮ĸؾϡеĿͻ˶άһݿ÷嵥Щ嵥ǴӷעĻȡġ
ؾʱȽ͵ؾȻɸؾͨؾ㷨ڶ֮ѡһзʣڷٽиؾ㷨䡣򵥵˵ǣȷٽиؾ⡣ڷǰλڿͻ˵ķؾ Ribbonͨؾ㷨ѡһȻзʡ򵥵˵ǣȽиؾ⣬ٷ
ͻǷ˽ṩϢڸؾڿͻ˷еģ˿ͻ˲֪ĸṩķؾڿͻ˷ǰеģ˿ͻ֪ĸṩķ

Ribbon ʵַ

Ribbon RestTemplateRest ģ壩ʹãʵ΢֮ĵá

RestTemplate Spring еһѵ REST ܡRestTemplate ʵ˶ HTTP ķװṩһģ廯ķ÷ͨSpring ӦÿԺܷضԸ͵ HTTP зʡ

RestTemplate Ը͵ HTTP ṩӦķд HEADGETPOSTPUTDELETE ͵ HTTP 󣬷ֱӦ RestTemplate е headForHeaders()getForObject()postForObject()put() Լ delete()

ͨһ򵥵ʵʾ Ribbon ʵַõġ

1. spring-cloud-demo2 £һΪ micro-service-cloud-consumer-dept-80 ΢񣬲 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <!---->
    <parent>
        <artifactId>spring-cloud-demo2</artifactId>
        <groupId>net.biancheng.c</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <groupId>net.biancheng.c</groupId>
    <artifactId>micro-service-cloud-consumer-dept-80</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>micro-service-cloud-consumer-dept-80</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--ģ-->
        <dependency>
            <groupId>net.biancheng.c</groupId>
            <artifactId>micro-service-cloud-api</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--Spring Boot Web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--Spring Boot -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--Spring Cloud Eureka ͻ-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--Spring Cloud Ribbon -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

  1. · /resource Ŀ¼£½һļ application.yml¡
server:
  port: 80 #˿ں

############################################# Spring Cloud Ribbon ؾ##########################
eureka:
  client:
    register-with-eureka: false #΢ΪߣҪԼעᵽע
    fetch-registry: true  #΢ΪߣҪע
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ #עļȺ

3. net.biancheng.c.config £һΪ ConfigBean ࣬ RestTemplate ע뵽У¡



package net.biancheng.c.config;

import com.netflix.loadbalancer.IRule;

import com.netflix.loadbalancer.RetryRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
// ע
@Configuration
public class ConfigBean {
    
    @Bean // RestTemplate ע뵽
    @LoadBalanced //ڿͻʹ RestTemplate ʱؾ⣨Ribbon
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

4. net.biancheng.c.controller £һΪ DeptController_Consumer Controller Controller жڵ÷ṩķ񣬴¡

package net.biancheng.c.controller;

import net.biancheng.c.entity.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@RestController
public class DeptController_Consumer {
    //private static final String REST_URL_PROVIDER_PREFIX = "http://localhost:8001/"; ַʽֱ÷񷽵ķûõ Spring Cloud

    //΢̣ͨ΢ȡõַ
    private static final String REST_URL_PROVIDER_PREFIX = "http://MICROSERVICECLOUDPROVIDERDEPT"; // ʹעᵽ Spring Cloud Eureka עеķ񣬼 application.name

    @Autowired
    private RestTemplate restTemplate; //RestTemplate һּ򵥱ݵķ restful ģ࣬ Spring ṩڷ Rest Ŀͻģ幤߼ṩ˶ֱݷԶ HTTP ķ

    //ȡָϢ
    @RequestMapping(value = "/consumer/dept/get/{id}")
    public Dept get(@PathVariable("id") Integer id) {
        return restTemplate.getForObject(REST_URL_PROVIDER_PREFIX + "/dept/get/" + id, Dept.class);
    }
    //ȡб
    @RequestMapping(value = "/consumer/dept/list")
    public List<Dept> list() {
        return restTemplate.getForObject(REST_URL_PROVIDER_PREFIX + "/dept/list", List.class);
    }
}

5. micro-service-cloud-consumer-dept-80 ϣʹ @EnableEurekaClient ע Eureka ͻ˹ܣ¡


package net.biancheng.c;

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

@SpringBootApplication
@EnableEurekaClient
public class MicroServiceCloudConsumerDept80Application {

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

6. ע micro-service-cloud-eureka-7001ṩ micro-service-cloud-provider-dept-8001 Լ micro-service-cloud-consumer-dept-80

7. ʹʡhttp://eureka7001.com:80/consumer/dept/listͼ

ͼ3Ribbon ʵַ

Ribbon ʵָؾ

Ribbon һͻ˵ĸؾ Eureka ʹɵʵֿͻ˵ĸؾ⡣Ribbon ȴ Eureka ServerעģȥȡбȻͨؾԽ̯ˣӶﵽؾĿġ

Spring Cloud Ribbon ṩһ IRule ӿڣýӿҪ帺ؾԣ 7 Ĭʵ࣬ÿһʵ඼һָؾԡ

ʵؾ
1RoundRobinRuleѯԣһ˳ѡȡʵ
2RandomRuleѡȡһʵ
3RetryRuleRoundRobinRuleѯIJȡȡķʵΪ null ѾʧЧָʱ֮ڲϵؽԣʱȡIJԻ RoundRobinRule жIJԣָʱȻûȡʵ򷵻 null
4WeightedResponseTimeRuleWeightedResponseTimeRule RoundRobinRule һ࣬ RoundRobinRule ĹܽչƽӦʱ䣬зʵȨأӦʱԽ̵ķʵȨԽߣѡеĸԽ󡣸ʱͳϢ㣬ʹѯԣϢ㹻ʱл WeightedResponseTimeRule
5BestAvailableRule̳ ClientConfigEnabledRoundRobinRuleȹ˵ϻʧЧķʵȻѡ񲢷Сķʵ
6AvailabilityFilteringRuleȹ˵ϻʧЧķʵȻѡ񲢷Сķʵ
7ZoneAvoidanceRuleĬϵĸؾԣۺжϷzoneܺͷserverĿԣѡʵûĻ£òѯRandomRuleơ

Ǿͨһʵ֤£Ribbon Ĭʹʲôѡȡʵġ

  1. MySQL ݿִ SQL 䣬׼ݡ
DROP DATABASE IF EXISTS spring_cloud_db2;
CREATE DATABASE spring_cloud_db2 CHARACTER SET UTF8;

USE spring_cloud_db2;

DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (
  `dept_no` int NOT NULL AUTO_INCREMENT,
  `dept_name` varchar(255) DEFAULT NULL,
  `db_source` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`dept_no`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

INSERT INTO `dept` VALUES ('1', '', DATABASE());
INSERT INTO `dept` VALUES ('2', '²', DATABASE());
INSERT INTO `dept` VALUES ('3', '', DATABASE());
INSERT INTO `dept` VALUES ('4', 'г', DATABASE());
INSERT INTO `dept` VALUES ('5', 'ά', DATABASE());

#############################################################################################

DROP DATABASE IF EXISTS spring_cloud_db3;

CREATE DATABASE spring_cloud_db3 CHARACTER SET UTF8;

USE spring_cloud_db3;

DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (
  `dept_no` int NOT NULL AUTO_INCREMENT,
  `dept_name` varchar(255) DEFAULT NULL,
  `db_source` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`dept_no`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

INSERT INTO `dept` VALUES ('1', '', DATABASE());
INSERT INTO `dept` VALUES ('2', '²', DATABASE());
INSERT INTO `dept` VALUES ('3', '', DATABASE());
INSERT INTO `dept` VALUES ('4', 'г', DATABASE());
INSERT INTO `dept` VALUES ('5', 'ά', DATABASE());```

2\. ο micro-service-cloud-provider-dept-8001ٴ΢ Moudle micro-service-cloud-provider-dept-8002  micro-service-cloud-provider-dept-8003

3\.  micro-service-cloud-provider-dept-8002  application.yml У޸Ķ˿ںšݿϢԼԶϢeureka.instance.instance-id޸ĵ¡

server:
  port: 8002  #˿ں޸Ϊ 8002

spring:
  application:
    name: microServiceCloudProviderDept  #΢ƣ޸ģ micro-service-cloud-provider-dept-8001 ñһ

  datasource:
    username: root        #ݿ½û
    password: root        #ݿ½
    url: jdbc:mysql://127.0.0.1:3306/spring_cloud_db2       #ݿurl
    driver-class-name: com.mysql.jdbc.Driver                  #ݿ

eureka:
  client: #ͻעᵽ eureka б
    service-url:
     #defaultZone: http://eureka7001:7001/eureka  #ַ 7001ע application.yml б¶עַ 棩
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/  #עᵽ Eureka Ⱥ
  instance:
    instance-id: spring-cloud-provider-8002 #޸ԶķϢ
    prefer-ip-address: true  #ʾ· ip ַ

4. micro-service-cloud-provider-dept-8003 application.yml У޸Ķ˿ںԼݿϢ޸ĵ¡


server:
  port: 8003  #˿ں޸Ϊ 8003

spring:
  application:
    name: microServiceCloudProviderDept  #΢ƣ޸ģ micro-service-cloud-provider-dept-8001 ñһ

  datasource:
    username: root        #ݿ½û
    password: root        #ݿ½
    url: jdbc:mysql://127.0.0.1:3306/spring_cloud_db3      #ݿurl
    driver-class-name: com.mysql.jdbc.Driver                  #ݿ

eureka:
  client: #ͻעᵽ eureka б
    service-url:
     #defaultZone: http://eureka7001:7001/eureka  #ַ 7001ע application.yml б¶עַ 棩
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/  #עᵽ Eureka Ⱥ
  instance:
    instance-id: spring-cloud-provider-8003 #ԶϢ
    prefer-ip-address: true  #ʾ· ip ַ

  1. micro-service-cloud-eureka-7001/7002/7003עļȺmicro-service-cloud-provider-dept-8001/8002/8003ṩ߼ȺԼ micro-service-cloud-consumer-dept-80ߣ

6. ʹʡhttp://eureka7001.com/consumer/dept/get/1,ͼ

ͼ4Ribbon Ĭϸؾ

ͨͼ 4 dbSource ֶȡֵı仯ԿSpring Cloud Ribbon ĬʹѯԽиؾ⡣

лؾ

Spring Cloud Ribbon ĬʹѯѡȡʵҲԸлؾԡ

лؾԵķܼ򵥣ֻҪڷߣͻˣУ IRule ʵע뵽мɡ

ǾͨһʵʾлؾIJԡ

1. micro-service-cloud-consumer-dept-80 ConfigBean ´룬ؾлΪ RandomRule



@Bean
public IRule myRule() {
    // RandomRule Ϊ
    return  new RandomRule();
}

2. micro-service-cloud-consumer-dept-80ʹʡhttp://eureka7001.com/consumer/dept/get/1ͼ

ͼ5лؾΪ

ͨͼ 5 dbSource ֶȡֵı仯ԿѾؾлΪ RandomRule

Ƹؾ

ͨ£Ribbon ṩЩĬϸؾǿǵģҪǻԸƸؾԡ

ǾʾζƸؾԡ

1. micro-service-cloud-consumer-dept-80 ½һ net.biancheng.myrule ڸð´һΪ MyRandomRule ࣬¡


package net.biancheng.myrule;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

import java.util.List;

/**
*  Ribbon ؾ
*/
public class MyRandomRule extends AbstractLoadBalancerRule {
    private int total = 0;            // ܹõĴĿǰҪÿ̨5
    private int currentIndex = 0;    // ǰṩĻ

    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        }
        Server server = null;

        while (server == null) {
            if (Thread.interrupted()) {
                return null;
            }
            //ȡЧķʵб
            List<Server> upList = lb.getReachableServers();
            //ȡеķʵб
            List<Server> allList = lb.getAllServers();

            //ûκεķʵ򷵻 null
            int serverCount = allList.size();
            if (serverCount == 0) {
                return null;
            }
            //ƣÿʵֻڵ 3 ֮󣬲Żķʵ
            if (total < 3) {
                server = upList.get(currentIndex);
                total++;
            } else {
                total = 0;
                currentIndex++;
                if (currentIndex >= upList.size()) {
                    currentIndex = 0;
                }
            }
            if (server == null) {
                Thread.yield();
                continue;
            }
            if (server.isAlive()) {
                return (server);
            }
            server = null;
            Thread.yield();
        }
        return server;
    }

    @Override
    public Server choose(Object key) {
        return choose(getLoadBalancer(), key);
    }

    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {
        // TODO Auto-generated method stub
    }
}

2. net.biancheng.myrule ´һΪ MySelfRibbonRuleConfig ࣬ǶƵĸؾʵע뵽У¡

package net.biancheng.myrule;

import com.netflix.loadbalancer.IRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
*  Ribbon ؾԵ
* Զ Ribbon ؾ  net.biancheng.c Ӱ
* е Ribbon ͻ˶øòԣ޷ﵽ⻯ƵĿ
*/
@Configuration
public class MySelfRibbonRuleConfig {
    @Bean
    public IRule myRule() {
        //Զ Ribbon ؾ
        return new MyRandomRule(); //Զ壬ѡijһ΢ִ
    }
}

3. ޸λ net.biancheng.c µ࣬ڸʹ @RibbonClient עǶƵĸؾЧ¡



package net.biancheng.c;

import net.biancheng.myrule.MySelfRibbonRuleConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;

@SpringBootApplication
@EnableEurekaClient
//Զ Ribbon ؾʹ RibbonClient ע⣬ڸ΢ʱԶȥԶ Ribbon ࣬ӶЧ
// name ΪҪƸؾԵ΢ƣapplication name
// configuration ΪƵĸؾԵ࣬
// ҹٷĵȷ಻ ComponentScan ע⣨SpringBootApplication עа˸ע⣩µİӰУԶ帺ؾ಻ net.biancheng.c Ӱ
@RibbonClient(name = "MICROSERVICECLOUDPROVIDERDEPT", configuration = MySelfRibbonRuleConfig.class)
public class MicroServiceCloudConsumerDept80Application {

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

4. micro-service-cloud-consumer-dept-80ʹʡhttp://eureka7001.com/consumer/dept/get/1ͼ

ͼ6Ƹؾ

ͨͼ 6 dbSource ֶȡֵı仯ԿǶƵĸؾѾЧ

ο

https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA https://juejin.cn/post/6931922457741770760 https://github.com/D2C-Cai/herring http://c.biancheng.net/springcloud https://github.com/macrozheng/springcloud-learning