SpringCloud(7)Ribbon負載均衡
一:學習目標
①什麼是Ribbon,②Ribbon解決了什麼問題,③負載均衡不同方案的區別,④Ribbon負載均衡策略,⑤Ribbon入門案列,⑥Ribbon點對點直連(跳過負載均衡,在測試的時候更加方便),⑦Ribbon負載均衡策略設定.
二:什麼是Ribbon
(就是我們消費方進行呼叫服務的時候(服務是好多個),這個時候我們需要從這麼多服務中挑選)選擇哪個結點(怎麼分散的選取對應的服務提供方呢)
我們本來有註冊中心,服務提供方,服務消費方;
服務提供方將服務提供方將服務註冊到註冊中心後,我們的服務消費方從註冊中心中拉取列表,(重點)這個時候我們的消費方就遠端呼叫提供方(我們的Ribbon就在這個實現負載均衡)
①:Ribbon 是一個基於 HTTP 和 TCP 的 客服端 負載均衡工具,它是基於 Netflflix Ribbon 實現的。它不像 Spring Cloud 服務註冊中心、配置中心、API 閘道器那樣獨立部署,但是它幾乎存在於每個 Spring Cloud微服務中。包括 Feign 提供的宣告式服務呼叫也是基於該 Ribbon 實現的。Ribbon 預設提供很多種負載均衡演算法,例如輪詢、隨機等等。甚至包含自定義的負載均衡演算法。
三:負載均衡不同方案的區別
目前業界主流的負載均衡方案可分成兩類(Ribbon屬於第二種): 集中式負載均衡(伺服器負載均衡),即在 consumer 和 provider 之間使用獨立的負載均衡設施(可以是硬 件,如 F5,也可以是軟體,如 nginx),由該設施負責把訪問請求通過某種策略轉發至 provider;(左圖) 程序內負載均衡(客戶端負載均衡)Ribbon屬於這種,將負載均衡邏輯整合到 consumer,consumer 從服務註冊中心獲知有 哪些地址可用,然後自己再從這些地址中選擇出一個合適的 provider。Ribbon 屬於後者,它只是一個類庫,集 成於 consumer 程序,consumer 通過它來獲取 provider 的地址。(右圖)四:Ribbon負載均衡策略
①輪詢策略(預設)
策略對應類名: RoundRobinRule 實現原理:輪詢策略表示每次都順序取下一個 provider,比如一共有 5 個 provider,第 1 次取第 1 個,第 2 次取第 2 個,第 3 次取第 3 個,以此類推。 ②權重輪詢策略策略對應類名: WeightedResponseTimeRule 實現原理: 根據每個 provider 的響應時間分配一個權重,響應時間越長,權重越小,被選中的可能性越低。 原理:一開始為輪詢策略,並開啟一個計時器,每 30 秒收集一次每個 provider 的平均響應時間,當資訊足夠時,給每個 provider 附上一個權重,並按權重隨機選擇 provider,高權越重的 provider 會被高概率選中。 ③隨機策略
策略對應類名: RandomRule 實現原理:從 provider 列表中隨機選擇一個。 ④最少併發數策略
策略對應類名: BestAvailableRule 實現原理:選擇正在請求中的併發數最小的 provider,除非這個 provider 在熔斷中。 ⑤重試策略(輪詢策略的增強版)
策略對應類名: RetryRule 實現原理:其實就是輪詢策略的增強版,輪詢策略服務不可用時不做處理,重試策略服務不可用時會重新嘗試集 群中的其他節點。 ⑥可用性敏感策略
策略對應類名: AvailabilityFilteringRule 實現原理:過濾效能差的 provider 第一種:過濾掉在 Eureka 中處於一直連線失敗的 provider。 第二種:過濾掉高併發(繁忙)的 provider。 ⑦區域敏感性策略
策略對應類名: ZoneAvoidanceRule 實現原理: 以一個區域為單位考察可用性,對於不可用的區域整個丟棄,從剩下區域中選可用的 provider。 如果這個 ip 區域內有一個或多個例項不可達或響應變慢,都會降低該 ip 區域內其他 ip 被選中的權 重。 五:Ribbon入門案列 ①首先建立一個service-prover02的module ②將我們的ervice-prover的pom,以及包和類複製過來 ③將service-prover的yml複製過來,把埠改為7071 ④將Eureka-server03啟動和Eureka-server啟動,將service-prover與service-prover02啟動 ⑤檢視我們現在的服務
⑥我們修改一下我們的consumer中的impl類
將//負載均衡器 Ribbon 負載均衡器
@Autowired
private LoadBalancerClient loadBalancerClient;設定這個當做我們的連線
public order selectOrderById(Integer id) { return new order(id,"order-001","中國",319940D,selectProductListBydiscoveryClient1()); } private List<product> selectProductListBydiscoveryClient1(){ StringBuffer sb=null; //獲取服務列表 這裡沒有了獲取服務列表 //根據服務名稱獲取服務 ServiceInstance si=loadBalancerClient.choose("SERVICE-PRODUCT"); if (si==null) return null; sb=new StringBuffer(); sb.append("http://"+si.getHost()+":"+si.getPort()+"/product/list"); //為了測試我們的Ribbon策略,打印出來我們具體呼叫的是哪個生產者 System.out.println("sb.tostring:"+sb.toString()); //ResponseEntity : 封裝了返回資料 ResponseEntity<List<product>> response=restTemplate.exchange( sb.toString(), HttpMethod.GET, null, new ParameterizedTypeReference<List<product>>(){} ); return response.getBody(); }
記得把啟動類的負載均衡去掉:
⑦啟動consumer應用
在輸入
檢視我們的console輸出臺(呼叫的是prover的):
再次請求一下結果(請求的是prover02):
再多次請求一下(預設採用的是輪詢策略):
六:Ribbon負載均衡策略設定
①全域性的:在啟動類或配置類中注入負載均衡策略物件。所有服務請求均使用該策略。
我們在啟動類中注入Bean,全域性都是以這種方式進行遠端呼叫(我們使用的是隨機策略)
//@EnableEurekaClient //@EnableEurekaClient 註解,目前版本如果配置了Client註冊中心,預設會開啟該註解 @SpringBootApplication public class ServiceConsumerApplication { //這裡直接注入負載均衡的策略,我們這裡使用的是隨機 @Bean public RandomRule randomRule(){ return new RandomRule(); } @Bean // @LoadBalanced //負載均衡註解 public RestTemplate restTemplate(){ return new RestTemplate(); } public static void main( String[] args ) { SpringApplication.run(ServiceConsumerApplication.class,args); } }
現在進行訪問(這是隨機訪問的結果):
②區域性(設定配置檔案,看具體的哪個微服務用什麼策略)這個是在消費者的配置檔案寫具體生產者的策略
修改配置檔案指定服務的負載均衡策略(NFLoadBalancerRuleClassName為策略)。格式: 服務應用名.ribbon.NFLoadBalancerRuleClassName我們進行訪問(這裡的策略是隨機的策略):
七:Ribbon點對點直連(沒有從註冊中心拉取,直接通過Ribbon點對點直連)
指的是我們的消費者跳過註冊中心,直接去請求生產者(一般在我們的測試環境中用)
①先開啟consumer中的pom檔案中,將eureka-client的登出掉
②把consumer中的yml檔案中的eureka也登出掉
③接下來我們把Ribbon的依賴拉進來(我們用的是Ribbon直連的)
④我們現在要直連,直連的服務是哪幾個呢,需要在yml中配置一下
⑤將顯示的Eureka關閉,因為預設是開啟的
⑥:現在只需要啟動服務提供者和服務消費者
現在我們的prover與prover02 都是報錯的,因為我們沒有Eureka啟動,所以會報錯,當我們啟動consumer後,我們進行訪問:
訪問 關閉 Eureka 註冊中心,服務提供者由於無法連線至註冊中心所以會報連線異常。但是服務是可以正常可消費 的,所以目前使用的是點對點的方式來進行呼叫的。