概述

Netflix Ribbon 是一个跨进程通信(Inter Process Communication,简称 IPC)的云端库,主要提供客户端负载均衡算法。除了客户端负载均衡算法,Ribbon 还提供了其他功能:

  • 服务发现集成:在动态环境如云中,Ribbon 负载均衡器支持服务发现。它与 Netflix 的 Eureka 服务发现组件进行了集成。
  • 故障容错性:Ribbon API 可以在实时环境中动态判断服务器是否运行正常,并能检测出那些宕机的服务器。
  • 可配置负载均衡规则:Ribbon 内置了 RoundRobinRuleAvailabilityFilteringRuleWeightedResponseTimeRule 规则,同时也支持自定义规则。

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 存储库 中找到。


» 下一篇: org.springframework包