概述
Netflix Ribbon 是一个跨进程通信(Inter Process Communication,简称 IPC)的云端库,主要提供客户端负载均衡算法。除了客户端负载均衡算法,Ribbon 还提供了其他功能:
- 服务发现集成:在动态环境如云中,Ribbon 负载均衡器支持服务发现。它与 Netflix 的 Eureka 服务发现组件进行了集成。
- 故障容错性:Ribbon API 可以在实时环境中动态判断服务器是否运行正常,并能检测出那些宕机的服务器。
- 可配置负载均衡规则:Ribbon 内置了
RoundRobinRule
、AvailabilityFilteringRule
和WeightedResponseTimeRule
规则,同时也支持自定义规则。
Ribbon API 的工作原理基于名为“命名客户端”的概念。在我们的应用程序配置文件中,我们为负载均衡所涉及的服务器列表提供一个名称。
现在让我们深入了解它的使用方法。
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
,在配置文件中定义的名为“ping-server”的命名客户端下,对两个服务器进行客户端负载均衡。
4. Ribbon 配置
Ribbon API 允许我们配置负载均衡器的以下组件:
- 规则(Rule):逻辑组件,指定我们应用中使用的负载均衡规则。
- 心跳(Ping):确定服务器实时可用性的机制。
- 服务器列表(ServerList):可以是动态或静态的。在我们的例子中,我们使用静态服务器列表,因此直接在配置文件中定义它们。
下面是一个简单的库配置示例:
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
将定期ping每个URL来确定服务器的可用性。
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
- 定义了可用于负载均衡的服务器列表,这里有两个服务器
- 配置了服务器刷新间隔,使用
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 通过定期检查服务器的健康状态,通过心跳机制来确定服务器是否在线,并有能力跳过那些不活跃的服务器。
此外,它还实现了断路器模式,根据特定条件过滤服务器。断路器模式通过快速拒绝失败服务器上的请求,而不等待超时,从而最小化服务器故障对性能的影响。可以通过设置 niws.loadbalancer.availabilityFilteringRule.filterCircuitTripped
属性为 false
来禁用此断路器特性。
当所有服务器都宕机,没有可用的服务器处理请求时,pingUrl()
将失败,并抛出异常 java.lang.IllegalStateException
,消息为“无实例可供处理请求”。
8. 总结
在这篇文章中,我们讨论了 Netflix Ribbon API 及其在一个简单示例应用中的实现。有关上述示例的完整源代码可以在 GitHub 存储库 中找到。