SpringCould 專案-- Ribbon負載均衡
阿新 • • 發佈:2020-11-14
1.根據之前兩篇文章完成springcloud eureka 註冊中心 和 springcloud eureka叢集的搭建
2.新增兩個db01資料庫
修改資料庫名db01.db02.db03
修改資料db_source`db01/db02/db03 以便區分資料庫
1 1 /* 2 2 Navicat Premium Data Transfer 3 3 4 4 Source Server : localhost_3306 5 5 Source Server Type : MySQL6 6 Source Server Version : 50527 7 7 Source Host : localhost:3306 8 8 Source Schema : db01 9 9 10 10 Target Server Type : MySQL 11 11 Target Server Version : 50527 12 12 File Encoding : 65001 13 13 14 14 Date: 04/11/2020 23:03:17 15 15 */ 16 16 17 17 SET NAMES utf8mb4;18 18 SET FOREIGN_KEY_CHECKS = 0; 19 19 20 20 -- ---------------------------- 21 21 -- Table structure for dept 22 22 -- ---------------------------- 23 23 DROP TABLE IF EXISTS `dept`; 24 24 CREATE TABLE `dept` ( 25 25 `deptno` int(11) NOT NULL AUTO_INCREMENT, 26 26 `dname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,27 27 `db_source` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, 28 28 PRIMARY KEY (`deptno`) USING BTREE 29 29 ) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; 30 30 31 31 -- ---------------------------- 32 32 -- Records of dept 33 33 -- ---------------------------- 34 34 INSERT INTO `dept` VALUES (1, '開發部', 'db01'); 35 35 INSERT INTO `dept` VALUES (2, '人事部', 'db01'); 36 36 INSERT INTO `dept` VALUES (3, '財務部', 'db01'); 37 37 INSERT INTO `dept` VALUES (4, '市場部', 'db01'); 38 38 INSERT INTO `dept` VALUES (5, '運維部', 'db01'); 39 39 INSERT INTO `dept` VALUES (6, '遊戲部', 'db01'); 40 40 INSERT INTO `dept` VALUES (7, NULL, 'db01'); 41 41 42 42 SET FOREIGN_KEY_CHECKS = 1;
3.複製兩個springcloud-provider-dept-8001 ----provider 服務提供者專案
8002、8003
provider pom檔案
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>springcloud</artifactId> 7 <groupId>com.puyu</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 12 <artifactId>springcloud-provider-dept-8001</artifactId> 13 <!-- 我們需要拿到實體類,所以需要配置api module--> 14 <dependencies> 15 <!--Hystrix 依賴--> 16 <!--<dependency> 17 <groupId>org.springframework.cloud</groupId> 18 <artifactId>spring-cloud-starter-hystrix</artifactId> 19 <version>1.4.6.RELEASE</version> 20 </dependency>--> 21 <!-- eureka依賴 --> 22 <dependency> 23 <groupId>org.springframework.cloud</groupId> 24 <artifactId>spring-cloud-starter-eureka</artifactId> 25 <version>1.4.6.RELEASE</version> 26 </dependency> 27 <!--actuator完善監控資訊 Hystrid 流監控所需要的jar依賴--> 28 <dependency> 29 <groupId>org.springframework.boot</groupId> 30 <artifactId>spring-boot-starter-actuator</artifactId> 31 </dependency> 32 33 <dependency> 34 <groupId>com.puyu</groupId> 35 <artifactId>springcloud-api</artifactId> 36 <version>1.0-SNAPSHOT</version> 37 </dependency> 38 <dependency> 39 <groupId>junit</groupId> 40 <artifactId>junit</artifactId> 41 <scope>test</scope> 42 </dependency> 43 <dependency> 44 <groupId>mysql</groupId> 45 <artifactId>mysql-connector-java</artifactId> 46 </dependency> 47 <dependency> 48 <groupId>com.alibaba</groupId> 49 <artifactId>druid</artifactId> 50 </dependency> 51 <dependency> 52 <groupId>ch.qos.logback</groupId> 53 <artifactId>logback-core</artifactId> 54 </dependency> 55 <dependency> 56 <groupId>org.mybatis.spring.boot</groupId> 57 <artifactId>mybatis-spring-boot-starter</artifactId> 58 </dependency> 59 <dependency> 60 <groupId>org.springframework.boot</groupId> 61 <artifactId>spring-boot-starter-web</artifactId> 62 <version>RELEASE</version> 63 <scope>compile</scope> 64 </dependency> 65 </dependencies> 66 67 </project>
配置8001/8002 application.yml 檔案
8002
1 server: 2 port: 8002 3 4 #mybatis 配置 5 mybatis: 6 type-aliases-package: com.puyu.springcloud.pojo 7 config-location: classpath:mybatis/mybatis-config.xml 8 mapper-locations: classpath:mybatis/mapper/*.xml 9 10 #spring配置 11 spring: 12 application: 13 name: springcloud-provider-dept # 3個服務名字一致 14 datasource: 15 type: com.alibaba.druid.pool.DruidDataSource #阿里巴巴德魯伊 16 driver-class-name: org.gjt.mm.mysql.Driver 17 url: jdbc:mysql://localhost:3306/db02?useUnicode=true&characterEncoding=utf-8 18 username: root 19 password: root 20 21 #eureka 配置 #defaultZone ---釋出到那個註冊中心 22 eureka: 23 client: 24 serviceUrl: 25 defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ 26 instance: 27 instance-id: springcloud-provider-dept8002 #修改eureka 上的預設描述資訊 28 29 #info 自定義配置資訊 30 info: 31 app.name: huangpuyu-springcloud # 顯示與springcloud-provider-dept8001 預設描述資訊 點選後項目描述 32 company.name: big.pig.com
8003
1 server: 2 port: 8003 3 4 #mybatis 配置 5 mybatis: 6 type-aliases-package: com.puyu.springcloud.pojo 7 config-location: classpath:mybatis/mybatis-config.xml 8 mapper-locations: classpath:mybatis/mapper/*.xml 9 10 #spring配置 11 spring: 12 application: 13 name: springcloud-provider-dept # 3個服務名字一致 14 datasource: 15 type: com.alibaba.druid.pool.DruidDataSource #阿里巴巴德魯伊 16 driver-class-name: org.gjt.mm.mysql.Driver 17 url: jdbc:mysql://localhost:3306/db03?useUnicode=true&characterEncoding=utf-8 18 username: root 19 password: root 20 21 #eureka 配置 #defaultZone ---釋出到那個註冊中心 22 eureka: 23 client: 24 serviceUrl: 25 defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ 26 instance: 27 instance-id: springcloud-provider-dept8003 #修改eureka 上的預設描述資訊 28 29 #info 自定義配置資訊 30 info: 31 app.name: huangpuyu-springcloud # 顯示與springcloud-provider-dept8001 預設描述資訊 點選後項目描述 32 company.name: big.pig.com
專案包結構
4.配置springcloud-consumer-dept-81
pom檔案新增依賴
ribbon依賴和eureka 依賴
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>springcloud</artifactId> 7 <groupId>com.puyu</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 12 <artifactId>spingcloud-consumer-dept-81</artifactId> 13 14 <!-- 實體類+web依賴 --> 15 <dependencies> 16 <!-- 新增ribbon需要的依賴 完成負載均衡 --> 17 <dependency> 18 <groupId>org.springframework.cloud</groupId> 19 <artifactId>spring-cloud-starter-ribbon</artifactId> 20 <version>1.4.6.RELEASE</version> 21 </dependency> 22 <!-- 因為要從服務中心 判斷拿那些東西 所以需要eureka依賴 client 客戶端依賴 ribbon 需要 --> 23 <dependency> 24 <groupId>org.springframework.cloud</groupId> 25 <artifactId>spring-cloud-starter-eureka</artifactId> 26 <version>1.4.6.RELEASE</version> 27 </dependency> 28 <!-- 匯入springcloud-api 以便獲取到Dept例項--> 29 <dependency> 30 <groupId>com.puyu</groupId> 31 <artifactId>springcloud-api</artifactId> 32 <version>1.0-SNAPSHOT</version> 33 </dependency> 34 <dependency> 35 <groupId>org.springframework.boot</groupId> 36 <artifactId>spring-boot-starter-web</artifactId> 37 </dependency> 38 <!-- 熱部署依賴 --> 39 <!-- <dependency> 40 <groupId>org.springframework.boot</groupId> 41 <artifactId>spring-boot-devtools</artifactId> 42 </dependency>--> 43 </dependencies> 44 </project>
5.配置application.yml檔案
1 server: 2 port: 81 #訪問埠號 3 4 #客戶端消費端 eureka配置 5 eureka: 6 client: 7 register-with-eureka: false #先宣告不向eureka中註冊自己 8 serviceUrl: 9 defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ 10 #客戶端 隨機向defaultzone中隨機選擇一個去訪問 實現負載均衡
6.配置ConfigBean
新增@LoadBalanced Ribbon 實現負載均衡
loadbalanced 預設是輪詢策略
1 1 package com.puyu.springcloud.config; 2 2 3 3 import com.netflix.loadbalancer.IRule; 4 4 import com.netflix.loadbalancer.RandomRule; 5 5 import org.springframework.cloud.client.loadbalancer.LoadBalanced; 6 6 import org.springframework.context.annotation.Bean; 7 7 import org.springframework.context.annotation.Configuration; 8 8 import org.springframework.web.client.RestTemplate; 9 9 10 10 @Configuration 11 11 public class ConfigBean { 12 12 13 13 //配置賦值均衡實現RestTemlate 14 14 //IRule 15 15 //RoundRobinRule 輪詢 16 16 //RandomRule 隨機 17 17 //AvailbiliryFilteringRule :會過濾掉 跳閘,訪問故障的服務,對剩下的進行;輪詢S 18 18 //RetryRule 會先按輪詢的策略獲取服務,如果服務獲取失敗,則會在指定的時間內進行重試 19 19 20 20 21 21 //@LoadBalanced --Ribbon 實現負載均衡 讓RestTemplate 實現負載均衡 22 22 @Bean 23 23 @LoadBalanced //Ribbon 實現負載均衡 24 24 public RestTemplate getRestTemplate() { 25 25 return new RestTemplate(); 26 26 } 27 27 28 28 29 29 }
ribbon的負載均衡方法策略
RoundRobinRule 輪詢
RandomRule 隨機
vailbiliryFilteringRule :會過濾掉 跳閘,訪問故障的服務,對剩下的進行;輪詢S
RetryRule 會先按輪詢的策略獲取服務,如果服務獲取失敗,則會在指定的時間內進行重試
6.springcloud-consumer-dept-81 啟動類添加註解
@EnableEurekaClient Eureka Client 註冊到Eureka 註冊中心中
1 package com.puyu.springcloud; 2 3 import com.puyu.myrule.PuYuRule; 4 import org.springframework.boot.SpringApplication; 5 import org.springframework.boot.autoconfigure.SpringBootApplication; 6 import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 7 import org.springframework.cloud.netflix.ribbon.RibbonClient; 8 9 10 //Ribbon 和Eureka 整合以後客戶端可以直接呼叫服務端,不用關心埠號和ip地址 11 @SpringBootApplication 12 @EnableEurekaClient // Eureka Client 註冊到Eureka 註冊中心中 13 //在微服務啟動的時候就能去載入 自定義的Ribbon類 ---指定ribbon自定義類 name為 服務名 14 //@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = PuYuRule.class) 15 public class DeptConsumer_81 { 16 public static void main(String[] args) { 17 SpringApplication.run(DeptConsumer_81.class,args); 18 } 19 }
6.1自定義負載均衡策略 繼承重寫輪詢策略
1 package com.puyu.myrule; 2 3 import com.netflix.client.config.IClientConfig; 4 import com.netflix.loadbalancer.AbstractLoadBalancerRule; 5 import com.netflix.loadbalancer.ILoadBalancer; 6 import com.netflix.loadbalancer.Server; 7 8 import java.util.List; 9 import java.util.concurrent.ThreadLocalRandom; 10 11 /** 12 * A loadbalacing strategy that randomly distributes traffic amongst existing 13 * servers. 14 * 15 * @author stonse 16 */ 17 public class PuYuRandomRule extends AbstractLoadBalancerRule { 18 19 /*每個服務,訪問5次 換下一個服務(3個)*/ 20 /*total=0 預設等於0 如果等於5 我們指向下一個服務節點*/ 21 /*index=0 預設等於0 如果totol等於5 index +1*/ 22 23 private int total =0;//被呼叫的次數 24 private int currentIndex=0;//當前是誰在提供服務 25 // @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE") 26 public Server choose(ILoadBalancer lb, Object key) { 27 if (lb == null) { 28 return null; 29 } 30 Server server = null; 31 32 while (server == null) { 33 if (Thread.interrupted()) { 34 return null; 35 } 36 List<Server> upList = lb.getReachableServers();//獲得還活著的服務 37 List<Server> allList = lb.getAllServers();//獲得全部的服務 38 39 int serverCount = allList.size(); 40 if (serverCount == 0) { 41 42 return null; 43 } 44 45 /* int index = chooseRandomInt(serverCount);//生成區間隨機數 46 server = upList.get(index);//從活著的服務中隨機獲取一個*/ 47 48 //------------- 49 if (total<5){ 50 server = upList.get(currentIndex); 51 total++; 52 }else { 53 total=0; 54 currentIndex++; 55 if (currentIndex>upList.size()){ 56 currentIndex =0; 57 } 58 server = upList.get(currentIndex); //從活著的服務中,獲取指定的服務來進行操作 59 } 60 //------------- 61 62 if (server == null) { 63 64 Thread.yield(); 65 continue; 66 } 67 68 if (server.isAlive()) { 69 return (server); 70 } 71 72 // Shouldn't actually happen.. but must be transient or a bug. 73 server = null; 74 Thread.yield(); 75 } 76 77 return server; 78 79 } 80 81 protected int chooseRandomInt(int serverCount) { 82 return ThreadLocalRandom.current().nextInt(serverCount); 83 } 84 85 @Override 86 public Server choose(Object key) { 87 return choose(getLoadBalancer(), key); 88 } 89 90 @Override 91 public void initWithNiwsConfig(IClientConfig clientConfig) { 92 // TODO Auto-generated method stub 93 94 } 95 }
6.2專案啟動類 配置@RibbonClient (name=“微服務名”,configuration= 類名.class)指定自定義輪詢策略類
最後eureka叢集 和ribbon 負載均衡執行結果