spring cloud 之 用戶端負載平衡 Ribbon,cloudribbon
一、負載平衡
負載平衡(Load Balance): 建立在現有網路結構之上,它提供了一種廉價有效透明的方法擴充網路裝置和伺服器的頻寬、增加輸送量、加強網路資料處理能力、提高網路的靈活性和可用性。其意思就是分攤到多個操作單元上進行執行,例如Web伺服器、FTP伺服器、企業關鍵應用伺服器和其它關鍵任務伺服器等,從而共同完成工作任務。
1、服務端負載平衡:用戶端請求到負載平衡伺服器,負載平衡伺服器根據自身的演算法將該請求轉給某台真正提供業務的伺服器,該伺服器將響應資料給負載平衡伺服器,負載平衡伺服器最後將資料返回給客服端。(nginx)
2、客服端負載平衡:基於用戶端的負載平衡,簡單的說就是在用戶端程式裡面,自己設定一個調度演算法,在向伺服器發起請求的時候,先執行調度演算法計算出向哪台伺服器發起請求,然後再發起請求給伺服器。
基於用戶端負載平衡的特點:
- 由用戶端內部程式實現,不需要額外的負載平衡器軟硬體投入。
- 程式內部需要解決商務服務器停用問題,伺服器故障對應用程式的透明度小。
- 程式內部需要解決商務服務器壓力過載的問題。
二、Ribbon實現用戶端的負載平衡
我們使用spring boot 來測試。
pom檔案:
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.jalja.org</groupId> <artifactId>spring-consumer-server-ribbon</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR4</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
application.yml
stores: ribbon: listOfServers: www.baidu.com,www.jalja.org,www.163.com
Ribbon的負載平衡策略
1、RoundRobinRule(輪詢模式) public class RoundRobinRule extends AbstractLoadBalancerRule roundRobin方式輪詢選擇server 輪詢index,選擇index對應位置的server 該策略也是ribbon的預設策略
SpringCloudRibbonApplication.java
@SpringBootApplication@EnableDiscoveryClient@RestControllerpublic class SpringCloudRibbonApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudRibbonApplication.class, args); } @Autowired private LoadBalancerClient loadBalancer; @RequestMapping(value="static") public String staticRibbon(){ ServiceInstance instance = loadBalancer.choose("stores"); URI storesUri = URI.create(String.format("http://%s:%s", instance.getHost(), instance.getPort())); System.out.println(storesUri); return "static"; }}
連續請求6次執行結果:
http://www.baidu.com:80
http://www.jalja.org:80
http://www.163.org:80
http://www.baidu.com:80
http://www.jalja.org:80
http://www.163.org:80
2、RandomRule(隨機策略) public class RandomRule extends AbstractLoadBalancerRule 隨機播放一個server 在index上隨機,選擇index對應位置的server。
在設定檔application.yml加入
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
stores: ribbon: listOfServers: www.baidu.com,www.jalja.org,www.163.org #隨機 NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
在SpringCloudRibbonApplication.java 中加入
@Bean public IRule ribbonRule() { return new RandomRule();//這裡配置策略,和設定檔對應 }
執行6次的結果:
http://www.baidu.com:80http://www.baidu.com:80http://www.baidu.com:80http://www.163.org:80http://www.baidu.com:80http://www.jalja.org:80
3、BestAvailableRule(並發量) public class BestAvailableRule extends ClientConfigEnabledRoundRobinRule 選擇一個最小的並發請求的server 逐個考察Server,如果Server被tripped了,則忽略,在選擇其中ActiveRequestsCount最小的server
在設定檔application.yml加入
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.BestAvailableRule
在SpringCloudRibbonApplication.java 中加入
@Bean public IRule ribbonRule() { return new BestAvailableRule();//這裡配置策略,和設定檔對應 }
執行6次的結果:
http://www.baidu.com:80http://www.baidu.com:80http://www.baidu.com:80http://www.baidu.com:80http://www.baidu.com:80http://www.baidu.com:80
4、AvailabilityFilteringRule(伺服器狀態) public class AvailabilityFilteringRule extends PredicateBasedRule 過濾掉那些因為一直串連失敗的被標記為circuit tripped的後端server,並過濾掉那些高並發的的後端server(active connections 超過配置的閾值) 使用一個AvailabilityPredicate來包含過濾server的邏輯,其實就就是檢查status裡記錄的各個server的運行狀態
5、WeightedResponseTimeRule(根據回應時間) public class WeightedResponseTimeRule extends RoundRobinRule 根據回應時間分配一個weight,相應時間越長,weight越小,被選中的可能性越低。 一個後台線程週期性從status裡面讀取評價回應時間,為每個server計算一個weight。Weight的計算也比較簡單responsetime 減去每個server自己平均的responsetime是server的權重。當剛開始運行,沒有形成statas時,使用roubine策略選擇server。
6、RetryRule(根據策略+重試)public class RetryRule extends AbstractLoadBalancerRule對選定的負載平衡策略機上重試機制。在一個配置時間段內當選擇server不成功,則一直嘗試使用subRule的方式選擇一個可用的server
7、ZoneAvoidanceRule(Zone狀態+服務狀態)public class ZoneAvoidanceRule extends PredicateBasedRule複合判斷server所在地區的效能和server的可用性選擇server使用ZoneAvoidancePredicate和AvailabilityPredicate來判斷是否選擇某個server,前一個判斷判定一個zone的運行效能是否可用,剔除停用zone(的所有server),AvailabilityPredicate用於過濾掉串連數過多的Server。
4、5、6、7這些策略使用方式與上述方式相同這裡不在示範