Правильный способ обработки нескольких услуг с помощью автоматического выключателя Polly - PullRequest
2 голосов
/ 17 октября 2019

У меня есть приложение, в котором мы общаемся с сотнями конечных точек HTTP. Приложение является своего рода прокси. При тестировании с помощью polly я заметил, что в случае сбоя одной конечной точки, скажем, «api.endpoint1.com», вызовы «api.endpoint2.com» и «api.endpoint3.com» также будут открыты / заблокированы. государство. Это имеет смысл, так как я определил только одну политику, но каков рекомендуемый подход к обработке этого сценария, чтобы вызовы к несвязанным конечным точкам не блокировались из-за проблем с производительностью другого?

Создаю ли я коллекцию политик, по одной для каждой конечной точки, или есть способ предоставить своего рода контекстный ключ (т. Е. Имя хоста) для охвата сбоев в данной конечной точке хоста?

Я просмотрел Документы Полли относительно ключей контекста, и кажется, что это способ обмена данными назад и вперед, а не то, что я здесь ищу.

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));

1 Ответ

1 голос
/ 17 октября 2019

Да, лучше всего создать отдельную политику для каждой конечной точки. Это лучше, чем делать это для каждого хоста, потому что конечная точка может медленно реагировать по причине, специфичной для этой конечной точки (например, хранимая процедура работает медленно).

Я использовал Dictionary<string, Policy> с URL-адресом конечной точки в качестве ключа.

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