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

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

Надежность

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

Грубо говоря, надежность — это как всегда иметь план резервного копирования — даже план резервного копирования для вашего плана резервного копирования. Система может поддерживать бесперебойную работу, даже если что-то идет не так.

Почему это важно?

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

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

Как построить для него

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

Это хорошее эмпирическое правило — подумайте, что произойдет, и как ваша система отреагирует на это.

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

Доступность

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

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

Почему это важно?

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

Как построить для него

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

Если вы переходите на облачные технологии, провайдеры обычно позаботятся обо всем этом за вас. Недавно я писал об архитектуре высокой доступности для AWS.

Ремонтопригодность

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

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

Почему это важно?

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

Как построить для него

К сожалению, для этого нет хорошего и уникального ответа. Некоторые известные принципы, которые вы можете применить к своему коду, такие как SOLID, KISS или YAGNI, восхваляют простоту.

Я считаю Дзен Python хорошим резюме того, как писать код:

Красивое лучше, чем уродливое.
Явное лучше, чем неявное.
Простое лучше, чем сложное.
Сложное лучше, чем сложное.
Плоское лучше, чем вложенное.
Разреженность лучше, чем плотность.
Удобочитаемость имеет значение.
Особые случаи не настолько особенные, чтобы нарушать правила.
Хотя практичность важнее чистоты.
Ошибки никогда не должны оставаться незамеченными.
Если явно не замалчивается.
Перед лицом двусмысленности откажитесь от искушения угадать.
Должен быть один — и желательно только один — очевидный способ сделать это.
Хотя этот способ может поначалу это может быть не очевидно, если только вы не голландец.
Лучше сейчас, чем никогда.
Хотя никогда лучше, чем *прямо* сейчас.
Если реализацию трудно объяснить, это плохая идея.
Если реализацию легко объяснить, это может быть хорошей идеей.
Пространства имен — это отличная идея — давайте сделаем больше таких!

Масштабируемость

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

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

Почему это важно?

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

Как построить для него

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

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

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

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

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

Последние мысли

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

Надеемся, что это введение даст вам лучшее представление о том, что это такое и почему они важны.

Использованная литература:

[1] Мартин Клеппманн, Проектирование приложений, интенсивно использующих данные: основные идеи, стоящие за надежными, масштабируемыми и ремонтопригодными системами (2017 г.), O’Reilly