什麼是 Ribbon
Ribbon 是一個基於 HTTP 和 TCP 的 客服端負載均衡工具,它是基於 Netflix Ribbon 實現的。
它不像 Spring Cloud 服務註冊中心、配置中心、API 閘道器那樣獨立部署,但是它幾乎存在於每個 Spring Cloud 微服務中。包括 Feign 提供的宣告式服務呼叫也是基於該 Ribbon 實現的。
Ribbon 預設提供很多種負載均衡演算法,例如輪詢、隨機等等。甚至包含自定義的負載均衡演算法。
Ribbon 解決了什麼問題Ribbon 提供了一套微服務的負載均衡解決方案。
負載均衡不同方案的區別目前業界主流的負載均衡方案可分成兩類:
集中式負載均衡(伺服器負載均衡),即在 consumer 和 provider 之間使用獨立的負載均衡設施(可以是硬體,如 F5,也可以是軟體,如 nginx),由該設施負責把訪問請求透過某種策略轉發至 provider;程序內負載均衡(客戶端負載均衡),將負載均衡邏輯整合到 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 入門案例eureka-demo 聚合工程。SpringBoot 2.2.4.RELEASE、Spring Cloud Hoxton.SR1。
Ribbon 中對於叢集的服務採用的負載均衡策略預設是輪詢。
建立專案使用學習 Eureka 時的 eureka-demo 專案,在該專案中建立子專案 service-provider02
新增依賴pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>
配置檔案application.yml
server: port: 7071 # 埠spring: application: name: service-provider # 應用名稱(叢集下相同)# 配置 Eureka Server 註冊中心eureka: instance: prefer-ip-address: true # 是否使用 ip 地址註冊 instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port client: service-url: # 設定服務註冊中心地址 defaultZone: http://root:123456@localhost:8761/eureka/,http://root:123456@localhost:8762/eureka/# 度量指標監控與健康檢查management: endpoints: web: exposure: include: shutdown # 開啟 shutdown 端點訪問 endpoint: shutdown: enabled: true # 開啟 shutdown 實現優雅停服
服務及啟動類將所有程式碼複製貼上一份至 server-provider02,修改啟動類名稱即可。
ServiceProvider02Application.java
package com.example;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication public class ServiceProvider02Application {
public static void main(String[] args) { SpringApplication.run(ServiceProvider02Application.class, args);}
}
為了更直觀地看到負載均衡的效果,我們在 service-consumer 專案中將服務地址列印至控制檯。
註冊中心執行完整的 Eureka 環境,訪問:http://localhost:8761/ 可以看到現在已經有兩個服務提供者。
消費服務多次訪問:http://localhost:9090/order/1 可以看到預設使用的是輪詢策略。
Ribbon 負載均衡策略設定全域性在啟動類或配置類中注入負載均衡策略物件。所有服務請求均使用該策略。
@Bean public RandomRule randomRule() { return new RandomRule(); }
多次訪問:http://localhost:9090/order/1 結果如下:
區域性修改配置檔案指定服務的負載均衡策略。格式:服務應用名.ribbon.NFLoadBalancerRuleClassName
# 負載均衡策略# service-provider 為呼叫的服務的名稱service-provider: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
多次訪問:http://localhost:9090/order/1 結果如下:
Ribbon 點對點直連點對點直連是指繞過註冊中心,直接連線服務提供者獲取服務,一般在測試階段使用比較多。
新增依賴在呼叫方 pom 檔案中引入 ribbon 依賴,需要注意的是如果 pom 中有 Eureka 的依賴,則需要去除 Eureka 的依賴。
配置檔案配置檔案中關閉 Eureka,新增直連的服務地址。如果不設定負載均衡策略預設使用輪詢策略。
# 負載均衡策略# service-provider 為呼叫的服務的名稱service-provider: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 點對點直連模式,指定具體的 Provider 服務列表,多個用逗號隔開 listOfServers: http://localhost:7070,http://localhost:7071# 關閉 Eureka 實現 Ribbon 點對點直連ribbon: eureka: enabled: false # false:關閉,true:開啟
訪問
關閉 Eureka 註冊中心,服務提供者由於無法連線至註冊中心所以會報連線異常。但是服務是可以正常可消費的,所以目前使用的是點對點的方式來進行呼叫的。
多次訪問:http://localhost:9090/order/1 結果如下:
至此 Ribbon 負載均衡所有的知識點就講解結束了。