Приложения, которые потребляют / передают любые данные на удаленные серверы (Apis), должны иметь политику для работы с временными сбоями. Временные сбои - это временные сбои, которые, вероятно, скоро исчезнут, например потеря пакетов, проблемы с подключением к сети и т. Д.

Наше приложение не должно давать сбой из-за неправильного поведения при возникновении некоторых из этих сбоев. Чтобы избежать такого поведения, мы можем полагаться на некоторые шаблоны, такие как шаблон повторных попыток, разрыв цепи, тайм-аут и т. Д. В сегодняшнем посте мы рассмотрим, как реализовать шаблон повторных попыток на C # с помощью Polly и Flurl.

Установка пакетов

В этом примере мы будем использовать два пакета, Polly и Flurl.

Polly - это гибкая .NET-библиотека, которая помогает разработчикам реализовать несколько устойчивых шаблонов, таких как Retry, Circuit break и Timeout. Чтобы установить его, введите следующую команду в консоли диспетчера пакетов Nuget:

Install-Package Polly

Flurl - это свободный HTTP-клиент для .NET, который поможет нам легко отправлять запросы. Благодаря его структуре плавного интерфейса мы можем создавать запросы путем объединения вызовов методов, уменьшая объем кода, который нам нужно написать, чтобы сделать простой HTTP-запрос. Чтобы Furl работал правильно, нам нужно установить два пакета:

Install-Package Flurl.Http
Install-Package Flurl

Создание HTTP-клиента

Давайте создадим класс для централизации всей логики работы с HTTP-запросами. Это позволяет нам повторно использовать этого клиента через нашу кодовую базу всякий раз, когда мы хотим сделать запрос. Назову это HttpClient.

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

Второй метод - создать политику повтора с использованием ранее установленной библиотеки Polly.

Мы указываем при создании политики для обработки исключенияFlurlHttpExceptionexception, поскольку для отправки запроса будет использоваться библиотека Flurl.

Метод IsTransientError будет использоваться, чтобы определить, следует ли повторить неудачный запрос. Если код состояния, присутствующий в исключении, равен любому коду состояния, который стоит повторить, политика будет предпринята новая попытка.

И последнее, но не менее важное: WaitAndRetryAsync метод будет выполняться каждый раз, когда запрос не выполняется. Этот метод получает общее количество повторных попыток (в данном случае три) и метод, который будет вызван с текущей попыткой и, как ожидается, вернет временную метку, которая будет использоваться для интервалов между повторными попытками.

Время между каждой повторной попыткой будет соответствовать квадрату текущего номера попытки, другими словами, первая попытка будет ждать одну секунду, вторая попытка - 4 секунды, а последняя попытка - 9 секунд. Эта идея использования экспоненциального отката позволяет нам дать удаленному серверу больше времени для восстановления после этого временного сбоя.

Отправка запросов

Когда политика готова, мы можем приступить к отправке HTTP-запросов. Прежде всего, давайте создадим метод для отправки запросов GET без использования ранее созданной политики.

Как видите, с помощью Flurl мы можем отправить запрос и десериализовать его ответ с помощью всего 3 строк кода (это может быть только одна). Последний шаг - соединить вызов с созданной политикой, чтобы политика могла отслеживать ошибки, если они возникнут, и вызывать нашу стратегию повторных попыток.

Мы можем сделать это, просто передав логику отправки методу ExecuteAsync, предоставляемому политикой:

Если что-то пойдет не так внутри метода ExecuteAsync, политика будет использовать IsTransientError, чтобы определить, стоит ли повторять выполненный код. Если да, будет сделана новая попытка, в противном случае исключение будет брошено клиенту, который изначально вызывает метод GetJsonAsync.

Вот и все, примерно с 50 строками кода мы только что создали HTTP-клиент, который будет достаточно умен, чтобы идентифицировать временную ошибку и повторить попытку как минимум три раза, прежде чем она окончательно выйдет из строя. Мы можем использовать эту политику для отправки других типов запросов, таких как POST, PUT, PATCH и DELETE.

На сегодня все, ребята. Я надеюсь, что эта статья вам чем-то помогла.

Будьте осторожны и удачного кодирования!

Полный клиентский код доступен здесь.