Обновить

Перезапустить недостаточно: как я сделал проверяемое автоматическое восстановление сервисов

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели6.7K
Всего голосов 1: ↑1 и ↓0+3
Комментарии2

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

Самое обидное в авто-восстановлении – когда воркер, повторив задачу после таймаута, устраивает второй перезапуск, и система восстановления сама превращается во второй инцидент. Лечили простой – получили два. Спасает монотонный номер у задачи, по которому hook отсекает опоздавший перезапуск как чужой.

Знакомо до боли. Мы к тому же пришли: у строки в outbox есть fence, он инкрементится при каждом claim, и каждая запись несёт and fence = ?. Опоздавший воркер уже ничего закоммитить не может, даже если очень хочет.

Но монотонный номер отсекает опоздавшую запись, а не уже ушедший наружу запрос. Если воркер успел дёрнуть рестарт и не дождался ответа — таймаут, connection reset — снаружи действие уже могло произойти, и никакой fence его не отменит. Поэтому у нас есть отдельный исход unknown: «могло долететь». Это единственный исход, в котором мы допускаем дубль, и мы его не прячем, а подсвечиваем в интерфейсе: честное «возможен дубль» полезнее красивого «доставлено».

Ещё из того, что вылезло на аудите перед релизом: «опоздавшего» нельзя определять по часам. Функция, решавшая, когда делать следующую попытку, брала время воркера — в сценарии с воркером, отставшим на 10 минут, бэкофф превращался в 20 попыток за 20 минут. С тех пор правило железное: любое «когда» решает база, воркеры со своими часами не голосуют. Так что да — номер, и только номер.

И про сам номер: если захотите повесить на него unique index, сначала прогоните на живых данных. У нас он не построился, и это оказалось не багом, а фактом предметной области: ветки, где попытка встаёт по стойке смирно — проба неопределённая, таргет уже сам поднялся — всё равно пишут строку с номером, на который были запланированы. Поэтому у одного инцидента легально живут skipped №1 и failed №1. Уникальность в итоге живёт в claim'е под row lock'ом, а не в схеме.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации