Пользовательская политика повтора AutoRest с преобразованием кода состояния
Я работаю над системой с несколькими микросервисами и Orchestrator, которые взаимодействуют через сгенерированные клиенты AutoRest. Я сталкиваюсь с проблемой, когда вызывается Orchestrator, и Orchestrator делает вызов зависимости, если зависимость не удается, он повторяется с помощью автоматического отдыха 3 раза. Теперь это обычно нормально, но, поскольку Orchestrator получает неудачный ответ, он будет повторять 3 раза, что будет повторять попытки нисходящих сервисов 3 раза, каждый из которых приведет к 9 нисходящим вызовам.
Я подумал о следующем решении: разрешить сбоям нижестоящих сервисов и вернуть 500 Internal Server Error как обычно. Если повторные попытки также будут неудачными, а окончательный код ответа, который мы получим, будет кодом переходного ответа, мы превращаем его в 502. Я создал пользовательский ITransientErrorDetectionStrategy, который не повторяет попытку на 502, поэтому, когда оркестратор возвращает код ответа 502, оркестратор запрос не повторен.
Мой ITransientErrorDetectionStrategy выглядит следующим образом:
public class DownStreamFailureStrategy : ITransientErrorDetectionStrategy
{
public bool IsTransient(Exception ex)
{
HttpRequestWithStatusException httpException;
if ((httpException = ex as HttpRequestWithStatusException) != null)
{
if (httpException.StatusCode == HttpStatusCode.RequestTimeout||
(httpException.StatusCode >= HttpStatusCode.InternalServerError &&
httpException.StatusCode != HttpStatusCode.NotImplemented &&
httpException.StatusCode != HttpStatusCode.HttpVersionNotSupported &&
httpException.StatusCode != HttpStatusCode.BadGateway))
{
return true;
}
}
return false;
}
}
У меня проблема с преобразованием существующего ответа 500 в 502, я не хочу оставлять это на усмотрение вызывающего кода, а встроить его в клиент. Я смотрел на создание пользовательского RetryDelegatingHandler, однако я не уверен, как бы я использовал его на моей фабрике клиентов.
1 ответ
Также вы можете изменить количество повторных попыток, изменив RetryPolicy.
public partial class YourAutoGeneratedClient
{
partial void CustomInitialize()
{
var retryPolicy = new RetryPolicy<TransientErrorIgnoreStrategy>(0);
SetRetryPolicy(retryPolicy);
}
}