JavaEE进阶知识学习-----SpringCloud(六)Ribbon负载均衡
Ribbon負(fù)載均衡
Ribbon概述
Spring Cloude Ribbon是基于Netfilx Ribbon實現(xiàn)的一套客戶端 負(fù)載均衡的工具,簡單說,Ribbon是Netfilix發(fā)布的開源項目,主要功能就是提供 客戶端的軟件負(fù)載均衡算法,將Netfilix的中間層服務(wù)連接在一起,Ribbon客戶端組件提供了一系列完善的配置項如連接超時,重試等,簡單說,就是在配置文件中列出Load Balance后面的所有機器,Ribbon會自動的幫助你基于某種算法規(guī)則(簡單輪詢,隨機連接等)去連接這些機器,也可以使用Ribbon自定義負(fù)載均衡算法。LB,即負(fù)載均衡,在微服務(wù)或者分布式集群中常用的一種應(yīng)用。負(fù)載均衡就是將用戶的請求平攤的分配到多個服務(wù)上,從而達到HA,常見的負(fù)載均衡軟件有Nginx,LVS,硬件F5等
Ribbon配置初步
由于Ribbon是客戶端的負(fù)載均衡工具,所以我們需要修改的是客戶端項目microservicecloud-consumer-dept-80
POM.xml文件
<!-- Ribbon相關(guān) --> <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> 復(fù)制代碼修改application.yml文件,添加Eureka的服務(wù)注冊地址
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/ 復(fù)制代碼修改客戶端配置類
由于客戶端使用restTemplate訪問服務(wù)端中的數(shù)據(jù)接口,restTemplate配置在服務(wù)端的配置類中,所以修改如下
public class ConfigBean {public RestTemplate geRestTemplate(){return new RestTemplate();} } 復(fù)制代碼修改客戶端主程序啟動類
public class DeptConsumer80_App {public static void main(String[] args) {SpringApplication.run(DeptConsumer80_App.class, args);} } 復(fù)制代碼修改客戶端訪問類DeptController_Consumer.java
private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT"; 復(fù)制代碼測試
啟動7001,7002,7003三個服務(wù)注冊中心,啟動8001服務(wù)提供者,啟動80客戶端,使用http://localhost/consumer/dept/list可以渠道對應(yīng)的數(shù)據(jù),在DeptController_Consumer使用的是http://MICROSERVICECLOUD-DEPT服務(wù)名稱來調(diào)用服務(wù)的接口,相比之前的http://localhost:8001,Ribbon和Eureka整合后,Consumer可以直接通過服務(wù)名稱來調(diào)用服務(wù),而不再關(guān)心地址和端口號。
Ribbon負(fù)載均衡
目前只有一個microservicecloud-provider-dept-8001服務(wù)提供者,為了實現(xiàn)Ribbon的負(fù)載均衡,所以我們需要多個服務(wù)提供者實例,新建microservicecloud-provider-dept-8002,microservicecloud-provider-dept-8003兩個Module。參考8001的pom.xml文件修改8002,8003的pom.xml文件。拷貝8001中的所以類和配置文件mybatis和application.yml文件,將主啟動類修改為對應(yīng)的名字
microservicecloud-provider-dept-8002服務(wù)提供者
使用的數(shù)據(jù)庫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('開發(fā)部',DATABASE()); INSERT INTO dept(dname,db_source) VALUES('人事部',DATABASE()); INSERT INTO dept(dname,db_source) VALUES('財務(wù)部',DATABASE()); INSERT INTO dept(dname,db_source) VALUES('市場部',DATABASE()); INSERT INTO dept(dname,db_source) VALUES('運維部',DATABASE()); 復(fù)制代碼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 # 當(dāng)前數(shù)據(jù)源操作類型 driver-class-name: org.gjt.mm.mysql.Driver # mysql驅(qū)動包 url: jdbc:mysql://localhost:3306/cloudDB02 # 數(shù)據(jù)庫名稱 username: root password: 1234 dbcp2: min-idle: 5 # 數(shù)據(jù)庫連接池的最小維持連接數(shù) initial-size: 5 # 初始化連接數(shù) max-total: 5 # 最大連接數(shù) max-wait-millis: 200 復(fù)制代碼microservicecloud-provider-dept-8003服務(wù)提供者
使用的數(shù)據(jù)庫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('開發(fā)部',DATABASE()); INSERT INTO dept(dname,db_source) VALUES('人事部',DATABASE()); INSERT INTO dept(dname,db_source) VALUES('財務(wù)部',DATABASE()); INSERT INTO dept(dname,db_source) VALUES('市場部',DATABASE()); INSERT INTO dept(dname,db_source) VALUES('運維部',DATABASE()); 復(fù)制代碼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 # 當(dāng)前數(shù)據(jù)源操作類型 driver-class-name: org.gjt.mm.mysql.Driver # mysql驅(qū)動包 url: jdbc:mysql://localhost:3306/cloudDB03 # 數(shù)據(jù)庫名稱 username: root password: 1234 dbcp2: min-idle: 5 # 數(shù)據(jù)庫連接池的最小維持連接數(shù) initial-size: 5 # 初始化連接數(shù) max-total: 5 # 最大連接數(shù) max-wait-millis: 200 復(fù)制代碼微服務(wù)提供者說明
三個微服務(wù)提供者連接不同的數(shù)據(jù)庫,因此在application.yml文件中,我們需要修改端口號和連接的數(shù)據(jù)庫,注意的是三個微服務(wù)提供者的微服務(wù)名字保持一樣,也就是如下的配置信息
spring: application: name: microservicecloud-dept 復(fù)制代碼負(fù)載均衡自測
訪問連接http://localhost:8001/dept/list,http://localhost:8002/dept/list,http://localhost:8003/dept/list得到不同數(shù)據(jù)庫數(shù)據(jù),當(dāng)我們啟動服務(wù)注冊中心7001,7002,7003,再啟動80客戶端,這個時候訪問localhost/consumer/dept/list,每次刷新就會得到不同數(shù)據(jù)庫的數(shù)據(jù)。這就是Ribbon默認(rèn)的輪詢算法的負(fù)載均衡。
Ribbon核心組件IRule
Ribbon負(fù)載均衡算法
Ribbon默認(rèn)提供的是輪詢的負(fù)載均衡算法,完整了還有如下
| RandomRule | 隨機 |
| AvaliabilityFilteringRule | 會先過濾由于多次訪問故障而處于斷路器跳閘的狀態(tài)的服務(wù)和并發(fā)的連接數(shù)量超過閾值的服務(wù),然后對剩余的服務(wù)列表按照輪詢策略 |
| WeightedResponseTimeRule | 根據(jù)平均響應(yīng)時間計算所有服務(wù)的權(quán)重,響應(yīng)時間越快服務(wù)權(quán)重越大 |
| RetryRule | 先按照RoundRobinRule策略獲取服務(wù),如果獲取服務(wù)失敗會在指定時間內(nèi)重試 |
| BestAvailableRule | 會先過濾掉由于多次訪問故障二處于斷路器跳閘狀態(tài)的服務(wù),然后選擇一個并發(fā)量最小的服務(wù) |
| ZoneAvoidanceRule | 默認(rèn)規(guī)則,復(fù)合判斷server所在的區(qū)域的性能和server的可用性選擇服務(wù)器 |
Ribbon負(fù)載均衡算法使用方法
在客戶端的配置類ConfigBean.java中添加IRule的實現(xiàn)
public class ConfigBean {public RestTemplate geRestTemplate(){return new RestTemplate();}public IRule myRule(){return new RandomRule();} } 復(fù)制代碼Ribbon自定義
如果不使用Ribbon默認(rèn)的七種負(fù)載均衡算法,這個時候就需要使用自定義負(fù)載均衡算法
客戶端主啟動類使用注解@RibbonClient
(name="MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class) public class DeptConsumer80_App {public static void main(String[] args) {SpringApplication.run(DeptConsumer80_App.class, args);} } 復(fù)制代碼特此說明
RibbonClient注解中的MySelfRule類使我們自定義負(fù)載均衡算法的類,但是,這個自定義配置類不能放在@ComponentScan所掃描的當(dāng)前包下以及子包下,否則我們這個自定義的配置類會被所有的Ribbon客戶端所共享,也就說,達不到我們特殊化定制的目的。舉例說明,自定義配置類不能放在項目主啟動類所有的包以及子包下,因為主啟動類使用注解@SpringBootApplication,這個注解點進去使用@ComponentScan注解
自定義負(fù)載均衡算法
輪詢算法中每一個服務(wù)輪詢一次,現(xiàn)在需求是每一個服務(wù)調(diào)用五次后在輪詢下一個服務(wù)
自定義配置類
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();} } 復(fù)制代碼自定義算法類
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 // 當(dāng)total==5以后,我們指針才能往下走,// index = 0 // 當(dāng)前對外提供服務(wù)的服務(wù)器地址,// total需要重新置為零,但是已經(jīng)達到過一個5次,我們的index = 1// 分析:我們5次,但是微服務(wù)只有8001 8002 8003 三臺,OK?private int total = 0; // 總共被調(diào)用的次數(shù),目前要求每臺被調(diào)用5次private int currentIndex = 0; // 當(dāng)前提供服務(wù)的機器號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; // 總共被調(diào)用的次數(shù),目前要求每臺被調(diào)用5次 // private int currentIndex = 0; // 當(dāng)前提供服務(wù)的機器號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){} } 復(fù)制代碼總結(jié)
以上是生活随笔為你收集整理的JavaEE进阶知识学习-----SpringCloud(六)Ribbon负载均衡的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在windowService用Proce
- 下一篇: Java 10更新汇总,新的编译器通吃主