1. 程式人生 > 實用技巧 >SpringCould 專案-- Ribbon負載均衡

SpringCould 專案-- Ribbon負載均衡

1.根據之前兩篇文章完成springcloud eureka 註冊中心 和 springcloud eureka叢集的搭建

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    : MySQL
6 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 負載均衡執行結果