Преимущества отказоустойчивых систем

Как вы справляетесь с неожиданным сбоем или состоянием системы?

Вы справитесь с ним изящно и сделаете попытку вернуть ответ? (fail-safe).

Или же вы останавливаете сбой на его пути, позволяете ему взорваться и подаете сигнал тревоги? (быстрое решение)

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

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

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

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

Заметные сбои облегчают поиск ошибок

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

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

Более простая отладка

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

Избегайте каскадных сбоев

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

Меньшая когнитивная нагрузка и простые ментальные модели

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

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

Ассертивное программирование

Существует целая методология разработки программного обеспечения для энтузиастов безотказной работы, называемая ассертивным программированием, о которой я впервые прочитал в книге «Прагматичный программист».

Ассертивное программирование следует принципу быстрого отказа, используя утверждения в коде для непрерывной проверки состояния системы, отбрасывая (аварийно завершая работу), если критерии утверждения не были выполнены.

Вот пример:

const adult = generateAdult();
assert(adult.age >= 18);
sellItemTo(adult);
Вход в полноэкранный режим Выход из полноэкранного режима

Мы добавляем утверждение после генерации adult в качестве защитной проверки, чтобы гарантировать, что система дойдет до строки 3, только если утверждение adult.age >= 18 будет истинным. Вы можете подумать: «Но ведь этого никогда не произойдет». Хотя этот пример является чрезмерным упрощением, всегда стоит добавлять утверждения, чтобы гарантировать, что то, что не может произойти, не произойдет.

Утвердительное программирование — это хорошая практика для подтверждения своих предположений в процессе написания кода, особенно если он довольно умный и склонен к ошибкам:

function someCrazyCalculationThatReturnsAPositiveNumber(num) {
  // do something with num
  // ...
  return result;
}

for (let i = 0; i < total; i++) {
  const a = someCrazyCalculationThatReturnsAPositiveNumber(i);
  assert(a > 0); // I don't entirely trust my crazy calc code yet
  doSomethingWith(a);
}
Войти в полноэкранный режим Выход из полноэкранного режима

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


Я надеюсь, что эта статья пролила немного больше света на многие преимущества быстрого отказа, и вы будете чаще использовать этот тип подхода в своих решениях. Спасибо, что прочитали, и я с удовольствием выслушаю ваши мысли. Не стесняйтесь общаться со мной в Twitter или LinkedIn!

Оцените статью
Procodings.ru
Добавить комментарий