1. 簡介
Netflix 的 Ribbon 是一個跨進程通信 (IPC) 雲庫。Ribbon 主要提供客户端負載均衡算法。
除了客户端負載均衡算法之外,Ribbon 還提供其他功能:
- 服務發現集成 – Ribbon 負載均衡器在動態環境中(如雲環境)提供服務發現。Ribbon 庫包含與 Eureka 和 Netflix 服務發現組件的集成
- 容錯性 – Ribbon API 可以動態地確定在運行環境中服務器是否可用,並檢測到下線服務器
- 可配置的負載均衡規則 – Ribbon 內置支持 RoundRobinRule、AvailabilityFilteringRule、WeightedResponseTimeRule 等規則,並支持定義自定義規則
Ribbon API 基於“命名客户端”的概念工作。在配置 Ribbon 的應用程序配置文件時,我們為負載均衡使用的服務器列表提供一個名稱。
讓我們來試用一下。
2. 依賴管理
Netflix Ribbon API 可以通過在我們的 pom.xml 中添加以下依賴項添加到項目中。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>最新版本的庫可以在這裏找到:這裏。
3. 示例應用程序
為了演示 Ribbon API 的工作原理,我們構建了一個使用 Spring 的 RestTemplate 框架的示例微服務應用程序,並在此基礎上增強了它,同時引入了 Spring Cloud Netflix API 和 Ribbon API。
我們將使用 Ribbon 的一種負載均衡策略,即 WeightedResponseTimeRule,在我們的應用程序中,在配置文件的命名客户端下定義了 2 台服務器,從而實現客户端之間的負載均衡。
4. 調散配置
Ribbon API 允許我們配置負載均衡器的以下組件:
- 規則 – 用於指定我們在應用程序中使用的負載均衡規則的邏輯組件
- 心跳探測 – 用於實時確定服務器可用性的組件
- 服務器列表 – 可以是動態或靜態。 在我們的情況下,我們使用靜態服務器列表,因此我們在應用程序配置文件中直接定義它們
讓我們為庫編寫一個簡單的配置:
public class RibbonConfiguration {
@Autowired
IClientConfig ribbonClientConfig;
@Bean
public IPing ribbonPing(IClientConfig config) {
return new PingUrl();
}
@Bean
public IRule ribbonRule(IClientConfig config) {
return new WeightedResponseTimeRule();
}
}請注意,我們使用了 加權響應時間規則 (WeightedResponseTimeRule) 來確定服務器,並使用 PingUrl 機制實時確定服務器的可用性。
根據該規則,每個服務器的權重根據其平均響應時間確定,響應時間越短,權重就越低。該規則會隨機選擇一個權重較低的服務器。
同時,PingUrl 會對每個 URL 進行 ping,以確定服務器的可用性。
5. application.yml
以下是為本示例應用程序創建的 application.yml 配置文件:
spring:
application:
name: spring-cloud-ribbon
server:
port: 8888
ping-server:
ribbon:
eureka:
enabled: false
listOfServers: localhost:9092,localhost:9999
ServerListRefreshInterval: 15000在以上文件中,我們指定了:
- 應用程序名稱
- 應用程序端口號
- 客户端名稱(用於服務器列表): “ping-server”
- 禁用 Eureka 服務發現組件,通過將 eureka 設置為 enabled 為 false
- 定義了用於負載均衡的服務器列表,在本例中為 2 台服務器
- 配置了服務器刷新間隔,使用 ServerListRefreshInterval
6. RibbonClient
現在,我們來設置主應用程序組件片段——這裏我們使用 RibbonClient 來啓用負載均衡,而不是簡單的 RestTemplate。
@SpringBootApplication
@RestController
@RibbonClient(
name = "ping-a-server",
configuration = RibbonConfiguration.class)
public class ServerLocationApp {
@Autowired
RestTemplate restTemplate;
@RequestMapping("/server-location")
public String serverLocation() {
return this.restTemplate.getForObject(
"http://ping-server/locaus", String.class);
}
public static void main(String[] args) {
SpringApplication.run(ServerLocationApp.class, args);
}
}以下是 RestTemplate 的配置:
@Configuration
public class RestTemplateConfiguration{
@LoadBalanced
@Bean
RestTemplate getRestTemplate() {
return new RestTemplate();
}
}我們定義了一個帶有@RestController註解的控制器類,並使用名稱和配置類對該類進行了@RibbonClient註解。
我們定義的配置類與我們在之前定義的相同類相同,該類為本應用程序提供了所需的 Ribbon API 配置。
請注意,我們使用@LoadBalanced註解了RestTemplate,這表明我們希望它進行負載均衡,並且在這種情況下是使用 Ribbon 實現的。
7. 彈性容錯機制在Ribbon中的應用
正如我們在本文前面所述,Ribbon API不僅提供客户端負載均衡算法,還內置了彈性容錯機制。
正如之前所説,Ribbon API通過在定期間隔內不斷地“ping”服務器來確定服務器的可用性,並且具有跳過不可用服務器的能力。
此外,它還實現了斷路器模式,根據指定標準過濾服務器。
斷路器模式通過迅速拒絕向不可用的服務器發送請求,從而最大限度地減少服務器故障對性能的影響,而無需等待超時。可以通過將屬性 niws.loadbalancer.availabilityFilteringRule.filterCircuitTripped 設置為 false 來禁用此斷路器功能。
當所有服務器都不可用,因此沒有服務器可以處理請求時,pingUrl() 將失敗,並且我們收到異常 java.lang.IllegalStateException,帶有消息 “No instances are available to serve the request”。
8. 結論
在本文中,我們討論了 Netflix Ribbon API及其在簡單示例應用程序中的實現。