Логика повторов при ошибке...
От: Shmj Ниоткуда  
Дата: 02.12.22 20:15
Оценка:
Есть пресловутый Polly, который реализует несколько паттернов. Среди прочих — CircuitBreaker.

Но вот как лучше делать повторы на практике? Можно ли придумать некое универсальное настраиваемое решение? Что используете вы?

Некоторые мысли в форме потока сознания:

  Скрытый текст
Давайте так — некая операция, которая не прошла. Тут сразу разделить на устраняемые и не устраняемые без перекомпиляции ошибки:

1. Устраняемые: сетевые (отвалилась база данных, отвалился внешний сервис), системные (как то файл заблокирован для записи, может потом разблокируется, т.к. админ просто открыл его в блокноте и потом закроет или нехватка места на диске — админ почистит).
2. Не устраняемые: ошибка в коде, как то не учли что логин может быть не только email-ом, но и телефоном — и пытаетесь телефон преобразовать к email — можно делать это бесконечное количество раз и результат будет всегда одним и тем же — долбежка не имеет смысла.


Т.е. сразу нужно как-то разделять исключения на два типа. Иногда это не так просто как кажется, иногда нет возможности строгой классификации

Далее. Пусть мы разделили худо-бедно ошибки и можем повторять. Но как часто повторять? Бесконечно? Может таки не стоит — может всему есть предел? Ок, этот предел можно конфигурировать. Но нужна какая-то хитрая формула.

К примеру, задали по числам Фибоначчи секунд:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711


Но вот, допустим, некий сервис внешний был не доступен сутки. Представьте какого значения достигло ЧФ и как долго ждать повтора Вроде можно ограничить — не более чем час. Или же какой-то рычаг оставить — повторить все. К примеру, когда вы узнали что была проблема с базой и она решилась.

В общем — кто к чему пришел?
Re: Логика повторов при ошибке...
От: sqrt  
Дата: 02.12.22 20:29
Оценка: -1 :)
Здравствуйте, Shmj, Вы писали:

Что такое Polly и CircuitBreaker?

S> Но вот как лучше делать повторы на практике?

Универсальных решений не бывает. Это анти-паттерн.
Re[2]: Логика повторов при ошибке...
От: Shmj Ниоткуда  
Дата: 02.12.22 20:32
Оценка:
Здравствуйте, sqrt, Вы писали:

S>Что такое Polly и CircuitBreaker?


https://makolyte.com/csharp-circuit-breaker-with-polly/

S>> Но вот как лучше делать повторы на практике?

S>Универсальных решений не бывает. Это анти-паттерн.

Что мешает сделать универсальное решение? Как вы предлагаете решать?
Re[3]: Логика повторов при ошибке...
От: Qulac Россия  
Дата: 02.12.22 20:36
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, sqrt, Вы писали:


S>>Что такое Polly и CircuitBreaker?


S>https://makolyte.com/csharp-circuit-breaker-with-polly/


S>>> Но вот как лучше делать повторы на практике?

S>>Универсальных решений не бывает. Это анти-паттерн.

S>Что мешает сделать универсальное решение? Как вы предлагаете решать?


Есть шаблон предохранитель
Программа – это мысли спрессованные в код
Re[4]: Логика повторов при ошибке...
От: Shmj Ниоткуда  
Дата: 02.12.22 20:39
Оценка: 1 (1)
Здравствуйте, Qulac, Вы писали:

Q>Есть шаблон предохранитель


Это и есть CircuitBreaker — автор вашей статьи так же упомянул Polly
Re: Логика повторов при ошибке...
От: ltc  
Дата: 02.12.22 20:48
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Но вот, допустим, некий сервис внешний был не доступен сутки. Представьте какого значения достигло ЧФ и как долго ждать повтора Вроде можно ограничить — не более чем час. Или же какой-то рычаг оставить — повторить все. К примеру, когда вы узнали что была проблема с базой и она решилась.


В отрыве от предметной области разговор бессмысленный. Если у тебя HFT, то ретрай даже в секунду никому не нужен. Если интерактивное приложение (некритичное) — то без привлечения внимания пользователя можно десяток-другой секунд потупить. Если бэкграунд сервис, опять же некритичный, то можно часами ждать. Система типа dead hand должна пытаться вечно.
Re[2]: Логика повторов при ошибке...
От: Shmj Ниоткуда  
Дата: 02.12.22 20:55
Оценка:
Здравствуйте, ltc, Вы писали:

ltc>Если интерактивное приложение (некритичное) — то без привлечения внимания пользователя можно десяток-другой секунд потупить. Если бэкграунд сервис, опять же некритичный, то можно часами ждать. Система типа dead hand должна пытаться вечно.


Немного проанализируйте и вы поймете — все эти случаи отличаются только одним параметром — время попыток повтора. Думайте что мешает сделать универсальное решение, где повторы применимы.
Re[3]: Логика повторов при ошибке...
От: Qulac Россия  
Дата: 02.12.22 22:05
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, ltc, Вы писали:


ltc>>Если интерактивное приложение (некритичное) — то без привлечения внимания пользователя можно десяток-другой секунд потупить. Если бэкграунд сервис, опять же некритичный, то можно часами ждать. Система типа dead hand должна пытаться вечно.


S>Немного проанализируйте и вы поймете — все эти случаи отличаются только одним параметром — время попыток повтора. Думайте что мешает сделать универсальное решение, где повторы применимы.


Термин взят из электротехники, где есть предохранитель с повторным включением, т.к. на линиях бывают случайные самопроходящие замыкания. Так и здесь: существуют случайные самопроходящие(сервис подвис на время) так и быстро устранимые сбои. Вот из среднего времени самопрохождения сбоя(максимального, минимального) и нужно исходить.
Программа – это мысли спрессованные в код
Re: Логика повторов при ошибке...
От: vsb Казахстан  
Дата: 03.12.22 00:48
Оценка:
Недавно реализовывал. Первоначальная задержка 5-7 минут. Максимальная 20-28 часов. Увеличивается на 0-40% каждый раз.
Отредактировано 03.12.2022 0:48 vsb . Предыдущая версия .
Re[2]: Логика повторов при ошибке...
От: Shmj Ниоткуда  
Дата: 03.12.22 06:57
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Недавно реализовывал. Первоначальная задержка 5-7 минут. Максимальная 20-28 часов. Увеличивается на 0-40% каждый раз.


Это вы описали параметры конфигурации. Понимаете ли, что параметры можно менять от проекта к проекту — а само решение можно везде использовать одно и то же.
Re: Логика повторов при ошибке...
От: Muxa  
Дата: 03.12.22 10:31
Оценка:
У меня сейчас схожая проблема проблема: есть библиотечный код, который пытается найти файл по текстовому запросу от юзер кода, в случае если ничего подходящего не нашлось я сообщаю об этом юзер коду и ожидаю что он передаст мне новую строку для поиска файла, который опять же может не найтись. Вот сколько раз спрашивать юзер код? Так можно до бесконечности висеть на этом месте.
Я даю юзер коду 10 попыток, после чего делаю некие действия по умолчанию и всё.
Re[3]: Логика повторов при ошибке...
От: vsb Казахстан  
Дата: 03.12.22 12:04
Оценка:
Здравствуйте, Shmj, Вы писали:

vsb>>Недавно реализовывал. Первоначальная задержка 5-7 минут. Максимальная 20-28 часов. Увеличивается на 0-40% каждый раз.


S>Это вы описали параметры конфигурации. Понимаете ли, что параметры можно менять от проекта к проекту — а само решение можно везде использовать одно и то же.


В спринге это есть. Я правда не пользовался сам, но вообще — есть. В Golang тоже, недавно к AWS SDK читал, там идет параметр Retry как интерфейс, я так понимаю, как раз чтобы настраивать его можно было.
Re: Логика повторов при ошибке...
От: Aquilaware  
Дата: 03.12.22 13:42
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Но вот как лучше делать повторы на практике? Можно ли придумать некое универсальное настраиваемое решение? Что используете вы?


Наверное самое универсальное и наиболее используемая модель это делать несколько повторов с экспонтенциальным ростом времени задержки между попытками. Если хотите еще больше "универсальности", то к времени задержки можно добавить случайную величину в пределах 1/4 этого времени. Так делают чтобы сделать нагрузку на ресурс более равномерной после провала в его доступности когда есть много клиентов, которые в противном случае могут параллельно пытаться делать повторы в одни и те же моменты времени создавая этим ненужный аврал.
Re[2]: Логика повторов при ошибке...
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.12.22 17:10
Оценка: 12 (1) +2
Здравствуйте, Aquilaware, Вы писали:

A>Наверное самое универсальное и наиболее используемая модель это делать несколько повторов с экспонтенциальным ростом времени задержки между попытками. Если хотите еще больше "универсальности", то к времени задержки можно добавить случайную величину в пределах 1/4 этого времени. Так делают чтобы сделать нагрузку на ресурс более равномерной после провала в его доступности когда есть много клиентов, которые в противном случае могут параллельно пытаться делать повторы в одни и те же моменты времени создавая этим ненужный аврал.

Вот мне, кстати, всегда было непонятно, почему нужно именно экспоненциальное время задержки. Почему не арктангенс или кусочно-линейное? Ну, типа попробовали ежеминутно-через 5 минут — через полчаса — через час — и долбим раз в час.
Тогда у нас матожидание бездарно потерянного времени после починки системы ограничено получасом. А не неизвестным заранее значением — когда в итоге после починки сервера нужно ещё и идти перезапускать клиента, который "следующая попытка подключения будет произведена через 32 дня".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Логика повторов при ошибке...
От: Shmj Ниоткуда  
Дата: 03.12.22 21:25
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

S>Тогда у нас матожидание бездарно потерянного времени после починки системы ограничено получасом. А не неизвестным заранее значением — когда в итоге после починки сервера нужно ещё и идти перезапускать клиента, который "следующая попытка подключения будет произведена через 32 дня".


Супер! Столкнулся с такой проблемой на практике. Внешний сервис упал на 24 часа. Редко, но бывает.

Однако же — долбить раз в час на протяжении 1 года каждый час = тоже глупо. По-моему должен быть какой то лимит. Ну ок, бывает что нечто упадет на сутки. Ну на трое суток в худшем случае. Но зачем долбить после 3 суток или на крайняк 5 дней?

По сути тут дело все в конфигурации. Нужно 3 параметра:

1. На короткой дистанции. Может просто сетевая ошибка рядовая. Тут можно по тем же числам Фибоначчи или тем же экспоненциальным ростом.
2. Предел, после которого значение переходит в константу. К примеру, 1 час. Раз в час это уже достаточно редко и уже не будет так уж нагружать сервер.
3. Все-таки предел, когда даже долбежку раз в час нужно признать бессмысленной. К примеру, спустя 3 суток.
Re[4]: Логика повторов при ошибке...
От: Aquilaware  
Дата: 03.12.22 23:13
Оценка:
Здравствуйте, Shmj, Вы писали:

S>По сути тут дело все в конфигурации. Нужно 3 параметра


Ну вот, философский камень найден. Как по мне, это очень хорошая и жизнеспособная модель.
Re[3]: Логика повторов при ошибке...
От: mogadanez Чехия  
Дата: 03.12.22 23:24
Оценка: +2
Здравствуйте, Shmj, Вы писали:


S>Немного проанализируйте и вы поймете — все эти случаи отличаются только одним параметром — время попыток повтора. Думайте что мешает сделать универсальное решение, где повторы применимы.


универсализм — как правило несет избыточность, зачем мне нужно решение с хиулиардом параметров если в моем случае я использую только 1
Re[3]: Логика повторов при ошибке...
От: Sharowarsheg  
Дата: 03.12.22 23:25
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Что мешает сделать универсальное решение? Как вы предлагаете решать?


Отсутствие универсальной задачи мешает сделать универсальное решение.

In startup we have great of capability for churn out solution. Please send problem, we are pay good money.


https://twitter.com/devops_borat/status/315549020326088704
Re[4]: Логика повторов при ошибке...
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.12.22 08:23
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Однако же — долбить раз в час на протяжении 1 года каждый час = тоже глупо.

Почему? Нужно какое-то математическое обоснование термина "глупо". С моей точки зрения, лишнее обращение к серверу плохо только создаваемой нагрузкой. Если мы долбим ежечасно в течение года, то это всего-то 8760 обращений.
Сколько обращений к этому сервису мы делаем обычно? Несколько раз в минуту? Ну ок, при неисправности мы снижаем нагрузку на 2 порядка. Можно и на 3 — ну, то есть должно быть какое-то соотношение между "обычной" и "аварийной" интенсивностью.

S>По-моему должен быть какой то лимит. Ну ок, бывает что нечто упадет на сутки. Ну на трое суток в худшем случае. Но зачем долбить после 3 суток или на крайняк 5 дней?

Потому что ремонт может занять и 3 суток, и 5 дней.
Но опять же, всё зависит от контекста. Если для нас это жизненно важный сервис, то вместе с ним лежим и мы. Допустим, он сломался навсегда — владельцы разорились, не смогли восстановить. Или вообще, мы понимаем, что нет смысла полагаться на сервис, SLA которого настолько плоха. За какое время мы переключимся на альтернативу? Если за неделю, то не имеет никакого смысла долбить больше недели — имеет смысл ввести регламент "сервис, не отвечающий более суток, подлежит замене". С таким регламентом через 8 дней от начала сбоя у нас будет новая версия кода, в которой обращений к этому сервису вовсе нет.
А долбление раз в час нужно только для того, чтобы если этот сервис через пару дней всё же поднялся, то мы продолжим работу на нём, пока инженеры пилят замену.

S>По сути тут дело все в конфигурации. Нужно 3 параметра:


S>1. На короткой дистанции. Может просто сетевая ошибка рядовая. Тут можно по тем же числам Фибоначчи или тем же экспоненциальным ростом.

S>2. Предел, после которого значение переходит в константу. К примеру, 1 час. Раз в час это уже достаточно редко и уже не будет так уж нагружать сервер.
S>3. Все-таки предел, когда даже долбежку раз в час нужно признать бессмысленной. К примеру, спустя 3 суток.
Да, согласен, похоже на правду.
Но, повторюсь, я сам правильного ответа не знаю. Наверняка есть какие-то учебники по SRE, где всё это расписано и дано в упражнениях.
Возможно, правильный профиль backoff зависит от распределения времени восстановления после сбоя с учётом распределения вероятностей различных типов сбоев.
И вот эта вот экспоненциальная формула тщательно выведена и обоснована для некоторого класса таких распределений
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Логика повторов при ошибке...
От: Shmj Ниоткуда  
Дата: 04.12.22 11:51
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>>Однако же — долбить раз в час на протяжении 1 года каждый час = тоже глупо.

S>Почему? Нужно какое-то математическое обоснование термина "глупо". С моей точки зрения, лишнее обращение к серверу плохо только создаваемой нагрузкой. Если мы долбим ежечасно в течение года, то это всего-то 8760 обращений.
S>Сколько обращений к этому сервису мы делаем обычно? Несколько раз в минуту? Ну ок, при неисправности мы снижаем нагрузку на 2 порядка. Можно и на 3 — ну, то есть должно быть какое-то соотношение между "обычной" и "аварийной" интенсивностью.

Тут, скорее, не мат. обоснование а практическая целесообразность, здравый смысл и лицензионное соглашение.

К примеру, если речь о сервисе пополнения счета. Приняли от вас оплату и пробуем провести через шлюз оператора как его партнеры. Не прошло. Ну ок, платеж в статусе — на обработке. Думаю и ежу понятно, что в таком статусе — ну день еще может повисеть, ну 3 дня с учетом выходных — а вот год ждать пока тебе телефон пополнят — никто не будет..

S>>По-моему должен быть какой то лимит. Ну ок, бывает что нечто упадет на сутки. Ну на трое суток в худшем случае. Но зачем долбить после 3 суток или на крайняк 5 дней?

S>Потому что ремонт может занять и 3 суток, и 5 дней.

Если ремонт 5 дней — то нужно отказываться от услуг такого поставщика. И быстренько за 1-2 дня переключиться на другого.

S>А долбление раз в час нужно только для того, чтобы если этот сервис через пару дней всё же поднялся, то мы продолжим работу на нём, пока инженеры пилят замену.


Вот именно что пару дней. Но зачем год долбить?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.