И0 · Пилот: деградация и поведение при отказе#
- Статус: пилот закончен · 2026-09-17 · результат —
D-06 · Деградация при отказе и перегрузкеи три правки метода - Метод:
00-plan.md, форма записи — раздел 3, правило допуска и поправки к канону — раздел 4 - Цель пилота: два результата — реестр, из которого вырастет
D-06, и проверенный (или переписанный) метод исследования
Порядок соблюдён: всё, что ниже раздела «Реестр», собрано из внешних источников до обращения к нашим карточкам и находкам. Сверка с корпусом — отдельным разделом в конце, и она не меняет формулировок, только колонку «чем закрыто у нас».
Первое, что сломалось: форма записи#
Девять полей раздела 3 не помещаются в строку таблицы — строка получается нечитаемой уже на третьей проблеме. Реестр — список блоков, а не таблица. Форма от этого не меняется, меняется вёрстка: поля те же, порядок тот же.
Второе: поле «частота» почти всегда пустое. Это не лень — данные о частоте существуют только там, где кто-то специально измерял, а таких работ единицы. Заполняю честно значением «не измерена», как и требует поправка к канону.
Реестр#
P-DEG-01 · Система не возвращается в норму после того, как причина устранена#
- Как проявляется. Нагрузку сняли до уровня, который система держала вчера, а полезная пропускная способность не восстановилась. Помогает только резкий сброс нагрузки или перезапуск.
- Признак. Есть усиливающий контур — ретраи, промахи кэша, сборка мусора, — и goodput ниже нормы при входной нагрузке, которую система раньше выдерживала. Формально: система в метастабильном состоянии, где «триггер вызывает переход в плохое состояние, которое сохраняется и после снятия триггера» (Bronson et al., HotOS '21).
- Требует решения? Да. Это свойство архитектуры, а не настройка.
- Цена изменения × влияние. Дорого × высокое → полная форма.
- Частота. Измерена частично: из сотен публичных отчётов об инцидентах подтверждённо метастабильными оказались 21–22 в 11 организациях; длительность от 1,5 до 73,5 часов, чаще всего 4–10 часов; более чем в 55 % случаев для выхода потребовался сброс нагрузки (Huang et al., OSDI '22). Редко, но очень дорого — профиль, при котором решение принимают заранее или не принимают никогда.
- Известные решения. Сброс нагрузки; ограничение усиления (см. P-DEG-02); уменьшение разрыва между «уязвимым» и «стабильным» режимом — то есть отказ от работы на грани эффективности; явная процедура выхода, не сводящаяся к перезапуску.
- Зрелость. Устоявшаяся. Термин с 2021 года, механизмы старше.
P-DEG-02 · Ретраи усиливают нагрузку вместо того, чтобы пережить отказ#
- Как проявляется. Зависимость деградировала — и нагрузка на неё выросла, а не упала.
- Признак. Ретраи есть больше чем на одном слое цепочки; отношение числа попыток к числу принятых запросов растёт при деградации.
- Требует решения? Да, но дёшево.
- Цена изменения × влияние. Дёшево × высокое → короткая форма.
- Частота. Измерена: усиление нагрузки ретраями — самый распространённый поддерживающий эффект, «более чем в 50 % изученных инцидентов» (OSDI '22).
- Известные решения, с числами. Ретрай только на одном слое — «неудачный запрос должен повторять слой непосредственно над ним; если повторяют несколько слоёв, получится комбинаторный взрыв»; бюджет на запрос — до трёх попыток; бюджет на клиента — доля ретраев ниже 10 %, что «снижает рост до 1,1× в общем случае»; адаптивное ограничение на стороне клиента с множителем 2×; ошибка «перегружен, не повторять», чтобы верхние слои не повторяли (Google SRE, Handling Overload). Случайный экспоненциальный откат — чтобы повторы не сходились в одну точку (Google SRE, гл. 22).
- Зрелость. Устоявшаяся, с конкретными числами — редкий случай, когда практика доведена до величин.
P-DEG-03 · При перегрузке умирает всё сразу, потому что нет классов важности#
- Как проявляется. Фоновая выгрузка отчёта и оплата отбрасываются одинаково; критичный сценарий падает вместе с некритичным.
- Признак. У запроса нет класса важности, и сервер не умеет отбрасывать по классу. Проверка: можно ли назвать, что именно система перестанет делать при нехватке мощности, — и записано ли это где-нибудь.
- Требует решения? Да.
- Цена изменения × влияние. Дорого × высокое → полная форма. Дорого потому, что класс важности надо протащить через всю цепочку вызовов, а не выставить в одном месте.
- Частота. Не измерена. Канон описывает решение, а не распространённость проблемы.
- Известные решения. Четыре уровня важности — от
CRITICAL_PLUSдоSHEDDABLE, — и отказ начинается с нижних (Google SRE, Handling Overload). - Зрелость. Устоявшаяся у крупных; для малой команды объём работы спорен, и это отдельный вопрос к
D-06.
P-DEG-04 · Что показывать, когда данных нет, решает разработчик в момент инцидента#
- Как проявляется. В одном месте пустой экран, в другом ошибка, в третьем устаревшие данные без предупреждения. Решение принято трижды, разными людьми, под давлением.
- Признак. Существует ли записанный список того, что система имеет право не показывать, и кто его утверждал. Если списка нет — решение не принято, независимо от того, есть ли в коде fallback.
- Требует решения? Да. Это и есть предмет
D-06: остальные проблемы реестра — про механизмы, эта — про обещание пользователю. - Цена изменения × влияние. Дорого × высокое → полная форма. Технически поменять дёшево, но это продуктовое обещание: «показываем устаревшее с пометкой» и «показываем ошибку» — разные договорённости с пользователем, и разворот стоит согласования, а не правки.
- Частота. Не измерена.
- Известные решения. Отказ рано и дёшево вместо попытки обслужить; снижение качества ответа вместо отказа; явный маркер устарелости. Граница между «упростить» и «отказать» — продуктовая, и в источниках она не решается, а называется (Google SRE, гл. 22).
- Зрелость. Практика устоявшаяся, форма решения — нет: нигде не описано, как это записывать.
P-DEG-05 · Механизм деградации есть и не работает, потому что никогда не исполняется#
- Как проявляется. Инцидент; включается запасной путь; он падает сам.
- Признак. Когда этот путь исполнялся последний раз — в проде или под нагрузкой. Если ответ «не помним», путь не существует.
- Требует решения? Да, дёшево.
- Цена изменения × влияние. Дёшево × высокое → короткая форма.
- Частота. Не измерена, но канон утверждает уверенно: деградация «не должна срабатывать часто», и потому неиспользуемая ветка «не работает» (Google SRE, гл. 22).
- Известные решения. Регулярное исполнение пути — на части трафика, по расписанию, в нагрузочном тесте. Нагружать компоненты до поломки, а не до расчётной величины, и отдельно смотреть, как система возвращается к норме после перегрузки.
- Зрелость. Устоявшаяся.
P-DEG-06 · Зависимость «жива» по проверке и мертва для потребителя#
- Как проявляется. Health check зелёный, мониторинг спокоен, пользователи видят ошибки. Автоматика не переключает, потому что не считает, что что-то сломалось.
- Признак. Дифференциальная наблюдаемость: «хотя бы одно приложение наблюдает систему нездоровой, а наблюдатель видит её здоровой» (Huang et al., HotOS '17). Практическая проверка: чем меряется здоровье — процессом о себе или потребителем о нём.
- Требует решения? Да.
- Цена изменения × влияние. Дорого × высокое → полная форма. Менять источник сигнала о здоровье — значит менять то, на что завязаны переключения и алерты.
- Частота. Не измерена. Работа приводит случаи из эксплуатации Azure, но не долю.
- Известные решения. Мерить здоровье с точки зрения потребителя; сводить наблюдения нескольких наблюдателей; не доверять проверке, которая исполняется в том же процессе, что и проверяемое.
- Зрелость. Спорная: проблема названа и признана, готовых рецептов мало.
P-DEG-07 · Таймауты не согласованы по цепочке#
- Как проявляется. Инициатор сдался, а работа внизу продолжается и занимает ресурс. Или наоборот: верхний ждёт дольше, чем ответ вообще кому-то нужен.
- Признак. Сумма таймаутов вниз по цепочке против таймаута инициатора и против продуктового бюджета задержки. Если сумма больше — таймауты не согласованы.
- Требует решения? Да, дёшево.
- Цена изменения × влияние. Дёшево × высокое → короткая форма.
- Частота. Не измерена.
- Известные решения. Бюджет задержки, распределяемый сверху вниз; отмена работы при уходе инициатора; таймаут как часть контракта, а не константа в клиенте.
- Зрелость. Устоявшаяся.
P-DEG-08 · Деградированный режим становится постоянным#
- Как проявляется. Упрощённый режим включили на время инцидента и не выключили. Через месяц это норма, и никто не помнит, что было иначе.
- Признак. Есть ли у режима срок и назначенный владелец снятия.
- Требует решения? Да, дёшево.
- Цена изменения × влияние. Дёшево × высокое → короткая форма.
- Частота. Не измерена.
- Источник. ⚠️ Не проходит критерий общности. Проблема выведена рассуждением и подтверждается только нашим собственным опытом ограничения сроков сосуществования путей (ADR-0002 E-02, последствие о сроке перехода). Ни одного внешнего источника, где она была бы названа как проблема, я не нашёл. Оставляю в реестре с пометкой — и это сознательно: пусть видно, как критерий работает, когда не срабатывает.
Что не попало в реестр и почему#
| Кандидат | Почему не запись |
|---|---|
| «Ретрай на каждом слое даёт комбинаторный взрыв» | Следствие P-DEG-02, а не отдельная проблема: это её признак и её решение, записанные с другой стороны |
| «Circuit breaker настроен наугад» | Проблема сформулирована через механизм, а не через последствие. Переформулировать не удалось — значит записи нет |
| «Нет наблюдаемости» | Вне темы пилота: это входное требование, а не решение о деградации |
| «Выкат сломал прод» | Другая тема — доставка. Граница проходит там, где проблема перестаёт быть про поведение при отказе |
Сверка с нашим корпусом — после сбора, не до#
Восемь записей реестра против того, что у нас уже написано.
| Проблема | Чем закрыта у нас | Достаточно ли |
|---|---|---|
| P-DEG-01 Система не возвращается после снятия причины | Ничем. REL-01 называет retry storm и thundering herd, но как пик, а не как самоподдерживающееся состояние | Нет. Дыра в карточках |
| P-DEG-02 Ретраи усиливают нагрузку | REL-01 — подробно, с бюджетом 10 %, джиттером и расчётом «три уровня по три попытки дают 27 запросов» | Механика — да. Решения нет |
| P-DEG-03 Нет классов важности при перегрузке | REL-03 — load shedding и приоритизация | Механика — да. Решения нет |
| P-DEG-04 Что показывать, когда данных нет | REL-04 — фича-флаги и kill switch | Механика — да. Решения нет, и это предмет D-06 |
| P-DEG-05 Путь деградации не исполняется | REL-10 — chaos engineering и game days | Частично: карточка про метод проверки, не про обязательность |
| P-DEG-06 Зависимость жива по проверке и мертва для потребителя | REL-05 — liveness против readiness. Близко, но уже: readiness не ловит серый отказ, при котором процесс исправен и отвечает | Нет. Дыра в карточках |
| P-DEG-07 Таймауты не согласованы по цепочке | REL-01 — бюджет задержки сверху вниз | Да |
| P-DEG-08 Деградированный режим навсегда | Ничем | Нет, но и общность не подтверждена |
Из прогонов. Дисквалификатор D-03 «система не переживает полного отказа кэша в час пик» сработал дважды — в E-01 и E-02 — и оба раза потребовал документа, которого нет. Оба случая относятся к P-DEG-04: механизмы описаны, а обещание пользователю не сформулировано.
Главный вывод сверки#
Механика покрыта почти вся, решений нет ни одного. Шесть карточек из восьми проблем закрывают «как это устроено» — и ни одна не отвечает на вопрос «что мы выбираем». Это ровно то разделение жанров, которое README объявляет, и пилот показывает его в чистом виде: D-06 не должен объяснять load shedding, circuit breaker и фича-флаги. Его предмет — P-DEG-04, а остальные записи реестра входят в него вопросами и дисквалификаторами, а не разделами.
Две дыры в карточках, а не в решениях: P-DEG-01 (метастабильность как состояние, а не пик) и P-DEG-06 (серый отказ, при котором проверка здоровья зелёная). Обе — материал для topics/08-reliability.md, и обе найдены исследованием, а не прогоном: кейсы их не показывали, потому что в кейсах нет эксплуатации.
Отчёт о методе — второй результат пилота#
| Что проверялось | Итог |
|---|---|
| Форма записи из девяти полей | ✅ пережила восемь заполнений. Но вёрстка сменилась: не таблица, а список блоков — девять полей в строку нечитаемы уже на третьей записи |
| Поле «признак» | ✅ оказалось самым ценным и самым трудным. Оно отсеяло два кандидата: «circuit breaker настроен наугад» не удалось сформулировать через последствие, и записи не стало. Без этого поля реестр был бы длиннее и бесполезнее |
| Поле «частота» | ⚠️ пустое в шести записях из восьми. Данные существуют только там, где кто-то специально измерял. Значение «не измерена» работает как задумано, но надо признать: колонка очереди будет строиться почти без данных |
| Критерий общности — три типа источников | ❌ слишком строг. Строго ему удовлетворяют P-DEG-01 и P-DEG-02. Остальные держатся на каноне плюс одном подтверждении. Если применять буквально, реестр из восьми записей схлопнется до двух — и потеряет то, ради чего собирался |
| Поправки к канону | ✅ сработали, и сразу. Google SRE и AWS Builders' Library по ретраям — не два независимых голоса: обе описывают одну практику, и обе от облачных провайдеров с похожим профилем нагрузки. Записано как один голос типа 1/4, а вес дала работа OSDI '22 с данными |
| Сбор до сверки с корпусом | ✅ оправдал себя дважды. Обе дыры в карточках (P-DEG-01, P-DEG-06) нашлись именно потому, что реестр собирался снаружи. Начни я с наших карточек — получил бы их оглавление |
| Ожидаемый объём 5–8 проблем | ✅ восемь, из них одна не проходит критерий |
Что предлагаю поправить в методе#
- Реестр — список блоков, а не таблица. Правка вёрстки, не формы. Внести в
00-plan.md, раздел 3. - Смягчить критерий общности. Вместо «три разных типа» — «канон плюс хотя бы одно независимое подтверждение: данные, публичный разбор или наш собственный прогон», и отдельная пометка у записей, где подтверждения нет вовсе (как у P-DEG-08). Строгий критерий отсекает не слабые записи, а те, которые никто не измерял, — а это большинство.
- Добавить в форму поле «жанр»: карточка, решение или и то и другое. Пилот показал, что реестр проблем сам по себе не говорит, что писать — памятку или документ решения, а разница принципиальная.
Третий пункт — не косметика. Без него исследование ответит на вопрос «какие бывают проблемы», но не на тот, ради которого затевалось: каким должен быть набор документов решений.
Чем кончился пилот#
Документ написан: D-06 v1.0. Собран из реестра, а не из пробелов набора, и видно, как именно:
| Запись реестра | Куда вошла в D-06 |
|---|---|
| P-DEG-04 · что показывать, когда данных нет | Предмет документа |
| P-DEG-01 · система не возвращается после снятия причины | Дисквалификатор «суррогат добывается через отказавшую зависимость» |
| P-DEG-02 · ретраи усиливают нагрузку | Вопрос 7 и тот же дисквалификатор |
| P-DEG-03 · нет классов важности | Вопрос 5 и правило группировки функций в одно применение |
| P-DEG-05 · путь не исполняется | Дисквалификатор и обязательная строка записи в ADR |
| P-DEG-06 · зависимость жива по проверке | Вопрос 6 и дисквалификатор о способе обнаружения |
| P-DEG-07 · таймауты не согласованы | Не вошла: это механика, а не выбор. Осталась карточкой REL-01 |
| P-DEG-08 · режим становится постоянным | Дисквалификатор «у режима нет выхода» и условие пересмотра |
Семь записей из восьми вошли вопросами и дисквалификаторами, восьмая стала предметом. Ни одна не стала разделом — это и есть разница между реестром проблем и документом решения: реестр перечисляет, документ выбирает.
P-DEG-07 не вошла вовсе, и это важнее, чем кажется. Она прошла в реестр как проблема, но при сборке документа выяснилось, что выбора в ней нет: согласовать таймауты по цепочке — не решение, а работа. Поле «жанр», добавленное в форму записи по итогам пилота, отсеяло бы её на входе. Правка проверена задним числом — и оказалась нужной.
Что пилот дал сверх документа
- Форма записи выдержала восемь заполнений, но сменила вёрстку и получила девятое поле.
- Критерий общности оказался слишком строгим и смягчён.
- Две дыры в карточках, которых прогоны показать не могли.
- Подтверждение, что механика у нас покрыта, а решений нет — и что документ решения должен начинаться там, где карточки заканчиваются, а не пересказывать их.