首页 > 解决方案 > 断路器在 Feign 客户端 + Netflix Ribbon + Spring Retry 中不起作用

问题描述

将 Feign 客户端与客户端负载均衡器 Ribbon 和 Spring Retry 一起使用。没有尤里卡。

得到:

  1. application.yml 中的 listOfServers
  2. Netflix Ribbon 和 Spring Retry 的默认配置

想要:

  1. 从 listOfServers 连接到第一台服务器
  2. 如果异常,则打开断路器到第一个服务器 N 秒
  3. 连接到第二台服务器
  4. 如果异常,则打开第二台服务器的断路器 N 秒
  5. 连接到第三台服务器...等

我得到什么:

  1. 从 listOfServers 连接到第一台服务器
  2. 如果异常,连接到第二台服务器
  3. 如果异常,连接到第三台服务器...等

事实上,断路器并没有为宕机的服务器打开。新请求将从 listOfServers 发送到所有服务器,而不依赖于 Circuit Breaker 的状态。

在 3 个请求失败后在日志中收到消息:

RibbonLoadBalancedRetryPolicy | host1:8080 RetryCount: 2 Successive Failures: 3 CircuitBreakerTripped:true

但是否则新请求将被发送到该服务器。尽管 CircuitBreakerTripped:true,但我在调试中看到对停机服务器的请求。

功能区文档说我可以使用 AvailabilityFilteringRule:

此规则将跳过被视为“电路跳闸”或具有高并发连接数的服务器。默认情况下,如果 RestClient 未能在最后 3 次与它建立连接,则实例会被电路跳闸。一旦一个实例电路跳闸,它将保持此状态 30 秒,然后再将电路视为闭合。但是,如果它继续连接失败,它将再次“电路跳闸”,并且它“电路关闭”的等待时间将与连续失败的次数成倍增加。

但这无济于事。无论如何,重试逻辑和其他功能区功能都可以正常工作,但断路器除外。

知道我错过了什么吗?

应用配置:

niws:
  loadbalancer:
    default:
      circuitTripMaxTimeoutSeconds: 60
      connectionFailureCountThreshold: 1

my-service:
  ribbon:
    eureka:
      enabled: false
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.AvailabilityFilteringRule
    ServerListRefreshInterval: 60000

    listOfServers: http://localhost:8182,http://localhost:8183,http://localhost:8184
    OkToRetryOnAllOperations: true
    MaxAutoRetries: 0
    MaxAutoRetriesNextServer: 2

假装客户端:

@FeignClient(
        name = "my-service",
        configuration = {
                FeignClientConfiguration.class
        }
)
public interface Client {...}

Feign客户端配置:

@Bean
@Primary
public Client client(
        CachingSpringLoadBalancerFactory cachingFactory,
        SpringClientFactory clientFactory) {
    ...
    return new LoadBalancerFeignClient(client, cachingFactory, clientFactory);
}

标签: spring-bootfeignspring-retrynetflix-ribbon

解决方案


推荐阅读