首页 > 解决方案 > 使用 polly 断路器处理多个服务的正确方法

问题描述

我有一个应用程序,我们在其中与数百个 HTTPs 端点进行通信。该应用程序是一种代理。在使用 polly 进行测试时,我注意到如果一个端点,比如“api.endpoint1.com”失败,对“api.endpoint2.com”和“api.endpoint3.com”的调用也将处于打开/阻塞状态状态。这是有道理的,因为我只定义了一个策略,但是处理这种情况的推荐方法是什么,这样对不相关端点的调用不会因为另一个有性能问题而被阻止?

我是为每个端点创建一个策略集合,还是有办法提供各种上下文键(即主机名)来将故障范围限定为给定的主机端点?

我已经查看了Polly 的有关上下文键的文档,看来这些是来回交换数据的一种方式,而不是我在这里寻找的方式。

var policy = Policy
            .Handle<TimeoutException>()
            .CircuitBreaker(1, TimeSpan.FromSeconds(1));

//dynamic, large list of endpoints. 
var m = new HttpRequestMessage(HttpMethod.Post, "https://api.endpoint1.com")
{
    Content = new StringContent("some JSON data here", Encoding.UTF8,"application/json")
};


policy.Execute(() => HTTPClientWrapper.PostAsync(message));

标签: c#.netpolly

解决方案


是的,最好的办法是为每个端点创建一个单独的策略。这比在每个主机上都做要好,因为端点可能由于特定于该端点的原因而响应缓慢(例如,存储过程很慢)。

我使用Dictionary<string, Policy>带有端点 URL 的 a 作为键。

if (!_circuitBreakerPolices.ContainsKey(url))
{
    CircuitBreakerPolicy policy = Policy.Handle<Exception>().AdvancedCircuitBreakerAsync(
        onBreak: ...
    );
    _circuitBreakerPolicies.Add(url, policy);
}
await _circuitBreakerPolicies[url].ExecuteAsync(async () => ... );

推荐阅读