JavaEE进阶知识学习-----SpringCloud(六)Ribbon负载均衡
Ribbon負載均衡
Ribbon概述
Spring Cloude Ribbon是基于Netfilx Ribbon實現的一套客戶端 負載均衡的工具,簡單說,Ribbon是Netfilix發布的開源項目,主要功能就是提供 客戶端的軟件負載均衡算法,將Netfilix的中間層服務連接在一起,Ribbon客戶端組件提供了一系列完善的配置項如連接超時,重試等,簡單說,就是在配置文件中列出Load Balance后面的所有機器,Ribbon會自動的幫助你基于某種算法規則(簡單輪詢,隨機連接等)去連接這些機器,也可以使用Ribbon自定義負載均衡算法。LB,即負載均衡,在微服務或者分布式集群中常用的一種應用。負載均衡就是將用戶的請求平攤的分配到多個服務上,從而達到HA,常見的負載均衡軟件有Nginx,LVS,硬件F5等
Ribbon配置初步
由于Ribbon是客戶端的負載均衡工具,所以我們需要修改的是客戶端項目microservicecloud-consumer-dept-80
POM.xml文件
<!-- Ribbon相關 --> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> 復制代碼修改application.yml文件,添加Eureka的服務注冊地址
server: port: 80 eureka: client: register-with-eureka: false #自己不能注冊 service-url: defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ 復制代碼修改客戶端配置類
由于客戶端使用restTemplate訪問服務端中的數據接口,restTemplate配置在服務端的配置類中,所以修改如下
public class ConfigBean {public RestTemplate geRestTemplate(){return new RestTemplate();} } 復制代碼修改客戶端主程序啟動類
public class DeptConsumer80_App {public static void main(String[] args) {SpringApplication.run(DeptConsumer80_App.class, args);} } 復制代碼修改客戶端訪問類DeptController_Consumer.java
private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT"; 復制代碼測試
啟動7001,7002,7003三個服務注冊中心,啟動8001服務提供者,啟動80客戶端,使用http://localhost/consumer/dept/list可以渠道對應的數據,在DeptController_Consumer使用的是http://MICROSERVICECLOUD-DEPT服務名稱來調用服務的接口,相比之前的http://localhost:8001,Ribbon和Eureka整合后,Consumer可以直接通過服務名稱來調用服務,而不再關心地址和端口號。
Ribbon負載均衡
目前只有一個microservicecloud-provider-dept-8001服務提供者,為了實現Ribbon的負載均衡,所以我們需要多個服務提供者實例,新建microservicecloud-provider-dept-8002,microservicecloud-provider-dept-8003兩個Module。參考8001的pom.xml文件修改8002,8003的pom.xml文件。拷貝8001中的所以類和配置文件mybatis和application.yml文件,將主啟動類修改為對應的名字
microservicecloud-provider-dept-8002服務提供者
使用的數據庫SQL語句
DROP DATABASE IF EXISTS cloudDB02 ;CREATE DATABASE cloudDB02 CHARACTER SET UTF8 ;USE cloudDB02 ;CREATE TABLE dept (deptno BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,dname VARCHAR (60),db_source VARCHAR (60) ) ;INSERT INTO dept(dname,db_source) VALUES('開發部',DATABASE()); INSERT INTO dept(dname,db_source) VALUES('人事部',DATABASE()); INSERT INTO dept(dname,db_source) VALUES('財務部',DATABASE()); INSERT INTO dept(dname,db_source) VALUES('市場部',DATABASE()); INSERT INTO dept(dname,db_source) VALUES('運維部',DATABASE()); 復制代碼Application.yml文件
server: port: 8002mybatis: config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路徑 type-aliases-package: com.luo.springcloud.entities # 所有Entity別名類所在包 mapper-locations: - classpath:mybatis/mapper/**/*.xml # mapper映射文件spring: application: name: microservicecloud-dept datasource: type: com.alibaba.druid.pool.DruidDataSource # 當前數據源操作類型 driver-class-name: org.gjt.mm.mysql.Driver # mysql驅動包 url: jdbc:mysql://localhost:3306/cloudDB02 # 數據庫名稱 username: root password: 1234 dbcp2: min-idle: 5 # 數據庫連接池的最小維持連接數 initial-size: 5 # 初始化連接數 max-total: 5 # 最大連接數 max-wait-millis: 200 復制代碼microservicecloud-provider-dept-8003服務提供者
使用的數據庫SQL語句
DROP DATABASE IF EXISTS cloudDB03 ;CREATE DATABASE cloudDB03 CHARACTER SET UTF8 ;USE cloudDB03 ;CREATE TABLE dept (deptno BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,dname VARCHAR (60),db_source VARCHAR (60) ) ;INSERT INTO dept(dname,db_source) VALUES('開發部',DATABASE()); INSERT INTO dept(dname,db_source) VALUES('人事部',DATABASE()); INSERT INTO dept(dname,db_source) VALUES('財務部',DATABASE()); INSERT INTO dept(dname,db_source) VALUES('市場部',DATABASE()); INSERT INTO dept(dname,db_source) VALUES('運維部',DATABASE()); 復制代碼Application.yml文件
server: port: 8003mybatis: config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路徑 type-aliases-package: com.luo.springcloud.entities # 所有Entity別名類所在包 mapper-locations: - classpath:mybatis/mapper/**/*.xml # mapper映射文件spring: application: name: microservicecloud-dept datasource: type: com.alibaba.druid.pool.DruidDataSource # 當前數據源操作類型 driver-class-name: org.gjt.mm.mysql.Driver # mysql驅動包 url: jdbc:mysql://localhost:3306/cloudDB03 # 數據庫名稱 username: root password: 1234 dbcp2: min-idle: 5 # 數據庫連接池的最小維持連接數 initial-size: 5 # 初始化連接數 max-total: 5 # 最大連接數 max-wait-millis: 200 復制代碼微服務提供者說明
三個微服務提供者連接不同的數據庫,因此在application.yml文件中,我們需要修改端口號和連接的數據庫,注意的是三個微服務提供者的微服務名字保持一樣,也就是如下的配置信息
spring: application: name: microservicecloud-dept 復制代碼負載均衡自測
訪問連接http://localhost:8001/dept/list,http://localhost:8002/dept/list,http://localhost:8003/dept/list得到不同數據庫數據,當我們啟動服務注冊中心7001,7002,7003,再啟動80客戶端,這個時候訪問localhost/consumer/dept/list,每次刷新就會得到不同數據庫的數據。這就是Ribbon默認的輪詢算法的負載均衡。
Ribbon核心組件IRule
Ribbon負載均衡算法
Ribbon默認提供的是輪詢的負載均衡算法,完整了還有如下
| RandomRule | 隨機 |
| AvaliabilityFilteringRule | 會先過濾由于多次訪問故障而處于斷路器跳閘的狀態的服務和并發的連接數量超過閾值的服務,然后對剩余的服務列表按照輪詢策略 |
| WeightedResponseTimeRule | 根據平均響應時間計算所有服務的權重,響應時間越快服務權重越大 |
| RetryRule | 先按照RoundRobinRule策略獲取服務,如果獲取服務失敗會在指定時間內重試 |
| BestAvailableRule | 會先過濾掉由于多次訪問故障二處于斷路器跳閘狀態的服務,然后選擇一個并發量最小的服務 |
| ZoneAvoidanceRule | 默認規則,復合判斷server所在的區域的性能和server的可用性選擇服務器 |
Ribbon負載均衡算法使用方法
在客戶端的配置類ConfigBean.java中添加IRule的實現
public class ConfigBean {public RestTemplate geRestTemplate(){return new RestTemplate();}public IRule myRule(){return new RandomRule();} } 復制代碼Ribbon自定義
如果不使用Ribbon默認的七種負載均衡算法,這個時候就需要使用自定義負載均衡算法
客戶端主啟動類使用注解@RibbonClient
(name="MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class) public class DeptConsumer80_App {public static void main(String[] args) {SpringApplication.run(DeptConsumer80_App.class, args);} } 復制代碼特此說明
RibbonClient注解中的MySelfRule類使我們自定義負載均衡算法的類,但是,這個自定義配置類不能放在@ComponentScan所掃描的當前包下以及子包下,否則我們這個自定義的配置類會被所有的Ribbon客戶端所共享,也就說,達不到我們特殊化定制的目的。舉例說明,自定義配置類不能放在項目主啟動類所有的包以及子包下,因為主啟動類使用注解@SpringBootApplication,這個注解點進去使用@ComponentScan注解
自定義負載均衡算法
輪詢算法中每一個服務輪詢一次,現在需求是每一個服務調用五次后在輪詢下一個服務
自定義配置類
package com.luo.myrule;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.netflix.loadbalancer.IRule; public class MySelfRule {public IRule myRule(){return new RandomRule_lky();} } 復制代碼自定義算法類
package com.luo.myrule;import java.util.List;import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.AbstractLoadBalancerRule; import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.Server;public class RandomRule_lky extends AbstractLoadBalancerRule{// total = 0 // 當total==5以后,我們指針才能往下走,// index = 0 // 當前對外提供服務的服務器地址,// total需要重新置為零,但是已經達到過一個5次,我們的index = 1// 分析:我們5次,但是微服務只有8001 8002 8003 三臺,OK?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();int serverCount = allList.size();if (serverCount == 0) {return null;} // private int total = 0; // 總共被調用的次數,目前要求每臺被調用5次 // private int currentIndex = 0; // 當前提供服務的機器號if(total < 5){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;}public Server choose(Object key){return choose(getLoadBalancer(), key);}public void initWithNiwsConfig(IClientConfig clientConfig){} } 復制代碼總結
以上是生活随笔為你收集整理的JavaEE进阶知识学习-----SpringCloud(六)Ribbon负载均衡的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在windowService用Proce
- 下一篇: Java 10更新汇总,新的编译器通吃主