3.3

Смотреть на английском

3.3 Распределённые системы

Обзор и мотивация

Распределённая система это любая система, чьи компоненты работают более чем на одной машине и координируются по сети. В момент, когда вы пересекаете границу процесса по сети, вы наследуете жёсткие истины, которых внутри одного процесса просто нет. Сеть ненадёжна, а её задержка варьируется. Сообщения могут быть потеряны, продублированы, задержаны или переупорядочены. Удалённые компоненты отказывают сами по себе. Общих часов нет. Классические «заблуждения распределённых вычислений» (сеть надёжна, задержка нулевая, пропускная способность бесконечна, топология никогда не меняется) называют ровно те допущения, что вызывают сбои. Ваша задача проектировать с учётом этих реалий с самого начала, а не заново открывать их во время инцидента.

Для большой организации распределённость не опциональна. Любая система, обслуживающая национальный или глобальный масштаб, объединяющая несколько ведомств или требующая высокой доступности, охватит много машин, центров обработки данных и часто регионов. Корпорации ведут системы распределённых транзакций, конвейеры событий и многорегиональные развёртывания. Государства ведут межведомственные интеграции, где каждое ведомство владеет своими системами и никто не контролирует целое. Здесь разрыв между надёжным и хрупким проектом проявляется заголовками о сбоях, пропущенными выплатами пособий и регуляторными последствиями. Приёмы этой главы (рассуждение о согласованности, идемпотентность, повторы с отступлением, предохранители, саги и распределённая наблюдаемость) ваши стандартные защиты.

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

Ключевые принципы

  • Сеть ненадёжна. Проектируйте каждое удалённое взаимодействие в предположении, что оно может быть медленным, отказать, продублироваться или переупорядочиться.
  • Нельзя иметь идеальную согласованность и идеальную доступность во время разделения. Выбирайте намеренно по взаимодействию (CAP/PACELC) и помните, что задержка это цена даже без разделения.
  • Делайте операции идемпотентными. Если операцию можно безопасно повторить, большая часть обработки распределённых отказов становится выполнимой.
  • Каждому удалённому вызову нужен тайм-аут. Неограниченные ожидания превращают одну медленную зависимость в сбой всей системы.
  • Предпочитайте согласованность в конечном счёте там, где позволяет бизнес, но делайте это явным. Пользователи и аудиторы должны понимать, когда они могут увидеть устаревшие данные.
  • Изолируйте отказы. Переборки и предохранители не дают одному отказывающему компоненту каскадом захватить все.
  • Нельзя отлаживать то, чего не видишь. Распределённые потоки требуют сопоставленной трассировки, метрик и журналов на каждом переходе.
  • «Ровно однократная доставка» миф; ровно однократная обработка инженерное достижение. Проектируйте под доставку «как минимум один раз» с устранением дубликатов.

Рекомендации

Рассуждайте о согласованности с помощью CAP и PACELC

Теорема CAP говорит, что во время сетевого разделения система должна выбирать между согласованностью (каждое чтение видит последнюю запись) и доступностью (каждый запрос получает ответ). PACELC добавляет второй размен: Else (когда разделения нет) вы всё равно меняете Latency (задержку) на Consistency (согласованность). Не ставьте это как ярлык всей системы. Решайте по операции. Банковскому переводу баланса нужна сильная согласованность, и он откажет, а не рискнёт двойной тратой. Социальная лента или счётчик просмотров товара может принять устарелость в обмен на доступность и скорость. Записывайте, какую модель согласованности использует каждый поток данных (сильная, причинная, чтение своих записей или согласованность в конечном счёте), чтобы никто не предполагал гарантию, которой система на самом деле не даёт.

Стройте идемпотентность, тайм-ауты, повторы и отступление вместе

Воспринимайте эти четыре приёма как один пакет. Дайте каждой удалённой операции тайм-аут, чтобы зависшая зависимость не могла блокировать поток вечно. При отказе повторяйте, но только операции, безопасные для повтора. Безопасные для повтора значит идемпотентные: назначьте каждому запросу уникальный ключ и пусть получатель устраняет дубликаты, чтобы повторное «списать с карты» не списывало дважды. Разносите повторы экспоненциальным отступлением и дрожанием, чтобы избежать синхронной лавины повторов, превращающей краткий сбой в самонанесённый отказ в обслуживании. Ограничивайте число повторов и общий бюджет времени, потому что повторы вечно лишь переносят отказ. Без идемпотентности повторы опасны. Без отступления повторы разрушительны.

Добавляйте предохранители и переборки, чтобы остановить каскады

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

Управляйте распределёнными транзакциями сагами, а не двухфазной фиксацией

Обычно нельзя удержать единую транзакцию ACID (атомарность, согласованность, изоляция, долговечность) через несколько сервисов или баз данных. Распределённая двухфазная фиксация медленна, блокирует ресурсы и режет доступность. Используйте вместо неё шаблон саги. Моделируйте бизнес-транзакцию как последовательность локальных транзакций, каждая из которых публикует событие, запускающее следующую, с компенсирующим действием для каждого шага, отменяющим его, если позже отказывает какой-то шаг. Саги бывают двух видов. Хореография: сервисы реагируют на события друг друга без центрального контроллера. Оркестровка: центральный координатор ведёт шаги, что проще осмыслить и отслеживать. Саги принимают согласованность в конечном счёте: система проходит через промежуточные состояния и затем сходится. Поэтому проектируйте пользовательский опыт и след аудита с учётом состояний «в процессе» и «скомпенсировано».

Воспринимайте «ровно однократно» как «как минимум однократно» плюс устранение дубликатов

Брокеры сообщений не могут по-настоящему гарантировать ровно однократную доставку при сбоях. Что они и вы можете достичь это доставку как минимум один раз с идемпотентной обработкой, дающую ровно однократные эффекты. Проектируйте потребителей так, чтобы безопасно обрабатывать дублирующиеся сообщения, используя ключи идемпотентности или журнал обработанных сообщений. Точно знайте гарантии порядка и доставки вашего брокера. Для потоков намеренно используйте группы потребителей, разделы и управление смещением и делайте повторную обработку безопасной, чтобы можно было воспроизвести поток после исправления ошибки, не портя нижестоящее состояние.

Инструментируйте распределённые потоки от начала до конца

Примите три столпа наблюдаемости, сопоставленные через границы сервисов. Передавайте идентификатор трассировки/корреляции через каждый переход, чтобы проследить один пользовательский запрос по всем затрагиваемым им сервисам (распределённая трассировка). Испускайте структурированные метрики (процентили задержки, доли ошибок, насыщение, пропускная способность) по сервису и зависимости. Испускайте структурированные журналы, несущие идентификатор корреляции. Используйте всё это для задания целей уровня обслуживания и оповещения о симптомах, которые пользователи действительно ощущают, вроде доли ошибок и задержки, а не только о здоровье отдельных машин. В распределённой системе наблюдаемость не необязательный инструмент. Это единственный способ понимать поведение при частичном отказе.

Компромиссы: плюсы и минусы

ПриёмПлюсыМинусы / цена
Сильная согласованностьПростая ментальная модель, нет устаревших чтенийНиже доступность при разделении, выше задержка, стоимость координации
Согласованность в конечном счётеВысокая доступность, низкая задержка, масштабируемостьУстаревшие чтения, сложное рассуждение, нужно разрешение конфликтов
Повторы с отступлениемАвтоматически переживают преходящие сбоиУсиливают нагрузку при неверном применении; нужны идемпотентность и пределы
Предохранители / переборкиПредотвращают каскадные отказы, быстро отказываютДополнительная сложность, настройка порогов, риск преждевременного срабатывания
Сага (против 2PC)Масштабируемо, доступно, нет распределённых блокировокСогласованность в конечном счёте, логика компенсации, труднее осмыслить

Главный компромисс между координацией и независимостью. Каждая гарантия, которую вы хотите между машинами (согласованность, порядок, ровно однократность), стоит задержки, доступности или сложности. Она требует, чтобы машины пришли к согласию, а согласие по ненадёжной сети дорого. Навык в том, чтобы покупать только гарантии, которые бизнесу действительно нужны, операция за операцией, а всё остальное проектировать под плавную деградацию. Переплатите за согласованность, и ваши системы станут медленными и хрупкими. Недоплатите, и получите молчаливую порчу данных, проявляющуюся как провал аудита месяцы спустя.

Вопросы для обсуждения с командой

  1. Поставляются ли ваши паттерны устойчивости как общие платформенные умолчания или каждая команда изобретает тайм-ауты и повторы заново? Глава считает идемпотентность, тайм-ауты, ограниченные повторы, предохранители и трассировку самыми дешёвыми и надёжными, когда они встроены один раз в общие библиотеки и платформенные умолчания. В большой организации предоставление каждой команде делать их вручную гарантирует несогласованность: на одних путях повторяются неидемпотентные операции, на других нет тайм-аута, третьи не испускают идентификатор корреляции. Принесите свидетельства, проверив выборку сервисов и сосчитав, сколько из них задают явный тайм-аут на каждом удалённом вызове и передают идентификатор трассировки от начала до конца. Если число низкое, исправление это платформенное вложение, а не памятка по обучению. Стандартные умолчания также делают устойчивость тестируемой и проверяемой, что регуляторы в финансах и государстве всё чаще ожидают от вас демонстрировать.

  2. Складываются ли ваши тайм-ауты и бюджеты повторов по всей цепочке вызовов или глубокий запрос повторяет сам себя в сбой? Один запрос часто пересекает много переходов, и если каждый слой независимо повторяет трижды со своим тайм-аутом, самый внутренний отказ умножается, а внешний вызывающий ждёт далеко за любым терпимым для человека пределом. Задайте общий бюджет времени для пользовательского запроса и делите его вниз по цепочке, чтобы внутренний сервис знал, как мало времени осталось, и отказывал быстро, а не повторял в лавину. Принесите ваш граф зависимостей и реальную трассировку, затем сложите худший случай комбинации тайм-аутов и повторов и сравните с тем, сколько пользователь на самом деле будет ждать. Экспоненциальное отступление с дрожанием и предел на общее число попыток не дают краткому сбою стать самонанесённым отказом в обслуживании. Глубокие болтливые синхронные цепочки здесь враг, поэтому ответ может подтолкнуть вас к асинхронным потокам или меньшему числу переходов.

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

  4. Может ли владеющая команда по каждому основному потоку данных назвать модель согласованности, которую он обеспечивает, и соответствует ли этот выбор тому, что бизнесу на самом деле нужно? CAP и PACELC вынуждают к намеренному выбору по операции, однако в большой организации умолчание это дрейф: поток, начатый как согласованный в конечном счёте для малозначимого счётчика, переиспользуется для чего-то, что теперь одобряет платежи или предоставляет доступ, и никто не пересматривает гарантию. Противоположные соображения реальны, поскольку сильная согласованность стоит доступности во время разделения и задержки, даже когда его нет, тогда как согласованность в конечном счёте покупает скорость ценой устаревших чтений и разрешения конфликтов, которое нужно проектировать. Принесите каталог ваших главных потоков данных, каждый помеченный текущей моделью (сильная, причинная, чтение своих записей или согласованность в конечном счёте) и бизнес-последствием устаревшего или потерянного чтения, затем ищите несоответствия, где гарантия сильнее или слабее, чем оправдывают ставки. В корпоративных финансах и в государственных системах пособий или идентификации чтение с согласованностью в конечном счёте за авторитетным решением это тот вид молчаливого дефекта, что проявляется как замечание аудита или неправомерный отказ месяцы спустя, поэтому само рассмотрение свидетельство, которое попросят показать аудиторы.

  5. Как ведут себя ваши многосервисные бизнес-транзакции на полпути и кто отвечает за компенсации, их отменяющие? Замена двухфазной фиксации сагами означает, что система проходит через видимые промежуточные состояния, а шаг может завершиться успешно, пока более поздний отказывает и запускает компенсирующее действие, отменяющее его. Для большой команды это поднимает трудные вопросы владения: цепочка «авторизовать-списать-зачислить-записать в книгу» часто пересекает несколько команд, а компенсация, которую одна команда забыла реализовать, оставляет деньги или записи навсегда несогласованными. Взвесьте хореографию, где сервисы реагируют на события друг друга без центрального контроллера и поток трудно увидеть, против оркестровки, где координатор ведёт и отслеживает шаги ценой компонента, который нужно эксплуатировать. Принесите диаграмму состояний вашей важнейшей саги, список компенсирующих действий и их владельцев и свидетельство того, что состояния «в процессе» и «скомпенсировано» обрабатываются и в пользовательском опыте, и в следе аудита. В банковской сфере и государственном ведении дел регуляторы ожидают, что вы сможете точно восстановить, что произошло с транзакцией, отказавшей на полпути, поэтому немоделированное промежуточное состояние пробел соответствия, а не просто ошибка.

  6. Переживают ли ваши потребители сообщений дублирующуюся и переупорядоченную доставку и можете ли вы это доказать, прежде чем брокер сам поставит вопрос? Ровно однократная доставка миф, поэтому ваша реальная гарантия «как минимум один раз», а потребитель, предполагающий, что каждое сообщение приходит один раз и по порядку, дважды обработает в день, когда брокер заново доставит пакет после переключения при отказе. Между многими командами риск нарастает, потому что один неидемпотентный потребитель на общем потоке может испортить нижестоящее состояние, от которого зависят другие команды, а отказ невидим до воспроизведения или пока разделение не переупорядочит события. Компромисс это инженерная стоимость ключей идемпотентности, журнала обработанных сообщений и явной обработки смещений и разделов против стоимости молчаливой порчи. Принесите список потребителей на ваших критических потоках, отметьте, какие устраняют дубликаты, а какие лишь надеются, и принесите результат настоящего теста повторной доставки или воспроизведения, а не заверение, что всё должно быть нормально. Для межведомственного обмена государственными данными и корпоративных событийных конвейеров способность безопасно воспроизвести поток после исправления ошибки, не создавая дубликатов дел или списаний, и эксплуатационная необходимость, и то, что захотят увидеть аудиторы.

Взгляд по секторам

Стартап. С двумя-тремя движущимися частями и без платформенной команды сопротивляйтесь построению распределённой машинерии, которую не можете укомплектовать. Покупайте устойчивость там, где она живёт, в SDK, который уже даёт ваш платёжный или обменивающийся сообщениями провайдер, и тратьте скудное внимание на два шаблона, предотвращающие необратимый вред: ключ идемпотентности на каждом вызове, двигающем деньги или меняющем учётную запись, и тайм-аут с ограниченным повтором, чтобы нестабильное соединение никогда не действовало дважды. Держите число сетевых переходов малым, потому что каждая добавленная синхронная зависимость ещё одна вещь, которая может отказать, пока у вас нет дежурного, чтобы заметить.

Малый бизнес. У вас, вероятно, нет специалиста по распределённым системам и ограничен бюджет, поэтому воспринимайте это как вопрос «купить, а не строить»: предпочитайте управляемые очереди, управляемые базы данных и платформы, берущие на себя повторы, порядок и устранение дубликатов, а не инфраструктуру, которую нужно эксплуатировать. Формулируйте риск простыми словами, зная, какие операции навредят клиенту, если выполнятся дважды или вернут устаревшие данные, и включайте возможности идемпотентности и доставки «как минимум один раз», которые ваши поставщики уже предлагают. Избегайте сшивания сервисов через общую базу данных ради имитации транзакции, поскольку это тихо воссоздаёт самую трудную распределённую проблему без инструментов управления ею.

Крупная организация. Основная проблема согласованность между многими командами, поэтому поставляйте идемпотентность, тайм-ауты, ограниченные повторы, предохранители и сопоставленную трассировку как общие платформенные умолчания, а не позволяйте каждой группе делать их вручную. Стандартизируйте, как объявляются модели согласованности и гарантии доставки по потоку, проводите внедрение отказов и игровые дни с регулярной периодичностью и делайте общие бюджеты времени складывающимися по глубоким цепочкам вызовов, чтобы один сервис не мог загнать платформу повторами в сбой. Управляйте устойчивостью как измеряемой способностью с целями уровня обслуживания по видимым пользователю симптомам, потому что в вашем масштабе один отсутствующий тайм-аут может каскадом привести к громкому сбою.

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

Примеры

Стартап. У небольшого финтех-стартапа всего две движущиеся части, общающиеся по сети: приложение и сторонний платёжный провайдер. Даже при таком размере он делает так, что каждый запрос на списание несёт ключ идемпотентности, а вызов обёрнут в повтор с отступлением, так что потерянный ответ на нестабильном соединении никогда не списывает с клиента дважды. Пропуск этого кажется дешёвым в первый день, но первое дублированное списание у реального пользователя стоит пожара в поддержке, возврата и вмятины в доверии, которую молодая компания не может себе позволить.

Крупная организация. Глобальная платформа поездок обрабатывает платежи за поездки сагой: авторизовать карту, списать с пассажира, зачислить водителю, записать в главную книгу, каждый шаг локальная транзакция с компенсирующей отменой. Каждый шаг несёт ключ идемпотентности, так что повторы после сетевого тайм-аута никогда не списывают дважды. Вызовы к сервису оценки мошенничества стоят за предохранителем; когда он деградирует в пик, предохранитель размыкается, и поездки откатываются к консервативной оценке вместо блокировки каждой поездки. Когда клиент оспаривает поездку, распределённая трассировка позволяет инженерам проследить её по дюжине сервисов за секунды.

Государственный сектор. Национальная служба идентификации используется многими ведомствами для верификации. Она предлагает строго согласованное чтение для авторитетных проверок статуса (нельзя одобрить пособие по устаревшим данным идентичности) плюс согласованную в конечном счёте кэшированную конечную точку для высокообъёмных несущественных поисков. Межведомственный обмен данными идёт по долговечной очереди сообщений с доставкой «как минимум один раз», а потребитель каждого ведомства устраняет дубликаты по идентификатору сообщения, так что повторно доставленная запись не создаёт дубликат дела. Идентификаторы корреляции проходят через границы ведомств, давая аудиторам сквозную трассировку того, как данные гражданина перемещались между отделами.

Бизнес-обоснование: мотивы, ROI и TCO

Дисциплина распределённых систем покупается дёшево, а её отсутствие оплачивается катастрофически. Стоимость внедрения это инженерное время на встраивание идемпотентности, тайм-аутов, повторов, предохранителей и трассировки в общие библиотеки и платформенные умолчания. Это скромное, в основном разовое вложение, затем приносящее пользу каждой команде. Стоимость отказа измеряется крупными сбоями: один отсутствующий тайм-аут, каскадом приводящий к полному сбою платформы, неидемпотентный платёжный путь, дважды списывающий деньги с тысяч клиентов, или распределённая транзакция без саги, оставляющая данные навсегда несогласованными. Каждое из них громкий инцидент с прямыми потерями выручки, затратами на исправление и репутационным ущербом, а в регулируемых секторах штрафами.

Формулируйте обоснование руководству вокруг доступности и радиуса поражения. Паттерны устойчивости напрямую уменьшают и частоту, и длительность серьёзных инцидентов, метрик, которые руководители уже отслеживают как время бесперебойной работы и среднее время восстановления. Распределённая наблюдаемость единственный самый крупный рычаг MTTR: команды с сопоставленной трассировкой решают межсервисные инциденты за долю времени. Поскольку эти возможности лучше всего поставляются как общие платформенные умолчания, их предельная стоимость на команду низка, а общеорганизационная отдача нарастает. Аргумент TCO прост: встраивание устойчивости с самого начала стоит долю стоимости дооснащения её после сбоя, вынуждающего заняться этим.

Антипаттерны и ловушки

  • Нет тайм-аутов. Одна зависшая зависимость исчерпывает все потоки и роняет всю систему.
  • Повтор неидемпотентных операций. Дублирующиеся побочные эффекты: двойные списания, дублированные записи, удвоенные письма.
  • Лавины повторов. Синхронные повторы без отступления и дрожания, усиливающие мелкий сбой в сбой.
  • Предположение о ровно однократной доставке. Построение потребителей, ломающихся на дублирующихся сообщениях, которые брокер в итоге доставит.
  • Распределённые транзакции через общую базу данных. Сцепление сервисов через одну базу данных для имитации ACID, воссоздающее распределённый монолит.
  • Игнорирование частичного отказа. Код, предполагающий, что удалённый вызов либо полностью успешен, либо полностью отказывает, без обработки «вышел по тайм-ауту, но, возможно, завершился».
  • Нет идентификаторов корреляции. Отладка межсервисного инцидента поиском по несвязанным журналам на десяти машинах.
  • Болтливые синхронные цепочки вызовов. Глубокие синхронные графы зависимостей, где любой один медленный переход останавливает весь запрос.

Модель зрелости

  • Уровень 1: Начальный. Удалённые вызовы воспринимаются как локальные. Тайм-ауты отсутствуют или наивны, повторы отсутствуют или безрассудны, а отказы каскадом идут по системе. Нет общего представления о согласованности или доставке, а отладка межсервисного инцидента означает раскопки по журналам машин постфактум.
  • Уровень 2: Развитие. Некоторые команды добавляют тайм-ауты и базовые повторы и немного идемпотентности, но практики непоследовательны от сервиса к сервису. Журналы централизованы, но не сопоставлены, поэтому прослеживание запроса по переходам ручное. Распределённые транзакции надеются работающими, а не моделируются, а гарантии согласованности живут в головах отдельных инженеров.
  • Уровень 3: Стандартизация. Идемпотентность, ограниченные повторы, отступление с дрожанием, предохранители и переборки стандартны по организации через общие библиотеки. Саги с компенсирующими действиями обрабатывают многосервисные транзакции, есть распределённая трассировка с идентификаторами корреляции, а каждый основной поток данных документирует свою модель согласованности и гарантию доставки. Правила записаны и соблюдаются по организации, а не оставлены каждой команде.
  • Уровень 4: Управление. Устойчивость измеряется относительно базовых значений, а не просто присутствует. Вы отслеживаете долю ошибок, процентили задержки, насыщение и пропускную способность по сервису и зависимости, наблюдаете доли повторов и доли разомкнутых предохранителей и задаёте цели уровня обслуживания по видимым пользователю симптомам. Проверяется, что общие бюджеты времени складываются по цепочкам вызовов, среднее время восстановления межсервисных инцидентов это отслеживаемая метрика, а результаты внедрения отказов и игровых дней питают числа, служащие шлюзом каждого изменения.
  • Уровень 5: Оркестрация. Устойчивость это непрерывно улучшаемое платформенное умолчание, интегрированное по всей организации и адаптивное к условиям. Внедрение отказов рутинно идёт в эксплуатации с узкими радиусами поражения, системы деградируют плавно по проекту, а выбор согласованности и доставки пересматривается по мере смещения нагрузки и бизнес-ставок. Метрики уровня 4 запускают автоматизированные ответы и устойчивую архитектурную эволюцию, так что распределённое хозяйство становится надёжнее с каждым инцидентом, а не просто переживает его.

Идеи для обсуждения

  1. Какие из ваших критических операций действительно идемпотентны сегодня, а какие втайне нет?
  2. Может ли ваша команда по каждому основному потоку данных назвать модель согласованности и гарантию доставки по памяти?
  3. Где предохранитель предотвратил бы ваш последний каскадный сбой?
  4. Сколько времени сейчас требуется, чтобы проследить один падающий запрос по всем затрагиваемым им сервисам?
  5. Какие из ваших «распределённых транзакций» на самом деле полагаются на удачу, а какие настоящие саги с компенсациями?
  6. Если бы ваш брокер сообщений час подряд доставлял каждое сообщение дважды, что сломалось бы?

Главные выводы

  • Предполагайте, что сеть ненадёжна, а отказы частичны; проектируйте каждое удалённое взаимодействие под медленность, потерю, дублирование и переупорядочение.
  • Решайте согласованность против доступности по операции с помощью CAP/PACELC; документируйте модель, которую обеспечивает каждый поток.
  • Идемпотентность, тайм-ауты, ограниченные повторы и отступление с дрожанием один пакет; никогда не принимайте повторы без трёх остальных.
  • Предохранители и переборки сдерживают отказы; саги с компенсациями заменяют неработоспособные распределённые транзакции.
  • Воспринимайте доставку как «как минимум один раз» и делайте обработку идемпотентной, чтобы достичь ровно однократных эффектов.
  • Сопоставленные трассировка, метрики и журналы единственный способ понимать и эксплуатировать распределённые потоки.

Источники и дополнительное чтение

  • Martin Kleppmann, Designing Data-Intensive Applications
  • Andrew Tanenbaum and Maarten van Steen, Distributed Systems: Principles and Paradigms
  • Michael Nygard, Release It!: Design and Deploy Production-Ready Software
  • Sam Newman, Building Microservices
  • Chris Richardson, Microservices Patterns (sagas, transactional messaging)
  • Eric Brewer, “CAP Twelve Years Later” and Daniel Abadi on PACELC
  • Leslie Lamport, “Time, Clocks, and the Ordering of Events in a Distributed System”
  • Cindy Sridharan, Distributed Systems Observability
  • Nassim Nicholas Taleb’s notion of antifragility (as applied by resilience-engineering literature)