docs/Spring全家桶/SpringCloud/SpringCloudRibbon.md
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עģлȡбȻͨؾԽ̯ṩߣӶﵽؾĿġ
ǾԱ£˸ؾͿͻ˸ؾʲô±
| ͬ | ˸ؾ | ͻ˸ؾ |
|---|---|---|
| ǷҪؾ | Ҫڿͻ˺ͷ֮佨һĸؾ | ؾԴʽװͻϣ˲Ҫؾ |
| ǷҪע | Ҫעġ | Ҫעġڿͻ˸ؾУеĿͻ˺ͷ˶Ҫṩķעᵽעϡ |
| ÷嵥洢λ | ÷嵥洢λڿͻ֮ĸؾϡ | еĿͻ˶άһݿ÷嵥Щ嵥ǴӷעĻȡġ |
| ؾʱ | Ƚ͵ؾȻɸؾͨؾ㷨ڶ֮ѡһзʣڷٽиؾ㷨䡣˵ǣȷٽиؾ⡣ | ڷǰλڿͻ˵ķؾ 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>
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 һͻ˵ĸؾ Eureka ʹɵʵֿͻ˵ĸؾ⡣Ribbon ȴ Eureka ServerעģȥȡбȻͨؾԽ̯ˣӶﵽؾĿġ
Spring Cloud Ribbon ṩһ IRule ӿڣýӿҪ帺ؾԣ 7 Ĭʵ࣬ÿһʵһָؾԡ
| ʵ | ؾ | |
|---|---|---|
| 1 | RoundRobinRule | ѯԣһ˳ѡȡʵ |
| 2 | RandomRule | ѡȡһʵ |
| 3 | RetryRule | RoundRobinRuleѯIJȡȡķʵΪ null ѾʧЧָʱ֮ڲϵؽԣʱȡIJԻ RoundRobinRule жIJԣָʱȻûȡʵ null |
| 4 | WeightedResponseTimeRule | WeightedResponseTimeRule RoundRobinRule һ࣬ RoundRobinRule ĹܽչƽӦʱ䣬зʵȨأӦʱԽ̵ķʵȨԽߣѡеĸԽʱͳϢ㣬ʹѯԣϢ㹻ʱл WeightedResponseTimeRule |
| 5 | BestAvailableRule | ̳ ClientConfigEnabledRoundRobinRuleȹ˵ϻʧЧķʵȻѡСķʵ |
| 6 | AvailabilityFilteringRule | ȹ˵ϻʧЧķʵȻѡСķʵ |
| 7 | ZoneAvoidanceRule | ĬϵĸؾԣۺжϷzoneܺͷserverĿԣѡʵûĻ£òѯRandomRuleơ |
Ǿͨһʵ֤£Ribbon Ĭʹʲôѡȡʵġ
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 ַ
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