Может ли автоматический выключатель Polly иметь экспоненциальную длительность отключения?

#c# #ado.net #circuit-breaker #polly #exponential-backoff

#c# #ado.net #автоматический выключатель #polly #экспоненциальный -откат

Вопрос:

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

В документации по объединению соединений указано, что:

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

Polly, похоже, хорошо подходит для решения этой проблемы с помощью комбинации политик резервного копирования, ожидания и повторной попытки и политик автоматического отключения. Здесь есть хорошая картина этого

В идеале я надеялся, что смогу указать экспоненциальную длительность отключения для автоматического выключателя, чтобы она соответствовала периоду удвоения, описанному выше. Я не видел в Интернете никаких примеров того, как это может быть возможно, так что, может быть, это невозможно?

Каков желаемый подход к настройке здесь? Можно ли указать автоматический выключатель с длительностью прерывания 5 секунд, а затем использовать экспоненциальную повторную попытку для компонента ожидания и повторной попытки, равного 5, 10, 20, 40 и 60 секундам? Это кажется неудачным в случае, когда соединения только что стали доступны, и ваша старая операция только что начала свое 40-секундное ожидание, в то время как новая операция будет работать немедленно.

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

Я ценю ваши отзывы!

Ответ №1:

Polly не предоставляет автоматические выключатели с переменной (например, экспоненциальной) продолжительностью отключения.

Следующее может на первый взгляд показаться нелогичным, но: звучит так, как будто в этой ситуации не требуется автоматический выключатель с экспоненциальным отключением, потому что ADO.NET описанный алгоритм пула соединений уже эффективно обеспечивает это.

Обоснование: Цель автоматического выключателя — прекратить передачу вызовов в нижестоящую систему, которая вряд ли справится с ними, чтобы: (а) быстро перейти к вызывающему абоненту; (б) защитить базовую систему от чрезмерной нагрузки. Это звучит так, как будто ADO.NET алгоритм уже выполняет обе эти цели.

Аналогично, цель политики повторных попыток с экспоненциальным отказом состоит в том, чтобы предотвратить повторные попытки, которые сами по себе «умножают» нагрузку (создавая самоиндуцированную DDOS-атаку на базовую систему … поступает больше запросов, и существующие запросы также повторяются). Опять же, это звучит как ADO.NET алгоритм force-you-to-back-off применяет свой собственный экспоненциальный откат для защиты базовой базы данных, поэтому может (*) не быть никакой пользы в наложении вашего собственного экспоненциального отката Polly поверх этого.

На основе ADO.NET обеспечивает свою собственную защиту, у меня был бы соблазн сделать что-то простое, например, использовать политику повторных попыток с фиксированным интервалом повторных попыток в 5 секунд или 5 с лишним секунд. (Независимо от того, какой «период блокировки» действует, кажется, он будет кратен 5 секундам.)

Это предложение основано на предположении, что ADO.NET управление пулом подключений — это (в отношении этого периода блокировки) все, что происходит на стороне вызывающего абонента; т.е. ADO.NET код, встроенный в вызывающее приложение, решает, что его пул подключений полностью использован, и отклоняет дальнейшие попытки подключения в период блокировки без выполнения сетевого вызовак базовому серверу SQL для проверки. Если это предположение неверно, то совет (*), приведенный выше, может быть плохим, и вам было бы лучше использовать политику экспоненциального возврата к повторным попыткам, чтобы избежать попыток повторного подключения, перегружающих сервер базы данных.


Предостережение: я не работал непосредственно с этим конкретным ADO.NET предел. У тех, у кого есть, может быть лучший совет. Те, кто знает внутреннюю ADO.NET архитектура лучше, возможно, лучше знает, насколько «дорого» продолжать делать попытки каждые пять секунд (как я уже предлагал), которые могут быть отклонены.


Дополнение: в этом обсуждении также игнорируется любое измерение высокого параллельного спроса внутри вызывающего абонента, вызывающее голод потока / процессора или подобное. Если это вопрос, рассмотрите возможность упреждающего сброса нагрузки при некотором известном допустимом пределе.

Комментарии:

1. Я ценю ваши предложения, а также ваши честные оговорки. 🙂 Если я правильно понимаю, я думаю, вы предполагаете, что мне не нужен автоматический выключатель — просто используйте политику повторных попыток и позвольте ADO.NET обратитесь к его части с автоматическим выключателем. Это кажется хорошим советом. Я подожду, чтобы увидеть, ответит ли кто-нибудь еще, а затем воздам вам должное за правильный ответ.