Системное мышление Границы системы: как выбор границы меняет вывод
0%

Границы системы: как выбор границы меняет вывод

Границы системы: как выбор границы меняет вывод

«Отдельных систем не существует. Мир — континуум. Где провести границу вокруг системы, зависит от цели разговора». — Донелла Медоуз, «Thinking in Systems» (2008)

Фраза звучит как разрешение делать что угодно. Означает она противоположное: раз граница выбирается, за неё отвечает тот, кто выбрал. В прошлой главе мы договорились, что система — это элементы, связи и назначение. Но чтобы перечислить элементы, надо знать, где остановиться: граница логически первична.

Сцена: два честных отчёта об одном инциденте

Пятница, 14:20. Оформление заказов деградировало на 40 минут. Через неделю — два постмортема.

Команда платежей. «Сервис отработал штатно: p99 обработки 38 мс при SLO 120 мс, ошибок 0.02%, деплоев не было. Причина вне нашей зоны — всплеск входящего трафика в 2.4 раза. Действие: попросить смежников предупреждать о нагрузочных тестах».

Команда заказов. «В 14:18 выкатили батчинг записи с окном 100 мс. Наш p99 вырос с 31 до 106 мс — в пределах SLO 150 мс. Причина вне нашей зоны: платежи начали таймаутиться. Действие: попросить платежи поднять лимиты».

Оба отчёта фактически верны, каждая метрика измерена правильно, и оба вывода бесполезны. События «всплеск трафика в 2.4 раза» не было: клиент с таймаутом 100 мс начал ретраить запросы, задержавшиеся из-за нового окна батчинга; ретраи подняли нагрузку; нагрузка подняла задержку; петля замкнулась. Причина лежит на стыке, а стык не попал ни в одну из двух границ. Это не история про плохие команды, а структурное свойство: когда граница режет петлю обратной связи пополам, каждая половина выглядит как внешнее возмущение.

Что такое граница: не два круга, а три

Бытовое представление — «есть система и есть внешний мир». Рабочее требует трёх зон.

Эндогенное — переменные, чьё поведение модель объясняет: у них есть причины внутри. Экзогенное — входы: модель их использует, но не объясняет. Исключённое — то, чего в модели нет вообще; самая опасная зона, потому что у неё нет ни строки в дашборде, ни узла на схеме, и её отсутствие не замечают.

Ключевой приём системной динамики Джея Форрестера — эндогенная точка зрения: интересующее поведение должно порождаться структурой внутри границы, а не подаваться снаружи как последовательность шоков. Отсюда критерий из «Industrial Dynamics» (1961): если для объяснения происходящего приходится каждый раз добавлять новое внешнее событие — граница проведена слишком узко. Посмотрите на пунктирные стрелки: в сцене выше «всплеск трафика» был экзогенным входом для обеих команд, а стоит перевести RPS в эндогенные — сделать его функцией собственной задержки — и модель воспроизводит инцидент без внешних шоков. Вывод переворачивается: не «смежники нас залили», а «мы сами замкнули петлю».

Граница — это решение, и у него есть критерий

Свобода выбора границы часто читается как «любая граница годится». Неверно: граница оценивается по одному признаку — воспроизводит ли модель внутри неё то поведение, которое вас интересует. Отсюда порядок работы, обратный интуитивному.

  1. Сначала режим поведения (reference mode) — не схема, а график во времени: «очередь растёт с 09:00 до 18:00 и не рассасывается за ночь», «после каждого крупного релиза MTTR растёт три недели, потом возвращается». Без графика границу нечем оценивать.
  2. Потом горизонт времени. Он входит в границу наравне со списком элементов и должен быть длиннее задержки между действием и последствием, иначе последствие окажется за пределами модели (см. задержки).
  3. И только потом список элементов. Элемент попадает внутрь, если без него режим поведения не воспроизводится.

Тест на «слишком узко». Приходится ли объяснять поведение чередой внешних событий? «В понедельник всплеск, в среду релиз смежников, в пятницу упала сеть» — и так каждый месяц с новым списком. Регулярность событий, которые вы считаете случайными, — сильный признак, что их источник внутри контура, просто снаружи вашей границы.

Тест на «слишком широко». Появились ли переменные, которые нельзя измерить, нельзя изменить, и при изменении которых на порядок вывод не меняется? Каждая такая — чистый минус: степеней свободы больше, предсказаний столько же. Итого: граница правильна не тогда, когда она полна, а тогда, когда её ошибочность можно обнаружить.

Шесть границ, которые обычно не совпадают

Слово «граница» означает минимум шесть разных вещей, и половина организационных патологий — следствие того, что их считают одной.

граница вопрос, на который она отвечает где обычно записана
физическая что за процесс, контейнер, VPC схема деплоя
ответственности кого будят ночью, кто владеет SLO расписание дежурств
измерения где стартует таймер, где стоит счётчик конфиг метрик
управления что можно изменить без согласования нигде
учёта чей бюджет платит, чья квота расходуется биллинг
времени горизонт квартала или трёх лет нигде

Обратите внимание на две строки «нигде»: именно незаписанные границы расходятся с остальными незаметно. Патологии живут не внутри зон, а в зазорах между ними.

  • Ответственность есть, управления нет. Дежурного будят за общую базу, конфигурацию которой он менять не может. Доступна одна реакция — обходной путь; со временем обходные пути становятся архитектурой.
  • Управление есть, измерения нет. Команда владеет воркером, но SLO меряется на ответе API: отставание очереди растёт часами при зелёном дашборде.
  • Измерение есть, ответственности нет. Метрику снимают, но реагировать никто не обязан. Такие метрики деградируют предсказуемо: сначала на них перестают смотреть, потом ломается сбор.
  • Учёт уже управления. Команда платит за свои поды, но не за нагрузку на общий кластер БД — готовая конструкция для трагедии общего ресурса, разберём ниже.

Три границы вокруг одной цепочки: деплой, дежурство и измерение SLO не совпадают

Приём: возьмите один компонент и честно ответьте по каждой из шести границ, внутри он или снаружи. Компоненты с расходящимися ответами — ваш список на разбор; обычно их два-три, и они же фигурируют в половине инцидентов. Отдельно стоит развести системную границу и ограниченный контекст из DDD (bounded context): первый — граница объяснения поведения во времени, второй — граница языка предметной области, внутри которой «заказ» значит ровно одно. Они часто не совпадают, и это нормально: критерии качества у них разные.

Граница измерения: где включается таймер

Самая коварная из шести, потому что выглядит объективным фактом, а является конструкторским решением.

Между T0 и T4 — четыре разных «времени ответа», и каждое кто-то называет латентностью. Серверный SLO меряет T2–T3 и умалчивает про три четверти ожидания. Это не подтасовка: команда добросовестно меряет то, чем управляет, — но выводы из отрезка T2–T3 нельзя переносить на впечатление пользователя. Есть и частный случай, где граница измерения искажает результат на два порядка: нагрузочный генератор шлёт запрос, ждёт ответа, шлёт следующий, и если сервис на 200 мс встал, за эти 200 мс он отправил один запрос вместо двухсот — медленные замеры просто не попали в выборку. Гил Тене назвал это coordinated omission: измеритель «согласованно» замолкает вместе с системой (How NOT to Measure Latency).

"""Одна и та же деградация, две границы измерения."""
import math

N, STALL_AT, STALL_MS = 10_000, 5_000, 200

def quantile(xs: list[float], p: float) -> float:
    s = sorted(xs)                                  # O(n log n) по времени, O(n) по памяти
    return s[min(len(s) - 1, math.ceil(p * len(s)) - 1)]

# «Внутри клиента»: меряем только отправленные запросы — во время затыка отправлен ровно один.
naive = [1.0] * (N - 1) + [float(STALL_MS)]
# «По расписанию»: запрос должен был уйти в момент i, а ушёл после затыка.
corrected = [float(STALL_AT + STALL_MS - i) if STALL_AT <= i < STALL_AT + STALL_MS else 1.0
             for i in range(N)]
for name, data in (("внутри клиента", naive), ("по расписанию", corrected)):
    print(f"{name:>16}: p50={quantile(data, .5):6.1f}  "
          f"p99={quantile(data, .99):6.1f}  p99.9={quantile(data, .999):6.1f}")
# внутри клиента: p50=   1.0  p99=   1.0  p99.9=   1.0
#  по расписанию: p50=   1.0  p99= 100.0  p99.9= 190.0

Обе цифры получены из одного и того же поведения системы, ошибки в коде нет ни в одном варианте, а p99 отличается в сто раз исключительно из-за границы измерения. Следствие: утверждение «p99 = 40 мс» неполно без указания границы. Техника — в «Измерение производительности» и «Наблюдаемость».

Разбор: батчинг, который «сэкономил» CPU

Вернёмся к сцене и посчитаем. Модель намеренно грубая: важен не абсолютный результат, а то, что меняется от переноса одной переменной через границу. Допущения (все проверяемы и все могут оказаться неверными): поток пуассоновский, обслуживание экспоненциальное — приближение M/M/1 со средним ожиданием 1/(C − λ); окно батчинга даёт равномерную задержку от 0 до B мс поверх очереди; клиент ретраит по таймауту T не более двух раз; ретраи неотличимы от новых запросов.

"""Ёмкость сервиса при экзогенной и эндогенной нагрузке."""
from math import exp

def p_timeout(lam: float, C: float, B_ms: float, T_ms: float) -> float:
    """Доля запросов, чьё полное время превысило таймаут клиента."""
    if lam >= C:
        return 1.0
    W = 1000.0 / (C - lam)                                          # ожидание в очереди, мс
    if B_ms == 0:
        return exp(-T_ms / W)
    return (W / B_ms) * (exp(-(T_ms - B_ms) / W) - exp(-T_ms / W))  # усреднение по окну батчинга

def fixpoint(lam0: float, C: float, B_ms: float, T_ms: float, retries: int = 2):
    """Неподвижная точка потока с учётом ретраев; None — устойчивой точки нет. O(k), k ~ 5-20."""
    lam = lam0
    for _ in range(500):
        p = p_timeout(lam, C, B_ms, T_ms)
        new = lam0 * sum(p ** k for k in range(retries + 1))
        if new >= C:
            return None, p                                          # поток превысил ёмкость: коллапс
        if abs(new - lam) < 1e-6:
            return new, p
        lam = new
    return lam, p

CONF = {"без батчинга": (1900, 0, 1.00), "с батчингом": (2600, 100, 0.62)}  # ёмкость, окно, CPU/запрос
for lam0 in (1200, 1750):
    for name, (C, B, cpu) in CONF.items():
        lam, p = fixpoint(lam0, C, B, T_ms=100.0)
        print(f"{lam0} rps / {name:>13}: поток={lam:7.1f} (+{100*(lam/lam0-1):.2f}%)  "
              f"таймауты={100*p:5.2f}%  p99={B + 4.605*1000/(C-lam):6.1f} мс  CPU={cpu*lam:6.0f}")
1200 rps /  без батчинга: поток= 1200.0 (+0.00%)  таймауты= 0.00%  p99=   6.6 мс  CPU=  1200
1200 rps /   с батчингом: поток= 1208.7 (+0.72%)  таймауты= 0.72%  p99= 103.3 мс  CPU=   749
1750 rps /  без батчинга: поток= 1750.0 (+0.00%)  таймауты= 0.00%  p99=  30.7 мс  CPU=  1750
1750 rps /   с батчингом: поток= 1771.4 (+1.22%)  таймауты= 1.21%  p99= 105.6 мс  CPU=  1098

Внутри границы команды заказов батчинг — однозначная победа: CPU на 37% меньше, p99 внутри своего SLO. Это правда, и её надо признать: локальная оптимизация здесь не выдумана. Расширим границу на клиента. Бинарный поиск по максимальному λ0, при котором неподвижная точка ещё существует, даёт настоящий потолок:

конфигурация потолок при экзогенной нагрузке потолок при эндогенной завышение
без батчинга 1900 rps 1838 rps 3.3%
с батчингом 2600 rps 2288 rps 12.0%

Батчинг поднял ёмкость с 1900 до 2600 rps, но реальный потолок вырос только до 2288. Важнее другое: ошибка планирования выросла вчетверо — раньше расчёт по экзогенной нагрузке врал на 3%, теперь на 12%. Изменение перевело систему в режим, где ретраи стали значимой эндогенной переменной. За потолком 2288 неподвижной точки нет вообще: поток растёт до ёмкости и держится там, пока кто-нибудь не выключит ретраи — механика метастабильных отказов из Metastable Failures in Distributed Systems.

Знаки читаются так: + — растёт причина, растёт следствие; — растёт причина, падает следствие. Цикл L → TO → R → Q → U → L состоит из одних плюсов, значит он усиливающий: любое отклонение он раздувает. Путь B → CPU → U — с минусом, уравновешивающий, и работает мгновенно. Поэтому решение и выглядит выигрышным: уравновешивающий эффект виден сразу, усиливающий — только под нагрузкой (разбор таких конструкций — в следующей главе).

Проверяемое предсказание. Гипотеза «нагрузка экзогенна» фальсифицируема: если она верна, рост нашего p99 на 70 мс не должен менять входящий RPS. Ставим окно батчинга под фиче-флагом, включаем на 10% трафика при стабильном спросе, сравниваем входящий RPS в контрольной и тестовой группах: разница за пределами шума опровергает гипотезу, и клиента надо втягивать внутрь границы.

Разбор: кэш внутри границы или снаружи

Типичная строчка в расчёте ёмкости: «hit rate кэша 92%, значит на базу пойдёт 8% трафика». Здесь hit rate — экзогенный параметр, и модель говорит: база выдержит, реплики не нужны. Если перенести кэш внутрь границы, у hit rate появляются причины: рабочее множество зависит от профиля трафика, а профиль меняется при деградации; вытеснение зависит от объёма; при росте задержки базы растёт время заполнения кэша, значит растёт доля промахов; промахи повышают нагрузку на базу — снова усиливающая петля.

Различие наблюдаемо и потому разрешаемо экспериментом: если hit rate экзогенен, он не должен зависеть от задержки базы. Внесите задержку 50 мс на 5% запросов к базе (простейший fault injection): не сдвинулся — экзогенность подтверждена для этого диапазона, поплыл — параметр переводим в эндогенные и пересчитываем ёмкость. Мы не спорим, «правильно» ли считать кэш частью системы, а формулируем, чем варианты различаются наблюдаемо, и меряем: спор о границе, который нельзя свести к наблюдению, — это спор о вкусах. Дальше: «Кэширование», «Паттерны устойчивости».

Разбор: найм — граница команды против границы организации

Внутри границы команды всё просто: наняли двух инженеров, расчётная мощность выросла на 40%, мощность есть сумма людей на производительность. Внутри границы организации онбординг потребляет время сеньора — того самого, который единственный держит ключевой сервис; мощность в первые месяцы падает, а координационная нагрузка растёт квадратично по числу пар. Это закон Брукса из «Мифического человеко-месяца» (Fred Brooks, 1975): «добавление рабочей силы к запаздывающему проекту задерживает его ещё больше».

Честно про доказательность: закон Брукса — обобщение опыта разработки OS/360, а не измеренная закономерность. Падение производительности при быстром росте воспроизводилось в исследованиях по ramp-up, но эффект сильно зависит от структуры работы: там, где задачи слабо связаны, он мал. Считайте это хорошо мотивированной гипотезой с ограниченной областью применимости; проверить у себя просто — постройте lead time по неделям вокруг прошлых расширений команды. Практика — в треке «Тимлид»: онбординг и топологии команд.

Разбор: техдолг — граница по времени

Здесь граница проходит не по элементам, а по горизонту. При горизонте в квартал техдолг вообще не переменная: он не успевает проявиться, и модель честно показывает, что торопиться выгодно. При горизонте в два года это запас с входящим потоком (скорость накопления при спешке), исходящим (скорость выплаты) и эффектом процента: чем больше запас, тем медленнее любое изменение, тем выше соблазн опять сделать быстро и грязно (запасы и потоки).

Следствие: спор «надо ли чинить техдолг» почти никогда не является спором о фактах. Это спор о горизонте, замаскированный под спор о приоритетах, и пока горизонт не назван вслух, обе стороны правы внутри своих границ. Первый ход — не аргументы, а вопрос: «на каком горизонте мы оцениваем это решение?». Прикладная сторона — в «Техдолг».

Разбор: общий ресурс — граница учёта

Общий кластер БД, общие раннеры CI, общий Kafka. Каждая команда оптимизирует своё время сборки, добавляя параллельных джоб; суммарная очередь растёт; сборки замедляются у всех; в ответ каждая команда добавляет ещё джоб. Трагедия общего ресурса в чистом виде — механизм описан у Хардина (Science, 1968). Причина не в жадности, а в конфигурации границ: выигрыш попадает внутрь границы команды, издержка — за неё.

Важная поправка, которую часто опускают: Элинор Остром показала на большом корпусе полевых исследований, что общие ресурсы регулярно управляются устойчиво без приватизации и без внешнего принуждения — при наличии наблюдаемости расхода, понятных правил и механизма разрешения споров («Governing the Commons», 1990, нобелевская лекция). В инженерном переводе это три вещи: видимость расхода по потребителям (дашборд «минуты раннеров по командам», а не общая цифра), квоты или ценник (перенос издержки внутрь границы того, кто её создаёт) и механизм исключений (иначе правила начнут обходить и вы получите теневую инфраструктуру). Все три — операции над границами, а не над поведением людей; это общий признак хорошего системного вмешательства, подробнее в главе «Точки воздействия».

Как записывать границу, чтобы к ней можно было вернуться

Граница, оставшаяся в голове автора, через месяц становится неотличимой от «объективной картины мира». Записывайте её явно — в ADR, дизайн-док или шапку постмортема; формат любой, смысл в том, чтобы каждая строка была опровержима.

# приложение к ADR-042 «Батчинг записи в сервисе заказов»
behavior_of_interest: "p99 оформления заказа и доля успешных оформлений"
reference_mode: "p99 стабилен 30 мс, при пиках скачки до 400 мс раз в 2-3 недели"
time_horizon: "90 дней — две недели на разгон плюс два пиковых цикла"
endogenous:                      # объясняем внутри модели
  - name: "длина очереди на запись; задержка API; доля запросов сверх таймаута клиента"
  - name: "входящий поток с учётом ретраев"
    note: "перенесено из exogenous после инцидента 14 марта"
exogenous:                       # берём как вход, сценарии заданы явно
  - name: "внешний спрос, rps"
    scenarios: [1200, 1750, 2100]
    source: "квантили за 90 дней из метрик балансировщика"
  - name: "ёмкость кластера БД"
    note: "фиксирована на горизонте, изменение требует отдельного ADR"
excluded:                        # сознательно не рассматриваем
  - name: "hit rate кэша"
    assumption: "не зависит от задержки БД в диапазоне до 150 мс"
    falsifier: "fault injection 50 мс на 5% запросов; сдвиг hit rate > 2 п.п. опровергает"
  - name: "мотивация команды"
    assumption: "влияет медленнее горизонта модели"
    falsifier: "нет дешёвого — помечено как непроверенная гипотеза"
review_trigger: "любой инцидент, объяснённый внешним всплеском трафика"

Рабочим, а не декоративным документ делает поле falsifier — наблюдение, которое опровергнет допущение. Если его нельзя придумать, честнее написать «непроверенная гипотеза», чем изобретать наукообразие; review_trigger при этом задаёт условие пересмотра — прямое следствие теста на «слишком узко».

Пределы метода: где граница перестаёт быть проверяемой

Теперь честная часть. Работа с границами легко вырождается в производство красивых схем, которые ничего не предсказывают. Признаки вырождения конкретны. Схема без режима поведения: если нельзя назвать график во времени, который модель должна воспроизвести, это не модель, а иллюстрация — её невозможно опровергнуть, а значит и подтвердить.

Граница, растущая после каждого возражения. На любое «а как же X?» автор добавляет X внутрь. Через три итерации внутри границы вся организация и рынок, модель объясняет всё постфактум и не запрещает ничего. Природа ошибки та же, что у нефальсифицируемых объяснений в «Причинные и статистические ошибки».

Стрелки без знаков и без данных. Причинная стрелка утверждает направление и знак; если ни то, ни другое не подкреплено измерением или явно названным допущением, она не несёт информации. Диаграмма из двадцати таких стрелок не становится информативнее — она становится убедительнее, а это хуже. Стрелка «нагрузка → ошибки» выглядит как причинное утверждение, но получена обычно из совпадения графиков: схема сама по себе причинности не даёт, причинность приходит из вмешательства («Научная и инженерная аргументация»).

Чего метод не даёт в принципе. Граница не определяет параметры: даже идеально проведённая, она не скажет, чему равна ёмкость. Без данных нет количественного прогноза — структура без измерений даёт класс поведения (растёт / колеблется / насыщается), а не числа. И она не разрешает ценностные конфликты: вопрос «чьи издержки считать» не технический. Им явно занимается Critical Systems Heuristics Вернера Ульриха (wulrich.com) — набор вопросов вида «кто бенефициар, кто принимает решения, кто затронут, но не имеет голоса»; его доказательная база это разборы случаев, а не эксперименты, поэтому он полезен как чек-лист и бесполезен как доказательство. Резюме: системное мышление хорошо объясняет форму поведения и плохо даёт числа — требуйте от модели ровно того, что она может дать (подробнее в главе «Моделирование и его пределы»).

Честно про доказательную базу

Метод не появился в вакууме, и его история — в основном история споров о границах.

Urban Dynamics (1969). Книга Форрестера выдавала контринтуитивные выводы о городской политике — например, что строительство дешёвого жилья ухудшает положение бедных районов. Критика начала 1970-х показала: выводы чувствительны к неизмерявшимся параметрам и к границе, проведённой так, что миграция между городом и остальной страной оказалась вне модели. Это ровно наш случай — границей был предопределён вывод. Урок не «системная динамика не работает», а «границу предъявляют вместе с выводом и проверяют устойчивость вывода к её сдвигу».

«Пределы роста» и World3 (1972). Модель агрегировала мир до нескольких переменных, не содержала цен и рынков, а результаты подавались как сценарии, но читались как прогнозы. Уильям Нордхаус в «World Dynamics: Measurement Without Data» (The Economic Journal, 1973) предъявил главную претензию: структура задана априори, параметры подобраны без данных. Позже Грэм Тёрнер сопоставил стандартный сценарий с данными за 30 лет и нашёл согласие по агрегатам (Global Environmental Change, 2008) — эту работу тоже критиковали, поскольку согласие агрегатов не подтверждает механизм. Взвешенная позиция: World3 — не подтверждённый и не опровергнутый прогноз, а структурная гипотеза с обсуждаемыми границами; трек на неё не опирается. Знаменитый список из двенадцати точек воздействия в «Leverage Points» Медоуз (1999) — тоже эссе с небесспорным, по признанию автора, порядком пунктов: эвристика для разговора, не измеренная иерархия (оригинал).

Что действительно измерено. Самая твёрдая часть доказательной базы — не модели, а эксперименты о том, как люди рассуждают о системах. Стерман и коллеги показали воспроизводимый эффект: люди систематически ошибаются в задачах на накопление — не могут построить график запаса по графику притока и оттока, даже имея техническое образование (bathtub dynamics, System Dynamics Review, 2000). То же даёт «пивная игра»: участники устойчиво порождают колебания в цепочке поставок из-за задержек, даже зная о них. Вывод скромный, но полезный: интуиция про накопление и задержки систематически подводит, поэтому запасы стоит считать, а не оценивать на глаз.

Безопасность как отдельная линия. Йенс Расмуссен (Safety Science, 1997) и Нэнси Левесон (STAMP, «Engineering a Safer World», полный текст) пришли к тому же выводу с другой стороны: авария редко имеет «корневую причину» внутри одного компонента, она возникает из структуры контроля, и граница расследования предопределяет, что будет названо причиной. Это позиция о том, как строить объяснение, а не предсказательная теория аварий. Общий итог: границы и петли хорошо работают как язык описания и генератор гипотез; количественные предсказания получаются только там, где есть измерения, а всё выходящее за рамки посчитанных примеров читайте как гипотезу для проверки на ваших данных.

Типичные ошибки

  • Граница выбрана по оргструктуре. Дефолт «система = то, что мы катим». Оргструктура коррелирует с архитектурой (закон Конвея, melconway.com), но отражает историю найма, а не структуру поведения.
  • Экзогенная нагрузка по умолчанию. «RPS задан извне» верно ровно до появления ретраев, автоскейлинга, фоновой синхронизации и повторных заходов раздражённого пользователя.
  • Горизонт по циклу планирования. Квартал выбран не потому, что соответствует динамике системы. Если задержка эффекта больше горизонта, модель систематически рекомендует брать в долг.
  • Смешение границы модели и границы ответственности. «Это не наша зона» — корректное утверждение об ответственности и некорректное о причинности. Симметричная ошибка — «это системная проблема» как способ ничего не делать: без проверки и следующего шага внутри вашей зоны управления это пустая фраза.
  • Молчаливое расширение границы в середине спора. Полдиалога обсуждали сервис, потом незаметно перешли к организации: оба правы, согласия нет. Лечится вопросом «мы сейчас про какую границу?». И наоборот, одна граница на все вопросы не работает — для ёмкости, постмортема и найма нужны разные; универсальной «карты системы» не бывает, бывает карта под вопрос.

Мини-итог

  • Граница отделяет три зоны, а не две: эндогенное, экзогенное и исключённое. Опаснее всего третья.
  • Критерий хорошей границы — воспроизведение заранее названного режима поведения, а не полнота. Сначала график во времени, потом горизонт, потом список элементов. Тест на узость: поведение объясняется чередой внешних шоков. Тест на широту: появились переменные, которые нельзя ни измерить, ни изменить.
  • Границы деплоя, ответственности, измерения, управления, учёта и времени не совпадают; патологии живут в зазорах между ними. Перенос одной переменной через границу переворачивает вывод: в примере расчёт завышал потолок на 12% только потому, что ретраи клиента считались внешними. Поэтому границу записывают явно и фальсифицируемо: допущение без опровергающего наблюдения — гипотеза, и называть её надо гипотезой.

Что дальше

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

Петли обратной связи: усиливающие и уравновешивающие

Источники

  • Donella H. Meadows. Thinking in Systems, 2008; «Leverage Points», 1999.
  • Jay W. Forrester. Industrial Dynamics, 1961; Urban Dynamics, 1969 — и критика последней в 1972–1974.
  • William D. Nordhaus. «World Dynamics: Measurement Without Data». The Economic Journal, 83(332), 1973; Graham Turner. «A comparison of The Limits to Growth with 30 years of reality», Global Environmental Change, 2008, https://doi.org/10.1016/j.gloenvcha.2008.05.001
  • John D. Sterman. Business Dynamics, 2000; Booth Sweeney & Sterman. «Bathtub dynamics». System Dynamics Review, 16(4), 2000.
  • Garrett Hardin. «The Tragedy of the Commons». Science, 162(3859), 1968; Elinor Ostrom. Governing the Commons, 1990, https://www.nobelprize.org/prizes/economic-sciences/2009/ostrom/lecture/
  • Jens Rasmussen. «Risk management in a dynamic society». Safety Science, 27(2-3), 1997; Nancy G. Leveson. Engineering a Safer World, 2011, http://sunnyday.mit.edu/safer-world.pdf
  • Инженерные ссылки по тексту: Bronson et al. «Metastable Failures in Distributed Systems» (HotOS ‘21), Gil Tene «How NOT to Measure Latency», Werner Ulrich «Critical Systems Heuristics», Google SRE Book.

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

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

Доска запросов