[Перевод] Дзен Эрланга, часть 2

задняя часть Python Программа перевода самородков продукт Erlang

так же плохо, как и все остальное

Дзен Эрланга

Если вы не читали первую часть этой статьи, пожалуйста, прочтите первую часть:Дзен Эрланга: Часть 1.

生产环境中的 Bug

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

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

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

С другой стороны, произошла временная ошибка. Джим Грей изобрел эти термины. Он сообщил, что на данном клиентском сайте ошибка 132 — это только одна бурская ошибка (воспроизводимая ошибка). ошибка, обнаруженная в производственной среде, есть ошибка Heisenberg 131/132 (невоспроизводимая ошибка). Их трудно вызвать, если они являются реальными ошибками, они могут возникать только один раз на миллион доз, это один раз, тогда вашей системе всегда потребуется некоторая нагрузка для их захвата; в системе, обрабатывающей 100 000 запросов в секунду, одна из 1 000 000 000 ошибок возникает каждые 3 часа, миллионная ошибка возникает раз в 10 секунд, но в тестовой среде подобная ошибка встречается редко.

Если не обращаться должным образом, у нас будет много ошибок и неудач.

通过重启来处理 bug

Итак, насколько эффективна перезагрузка как стратегия?

Для воспроизводимых ошибок в основных функциях перезагрузка бесполезна. Для воспроизводимых ошибок в редко используемых участках кода это зависит от ситуации; если функция важна для очень небольшого числа пользователей, перезагрузка мало что даст. Если это небольшая функция, которую все используют, но не особо заботятся о ней, этого достаточно, чтобы начать сначала или игнорировать неудачу. Например, если функция «тыкать» в facebook не работает (не знаю, существует ли эта проблема до сих пор), это не повлияет на работу многих пользователей.

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

Откат к известному стабильному состоянию и повторное повторение той же операции с меньшей вероятностью затронет странный контекст, вызвавший это. Поэтому возможная катастрофа — это всего лишь всплеск в системе, и пользователи быстро учатся приспосабливаться.

Затем вы можете использовать ведение журнала, отслеживание или различные инструменты самоанализа (все они готовы к использованию в Erlang), чтобы находить, понимать и исправлять проблемы, чтобы гарантировать, что они не повторятся. Или вы можете принять решение терпеть их, потому что для решения проблемы требуется огромное количество усилий.

臭名昭著的 bsd

Этот вопрос был задан на форуме, где я обсуждал программирование и модель Erlang. Я привел его дословно, потому что это хороший пример, который задают многие люди, когда слышат о перезагрузке и возможностях Erlang.

Я хотел бы проиллюстрировать, как проектировать систему в Erlang, на реальном примере, который больше подчеркивает ее возможности.

监控树示例

С супервайзерами (прямоугольники со скругленными углами) мы можем начать создавать глубокие процессы. Здесь у нас есть система выборов с двумя деревьями: дерево подсчета и дерево отчетности в реальном времени. Дерево подсчета отвечает за подсчет и хранение результатов, а дерево отчетности в реальном времени предназначено для того, чтобы люди могли подключиться к нему, чтобы увидеть результаты.

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

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

Сам процесс OCR может отслеживать код, написанный на C как автономный агент и связанный с ним. Это дополнительно изолирует этот код C от сбоя виртуальной машины для лучшей изоляции или распараллеливания.

Еще одна вещь, которую я хотел бы отметить, это то, что у каждого директора есть настраиваемая устойчивость к сбоям; региональные директора могут быть очень терпимыми, обрабатывая 10 сбоев в минуту, в то время как уровень хранения может быть довольно терпимым к сбоям, если ожидания правильные Не прощают, отключаются навсегда после 3 сбоев в час, если мы хотим, чтобы это было правильно.

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

Таким образом, определяя все это, мы можем изолировать опасный код в процессе, который имеет высокую устойчивость или отслеживается, и перемещать данные в более стабильный процесс по мере их поступления в систему. Если код OCR на C опасен, он может дать сбой и безопасно перезапуститься. Когда он работает, он передает свою информацию в процесс Erlang OCR. Процесс может верифицировать, а может сам рухнуть, а может и нет. Если информация достоверна, она перемещается в процесс Count, которому поручено сохранять очень простое состояние и, в конечном итоге, сбрасывать это состояние в базу данных, сохраняя безопасное и независимое поддерево.

Если процесс OCR завершается, он автоматически перезапускается. Если он слишком часто дает сбой, он закрывает свой собственный менеджер и перезапускает эту часть поддерева, не затрагивая остальную часть системы. Если это решит проблему, отлично. Если нет, то процесс повторяется до тех пор, пока не заработает, пока вся система не остановится, потому что что-то явно пошло не так, и мы не можем справиться с этим путем перезагрузки.

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

Этот способ стремится преобразовать код. Постепенно вы обнаружите, что он больше не содержит большого количества выражений if/else, switch или try/catch. Вместо этого он содержит четкий код, объясняющий, что должен делать код, когда все работает. Он больше не содержит множества форм догадок, и ваше программное обеспечение стало более читабельным.

监督子树

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

Также было бы здорово, если бы я мог поменять местами реализацию хранилища или использовать его независимо, например, в других системах. Также может быть полезно изолировать систему отчетности в реальном времени на другом узле или начать предлагать альтернативные средства (например, SMS).

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

OTP apps

Erlang OTP будет использоваться в качестве решения. Создан код приложения OTP для этого поддерева и некоторые метаданные. Метаданные включают основное содержимое, как описано в приложении и номере версии, а также отношение зависимости между указанным приложением. Это очень полезно, потому что позволяет остальным моим приложениям и системам хранения оставаться независимыми, но все же необходимо учитывать кодирование приложения во время выполнения. Я могу хранить всю свою информацию закодированной в системе, но теперь это самостоятельные строительные блоки, и эти блоки легче понять.

На самом деле, люди думают об OTP-приложениях как о библиотеках Erlang. Если ваша кодовая база не является приложением OTP, ее нельзя повторно использовать в других системах. [Примечание: существует много способов указать библиотеки OTP, которые на самом деле не содержат поддеревья, а только модули, которые повторно используются другими библиотеками]

После всего, что мы сделали, наша система Erlang теперь имеет все следующие свойства:

  • Критично или не критично для выживания системы
  • что может выйти из строя и как часто это может произойти, прежде чем оно перестанет быть устойчивым
  • Как программное обеспечение должно запускаться, исходя из каких гарантий и в каком порядке
  • Как программное обеспечение должно выйти из строя, что означает, что оно определяет юридическое состояние, в котором вы находитесь в случае частичного сбоя, и как вернуться к известному стабильному состоянию, когда это произойдет.
  • Как можно обновить программное обеспечение (поскольку оно может быть обновлено в режиме реального времени в соответствии со структурой надзора)
  • Как компоненты зависят друг от друга

Это очень ценно. Еще более ценно заставить каждого разработчика так думать на раннем этапе. У вас меньше защитного кода, и система продолжит работу в случае сбоя. Вам просто нужно просмотреть журналы или состояние системы в режиме реального времени и потратить время на устранение проблемы (если вы чувствуете, что это стоит времени).

晚上睡觉

После всего этого я должен спать спокойно, верно? Надеюсь, да. Здесь я показываю пиксельную диаграмму, которую мы развернули на Heroku несколько лет назад.

Крайний левый угол графика соответствует сентябрю. В то время наш новый прокси-слой (vegur) находится в производстве около 3 месяцев, и мы исправили большинство из них. У пользователей не было проблем, переход прошел гладко, и новые функции используются.

В какой-то момент член команды получил очень дорогой счет по кредитной карте за службу регистрации, которую мы использовали для агрегирования исключений. Вот когда мы взглянули и увидели ужас в крайнем левом углу графика: мы генерируем от 500 000 до 1 200 000 исключений в день! Боже мой, это слишком. но? Если проблема в гейзенбаге и наша система получает 100 000 запросов в секунду, каковы шансы, что это произойдет? Между 1/17000 и 1/7000. Это было часто, но, поскольку это не влияло на обслуживание, мы не замечали этого, пока не пришли счета за пропускную способность и хранилище.

Нам потребовалось некоторое время, чтобы понять ошибку, а затем мы ее исправили. Вы можете видеть, что уровень аномалий после этого все еще низок, может быть, несколько сотен тысяч в день. Они все, что мы знаем, но не имеют никакого эффекта. Два года спустя мы так и не удосужились это исправить, потому что несмотря на это система работает нормально.

预料失败

В то же время не всегда удается хорошо выспаться. Несмотря на ваши лучшие методы проектирования, неудача может выйти из-под контроля.

Несколько лет назад я полетел в Ванкувер. Когда самолет снижался, пилот сказал по рации: «Это капитан, мы собираемся приземлиться. Не паникуйте, потому что мы будем на летном поле несколько минут, пока пожарная часть проверяет самолет. Некоторые гидравлические компоненты вышли из строя, и они хотели убедиться, что нет риска возгорания. У нас есть две резервные системы, и мы должны быть в порядке».

У нас все хорошо. При этом самолет очень хорошо спроектирован.

На этом слайде изображен не тот полет, а другой, который я сделал две недели назад, когда восточная часть Соединенных Штатов была покрыта 24-дюймовым слоем снега. Этот самолет (Joint 734), который, я уверен, столь же надежен, приземлился на взлетно-посадочной полосе. Но когда пришло время отдыха, он наделал много шума, я думаю, это был самолет с АБС, но он продолжал лететь.

Мы пробежали на красный свет в конце полосы, видите на фото, в конце полосы самолет вылетел за пределы полосы, промахнулся по склону, и носовое колесо скрылось в траве. Все хорошо, но это пример отличной инженерной мысли, которая не работает каждый раз.

危险区

Фактически, операция всегда является важным фактором в успешном развертывании системы. Этот слайд очень популярен Richard Cook (Ричард Кук) Речь вдохновлена ​​(на самом деле это было украдено). Если вы его не знаете, я предлагаю вам пойти на YouTube, чтобы посмотреть видео о своем выступлении, видео великолепно.

Надлежащая системная архитектура и методы разработки до сих пор не могут быть заменены или могут быть нарушены неподходящими операциями; эффективность и полезность инструментов, сценариев, мониторинга, автоматизации и т. как пропускная способность, нагрузка, управление перегрузкой и т. д.). Эти операционные ограничения, если они определены, дадут вам знать, когда дела пойдут плохо, а когда снова наладятся.

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

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

飞机应急措施

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

Всю эту технику развернули, хотя у всех все было хорошо, несмотря на то, что самолеты были очень надежными. Они поступили правильно.

其他好处

Вот некоторые другие вещи, которые вы получаете с Erlang. Не так много, чтобы сказать о них, просто у меня есть некоторый интерес к переходу на его использование, вот и все.

Последний пункт стоит прокомментировать. Один из рисков, который возникает в языках, которые очень гибки в своем подходе к проектированию системы, заключается в том, что используемые вами библиотеки могут не делать ничего так, как вы думаете, имеет смысл. В таких случаях вы должны либо не использовать библиотеку, либо манипулировать кодовой базой с непоследовательным дизайном. Этого не происходит в Erlang, потому что все используют один и тот же проверенный метод для достижения цели.

组件如何交互

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

Звучит просто, но творит чудеса. Если вы считаете, что обычный случай сбоя, который вы можете понять, работает, тогда вся ваша обработка ошибок может быть применена к этому случаю. Вам больше не нужно беспокоиться или писать защитный код. Вы просто пишете, что должен делать код, а остальное диктует структура программы. Пусть развалится.

Erlang 之禅

В этом суть Erlang: сначала создавайте взаимодействия, удостоверившись, что худшее, что может случиться, все еще возможно. Тогда в вашей системе будет немного ошибок или сбоев, которые заставят вас нервничать (а когда это произойдет, вы сможете все проанализировать во время выполнения!), так что вы можете сесть и расслабиться.


Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.