1

早些时候,我们在代码中使用了 Bulkhead、CircuitBreaker 和 Retry,一切都按预期工作。现在我们想使用 TimeLimiter,我们修改了代码以一起使用 ThreadPoolBulkhead、TimeLimiter、CircuitBreaker、Retry 和 Fallback。以下是我们目前的配置:

配置文件

resilience4j.thread-pool-bulkhead:
  configs:
    default:
      maxThreadPoolSize: 50
      coreThreadPoolSize: 10
      queueCapacity: 100
      keepAliveDuration: 5000
  instances:
    backendA:
      baseConfig: default

resilience4j.timelimiter:
  configs:
    default:
      timeoutDuration: 45000
  instances:
    backendA:
      baseConfig: default
    fallbackA:
      timeoutDuration: 10000

...
Similar configurations for cicuitBreakers and Retry.

下面是我们如何在代码中使用它:

Decorators
  .ofSupplier(() -> test.hello())
  .withThreadPoolBulkhead(getThreadPoolBulkheadInstanceFromRegistry())
  .withTimeLimiter(getTimeLimiterInstanceFromRegistry(), Executors.newSingleThreadScheduledExecutor())
  .withCircuitBreaker(getCircuitBreakerFromRegistry())
  .withRetry(getRetryInstanceFromRegistry(), Executors.newSingleThreadScheduledExecutor())
  .withFallback(exception -> handleFallback(exception, transaction))
  .get()
  .toCompletableFuture()
  .get();

Fallback 机制与上面相同,唯一的区别是它使用fallbackA了 timelimiter 的实例,该实例被配置为在 10 秒后超时。

在测试系统时(20 tps,5-10 分钟),一切都按预期工作。但是当我们以相同的 20tps 将负载持续时间增加到 3-4 小时时,我们注意到系统在 40-45 分钟内按预期工作并且交易正在进行;但在那之后所有的交易开始失败。

在没有 TimeLimter 和 ThreadPoolBulkhead 的情况下,同样的事情。

上面的配置有问题吗?另外,当我们有线程池隔板时,为什么我们需要提供单独的 Scheduled Executor 服务?它不应该采用分配给隔板的线程吗?

此外,我们尝试在班级级别更改Executors.newSingleThreadScheduledExecutor()为。Executors.newScheduledThreadPool(10)然后一切都按预期在积极的情况下工作,但是当我们在 hello() 上延迟 45 秒并且回退也有延迟(它也应该从那里超时)并且负载保持不变,即 20 tps。我们注意到最初的 2 个事务是成功的,而其余的事务则失败了。但我们不确定为什么这 2 笔交易有效(它们花了大约 1 分 40 秒),它们也应该失败。

4

0 回答 0