Java Spring Cloud 負載均衡詳解
1. Ribbon 客戶端負載均衡
1.1 Ribbon 概述
- Ribbon 是 Netflix 提供的一個基於 HTTP 和 TCP 的客戶端負載均衡工具。
- Ribbon主要有兩個功能:
- 簡化遠程調用
- 負載均衡
客戶端負載均衡和服務端負載均衡的區別
服務端負載均衡
- 負載均衡算法在服務端
- 由負載均衡器維護服務地址列表
客戶端負載均衡
- 負載均衡算法在客戶端
- 客戶端維護服務地址列表
1.2 Ribbon 遠程調用
Ribbon 可以簡化 RestTemplate 的遠程調用。
原來的 Provider 中的遠程調用如下:
@GetMapping("/goods/{id}") public Goods findGoodsById(@PathVariable("id") int id){ //演示discoveryClient 使用 List<ServiceInstance> instances = discoveryClient.getInstances("eureka-provider"); //判斷集合是否有數據 if(instances == null || instances.size() == 0){ //集合沒有數據 return null; } ServiceInstance instance = instances.get(0); String host = instance.getHost();//獲取ip int port = instance.getPort();//獲取端口 System.out.println(host); System.out.println(port); String url = "http://"+host+":"+port+"/goods/findOne/"+id; // 3. 調用方法 Goods goods = restTemplate.getForObject(url, Goods.class); return goods; }
使用 Ribbon 簡化 restTemplate 調用:
1.在聲明 restTemplate 的 Bean 時候,添加一個註解:@LoadBalanced
@Configuration public class RestTemplateConfig { @LoadBalanced @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } }
2.在使用 restTemplate 發起請求時,需要定義 url 時,host:port 可以替換為服務提供方的應用名稱
@GetMapping("/goods2/{id}") public Goods findGoodsById2(@PathVariable("id") int id){ String url = "http://EUREKA-PROVIDER/goods/findOne/"+id; // 3. 調用方法 Goods goods = restTemplate.getForObject(url, Goods.class); return goods; }
1.3 Ribbon 負載均衡
1.既然要負載均衡,那麼我們就需要啟動多個 Provider 服務來構成集群,在啟動前先對 Provider 改造一下,讓它將端口號設置到商品標題上
package com.zt.provider.controller; /** * Goods Controller 服務提供方 */ @RestController @RequestMapping("/goods") public class GoodsController { @Value("${server.port}") private int port; @Autowired private GoodsService goodsService; @GetMapping("/findOne/{id}") public Goods findOne(@PathVariable("id") int id){ Goods goods = goodsService.findOne(id); goods.setTitle(goods.getTitle() + ":" + port);//將端口號,設置到商品標題上 return goods; } }
2.接下來以多例啟動 Provider,選擇 edit configurations –> 勾選 allow parallel run
3.然後分別以 8001 和 8002 端口號分別啟動 Provider
4.啟動 Consumer 進行測試
http://localhost:9000/order/goods2/1
采用輪詢的方式,調用兩個 8001 和 8002 兩個 Provider
{"id":1,"title":"華為手機:8001","price":3999.0,"count":10000}
{"id":1,"title":"華為手機:8002","price":3999.0,"count":10000}
1.4 Ribbon 負載均衡策略
策略類 | 命名 | 描述 |
---|---|---|
RandomRule | 隨機策略 | 隨機選擇server |
RoundRobinRule | 輪詢策略 | 輪詢選擇, 輪詢index,選擇index對應位置的Server; |
RetryRule | 重試策略 | 對選定的負載均衡策略機上重試機制,在一個配置時間段內當選擇Server不成功,則一直嘗試使用subRule的方式選擇一個可用的server; |
BestAvailableRule | 最低並發策略 | 逐個考察server,如果server斷路器打開,則忽略,再選擇其中並發鏈接最低的server |
AvailabilityFilteringRule | 可用過濾策略 | 過濾掉一直失敗並被標記為circuit tripped的server,過濾掉那些高並發鏈接的server(active connections超過配置的閾值)或者使用一個AvailabilityPredicate來包含過濾server的邏輯,其實就就是檢查status裡記錄的各個Server的運行狀態; |
ResponseTimeWeightedRule | 響應時間加權重策略 | 根據server的響應時間分配權重,響應時間越長,權重越低,被選擇到的概率也就越低。響應時間越短,權重越高,被選中的概率越高,這個策略很貼切,綜合瞭各種因素,比如:網絡,磁盤,io等,都直接影響響應時間 |
ZoneAvoidanceRule | 區域權重策略 | 綜合判斷server所在區域的性能,和server的可用性,輪詢選擇server並且判斷一個AWS Zone的運行性能是否可用,剔除不可用的Zone中的所有server |
設置負載均衡策略
1.編碼方式
在 Consumer 服務編寫配置類,采用隨即策略
package com.zt.consumer.config; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RandomRule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyRule { @Bean public IRule rule() { return new RandomRule(); } }
在啟動類上設置給指定服務開啟負載均衡策略,比如給 EUREKA-PROVIDER 開啟策略 MyRule
package com.zt.consumer; @SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient /* 配置Ribbon的負載均衡策略 name * name:設置 服務提供方的 應用名稱 * configuration:設置負載均衡Bean */ @RibbonClient(name="EUREKA-PROVIDER",configuration = MyRule.class) public class ConsumerApp { public static void main(String[] args) { SpringApplication.run(ConsumerApp.class, args); } }
2.配置方式
# 配置的方式設置Ribbon的負載均衡策略 EUREKA-PROVIDER: # 設置的服務提供方的 應用名稱 ribbon: NFloadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 策略類
總結
本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!
推薦閱讀:
- SpringCloud筆記(Hoxton)Netflix之Ribbon負載均衡示例代碼
- spring cloud 集成 ribbon負載均衡的實例代碼
- SpringCloud服務的發現與調用詳解
- Spring Cloud-Feign服務調用的問題及處理方法
- 深入理解Java SpringCloud Ribbon 負載均衡