Перейти к содержанию

И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 проблем ✅ восемь, из них одна не проходит критерий

Что предлагаю поправить в методе#

  1. Реестр — список блоков, а не таблица. Правка вёрстки, не формы. Внести в 00-plan.md, раздел 3.
  2. Смягчить критерий общности. Вместо «три разных типа» — «канон плюс хотя бы одно независимое подтверждение: данные, публичный разбор или наш собственный прогон», и отдельная пометка у записей, где подтверждения нет вовсе (как у P-DEG-08). Строгий критерий отсекает не слабые записи, а те, которые никто не измерял, — а это большинство.
  3. Добавить в форму поле «жанр»: карточка, решение или и то и другое. Пилот показал, что реестр проблем сам по себе не говорит, что писать — памятку или документ решения, а разница принципиальная.

Третий пункт — не косметика. Без него исследование ответит на вопрос «какие бывают проблемы», но не на тот, ради которого затевалось: каким должен быть набор документов решений.


Чем кончился пилот#

Документ написан: 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 не вошла вовсе, и это важнее, чем кажется. Она прошла в реестр как проблема, но при сборке документа выяснилось, что выбора в ней нет: согласовать таймауты по цепочке — не решение, а работа. Поле «жанр», добавленное в форму записи по итогам пилота, отсеяло бы её на входе. Правка проверена задним числом — и оказалась нужной.

Что пилот дал сверх документа

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