Пока система живёт внутри одной синхронной транзакционной границы, ты можешь о них почти не думать. Но как только её части начинают жить и работать независимо — появляются четыре всадника Распределённого Апокалипсиса: Timeout. Retry. Idempotency. Ordering.

Timeout

С локальным синхронным вызовом всё довольно просто: он либо отработал, либо вернул ошибку. Через сеть так уже не работает. Если ответ не пришёл вовремя, ты не знаешь почему. Запрос мог не дойти, сервис мог всё ещё его обрабатывать, операция могла успешно завершиться, а потерялся только ответ. Поэтому timeout — это не просто ошибка. Это ситуация, когда ты не знаешь, что произошло, и должен решить, что делать с этой неопределённостью.

Retry

Если что-то временно не сработало или результат неизвестен, логичный следующий шаг — попробовать ещё раз. В распределённой системе без retry далеко не уедешь: сеть сбоит, сервисы перезапускаются, базы и брокеры иногда недоступны. Но у retry есть цена: одна логическая операция может выполниться несколько раз, а слишком агрессивные повторы могут только усугубить проблему. Поэтому нужно понимать, что можно повторять, после каких ошибок и как часто — отсюда retry limits, backoff и jitter.

Idempotency

Раз запрос или сообщение может прийти повторно, система должна понимать, что с этим делать. Два одинаковых GET обычно никого не волнуют. Два списания денег или два созданных заказа — уже совсем другая история. Idempotency позволяет сказать: это не новая операция, а ещё одна попытка выполнить старую, и не применять её эффект второй раз. В системе с retries или at-least-once delivery дубли — не редкий edge case, а нормальная ситуация, к которой нужно быть готовым.

Ordering

Даже если с дублями разобрались, остаётся порядок. Сообщения могут задерживаться, ретраиться и обрабатываться с разной скоростью, поэтому то, что произошло раньше, иногда приезжает позже. Например, состояние уже изменилось, а следом пришло старое сообщение, которое пытается изменить его снова. Поэтому важно понимать не только обрабатывали ли мы это сообщение раньше, но и можно ли применять его сейчас. Здесь появляются ordering keys, sequence numbers, версии, state machines и отбрасывание устаревших сообщений.

Четыре всадника неизбежны. Апокалипсис — нет.

Пока система живёт внутри одной синхронной транзакционной границы, ты можешь о них почти не думать | Сетка — социальная сеть от hh.ru