Провайдер платежей отдаёт таймаут. Что дальше? Таймаут выжирает пул соединений — а тот блокирует API оформления заказа? Блокировка валит каталог товаров, и каталог тянет за собой всё остальное?
Цепочка из пяти вопросов, и в ней уже вся суть senior-инженерии. Код, который работает на счастливом пути, пишется легко: тут справится и джун, и генератор кода за пять секунд. Локальные тесты зелёные, сервис поднимается, всё красиво. Интерес начинается ровно в тот момент, когда что-то отваливается.
У этого взгляда есть название — доктрина радиуса поражения (Blast Radius Doctrine). Идея простая: у каждой ошибки есть радиус, и этот радиус можно ограничить архитектурой, а не героизмом дежурного в три ночи.
Два типа систем
На практике встречаются две крайности. Первая — когда связи между сервисами настолько плотные, что одна необработанная ошибка запускает retry storm по зависимостям и укладывает весь кластер. Вторая — когда отказы предусмотрены и заперты в своих отсеках: упал движок рекомендаций — корзина работает, база подтормаживает — срабатывают circuit breakers, читающие реплики берут нагрузку на себя, а пользователь получает кэшированный ответ.
| Хрупкий каскад | Суверенный балкхед | |
|---|---|---|
| Связи между сервисами | Жёсткие: сосед падает — падаешь ты | Разделены явными стенами |
| Необработанное исключение | Ретраи расходятся по зависимостям и валят кластер | Остаётся внутри своего отсека |
| Внешний сервис тормозит | Пул соединений исчерпан, очередь запросов растёт | Брейкер размыкается, реплики забирают чтение |
| Что видит пользователь | Белый экран целиком | Кэшированный фоллбэк: рекомендации не грузятся, корзина живёт |
| Кто решил, что будет так | Никто. Так получилось | Инженер, который заранее выбрал режим отказа |
Сеньор пишет код не для того, чтобы он работал. Сеньор проектирует архитектуру, чтобы решить, как он будет ломаться.
Модели, генерирующие код, не имеют понятия об организационном радиусе поражения. Они выдают изолированные функции, и в этом их предел: стены, которые удерживают взрыв, ставит человек. Функция может быть идеальной и при этом лежать в контуре, где один таймаут сносит витрину.
Что делать в понедельник утром
Ревью — самое дешёвое место, чтобы поймать эту проблему. Открывая пул-реквест — неважно, человеческий или сгенерированный, — добавьте к обычной проверке синтаксиса один вопрос: если конкретно эта строка бросит исключение таймаута, какой максимальный радиус ущерба?
- Если ответ «упадёт весь сервис» — до мержа нужен circuit breaker или балкхед.
- Если ответ «деградирует один блок страницы» — уже нормально, но проверьте, чем именно деградирует.
- Если ответ «не знаю» — считайте, что радиус неограничен, пока не доказано обратное.
Технический минимум на каждый внешний вызов
- Явный таймаут. Не «по умолчанию из библиотеки», а выбранное число, которое меньше бюджета всей операции.
- Ретраи с backoff и jitter и жёстким лимитом попыток. Без разброса они сами становятся источником шторма.
- Отдельный пул соединений на каждую зависимость — чтобы медленная чужая база не съедала поток, который нужен остальным.
- Circuit breaker с понятным порогом срабатывания и понятным поведением после размыкания.
- Фоллбэк, который реально работает: кэш, урезанный ответ или честный отказ на одном блоке интерфейса. Ошибка здесь не должна ходить в ту же недоступную базу.
Когда это лишнее
Внутренняя админка на двадцать человек, которая ходит в одну базу и больше никуда, не нуждается в балкхедах и брейкерах. Стоимость поддержки такой обвязки выше риска: если инструмент встанет на десять минут, никто не заметит. А вот если через этот же контур идут деньги или он стоит между пользователем и каталогом — вопрос «как оно сломается» перестаёт быть теоретическим.
Типичные ошибки
- Единый пул соединений на все зависимости сразу.
- Отсутствие таймаута: «подождём, пока ответит».
- Тесты только по счастливому пути — падение внешнего сервиса никто не воспроизводит.
- Фоллбэк, который на поверку сам зависит от упавшего узла.
- Ретраи без разброса: пять сервисов одновременно повторяют запрос, и добивают то, что почти поднялось.
Проверка на пальцах
Возьмите одну главную пользовательскую цепочку — оплата, заказ, каталог — и мысленно отключите каждое звено по очереди. Запишите, что именно упадёт и что останется жить. Это и есть карта радиуса поражения вашей системы, и она полезна куда больше, чем схема сервисов из вики. Если для какого-то звена ответ «упадёт всё», вы нашли следующий балкхед. Если для какого-то звена ответа нет вообще, значит, поведение системы при сбое никто не выбирал — оно получилось само.
Архитектура проявляется не на зелёных графиках, а на красных: в том, что осталось работать, пока соседняя часть уже сломалась. Спрашивать об этом дешевле всего на ревью.
Комментарии (0)
Войдите, чтобы комментировать.
Пока нет комментариев. Будьте первым.