Перейти к содержимому

Основные критерии систем

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

Основные критерии систем: как оценивать и проектировать качественную архитектуру

Когда мы говорим о качестве информационной системы, дело не только в том, “работает ли она”. Можно написать идеально работающий код, который через год станет невозможным поддерживать. Можно построить сверхнадёжный сервис, который разорит компанию стоимостью инфраструктуры. Можно сделать систему с 100% доступностью, но каждая операция будет длиться 5 секунд, и пользователи уйдут к конкурентам.

Критерии качества (Quality Attributes) — это характеристики, по которым оценивается система, помимо её способности выполнять функции. Знание этих критериев позволяет аналитику задавать правильные вопросы на этапе проектирования, выбирать между архитектурными альтернативами и предсказывать проблемы роста.

Надёжность и доступность (Reliability & Availability)

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

Доступность (Availability)

Доступность — это доля времени, в течение которого система находится в работоспособном состоянии и может обрабатывать запросы. Измеряется в процентах (“три девятки” — 99.9%).

Формула:
Availability = uptime / (uptime + downtime) × 100%

Самые частые виновники простоя:

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

Как влияет на архитектуру:

  • Устранение единой точки отказа (SPOF) — минимум два экземпляра каждого компонента.
  • Балансировщики нагрузки.
  • Автоматический failover (переключение на резерв).
  • Graceful degradation — при падении некритичного модуля система продолжает работать с урезанной функциональностью.
  • Мониторинг и алертинг — чтобы узнать о недоступности до пользователей.

Цена доступности:

  • 99.9% (три девятки) — допустим ~8,76 часа простоя в год. Реализуется за умеренные деньги: один дополнительный сервер, реплика БД.
  • 99.99% (четыре девятки) — ~52 минуты простоя в год. Требует автоматического failover, дублирования сетевых путей, избыточных блоков питания.
  • 99.999% (пять девяток) — ~5 минут простоя в год. Это уровень телеком-оборудования и платёжных систем. Стоит очень дорого, требует географически распределённой архитектуры.

Для аналитика ключевой вопрос: “Сколько денег компания теряет за час простоя?” Если 1000 рублей, четыре девятки не нужны. Если 1 млн рублей — инвестиции в 99.99% оправданы.

Надёжность (Reliability)

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

  • Неправильный ответ (ошибка в вычислениях, возврат не тех данных).
  • Потеря данных (заказ сохранился?).
  • Очень медленный ответ (если превышен порог, то тоже отказ).

Надёжность тесно связана с понятием “fault tolerance” — устойчивостью к сбоям. Система может быть доступна (процесс отвечает на ping), но ненадёжна (каждый второй ответ содержит ошибку).

Как отличается от доступности:

  • Сервер перегружен и выдаёт timeout. Доступность = 0% (он не отвечает). Надёжность тоже = 0%.
  • Сервер отвечает 200 OK, но в теле ответа поле userId всегда null. Доступность = 100%, надёжность = 0%.

Метрики надёжности:

  • Failure rate (частота отказов).
  • MTBF (Mean Time Between Failures) — среднее время между отказами.
  • MTTR (Mean Time To Recover) — среднее время восстановления.

Архитектурные приёмы повышения надёжности:

  • Ретрансляция идемпотентных запросов (retry).
  • Проверки целостности данных (CRC, хеши).
  • Изоляция компонентов (чтобы ошибка в модуле А не убила модуль Б) — будь то микросервисы, контейнеры или надёжные барьеры.
  • Автоматическое восстановление из бэкапов и чекпойнтов.

Вывод для аналитика:

  • Доступность отвечает на вопрос: “Система отвечает?”
  • Надёжность отвечает на вопрос: “Ответ корректный и данные не потерялись?”

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

Масштабируемость — это способность системы увеличивать производительность пропорционально добавленным ресурсам.

Виды масштабирования

Вертикальное масштабирование (scale up): увеличиваем мощность одного сервера (больше CPU, памяти, дисков). Просто, почти не меняя код. Но есть физический потолок и стоимость растёт нелинейно.

Горизонтальное масштабирование (scale out): добавляем новые серверы. Позволяет расти почти бесконечно, но требует изменения архитектуры (stateless, шардирование БД).

Линейность масштабирования

В идеале удвоение серверов даёт удвоение производительности. В реальности:

  • Закон Амдала: если треть кода последовательная (не распараллеливается), то ускорение принципиально ограничено (не более чем в 3 раза, даже при 1000 ядрах).
  • Накладные расходы на синхронизацию, сеть, очереди — с ростом числа серверов ускорение замедляется, а потом и вовсе падает.

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

  • Stateless компоненты (веб-серверы, API Gateway). Масштабируются горизонтально легко: копии за балансировщиком.
  • Stateful компоненты (базы данных, очереди). Тяжело. Требуют шардирования, репликации или перепроектирования.

Важное различие: масштабируемость чтения и масштабируемость записи.

Показатели масштабируемости

  • Горизонтальная: как растёт производительность с числом узлов.
  • Вертикальная: как растёт производительность с добавлением CPU/RAM на одном узле.

Для аналитика важно понимать, какие компоненты системы станут узким местом при росте нагрузки. Например:

  • База данных с ACID-транзакциями плохо масштабируется горизонтально. Возможно, потребуется шардирование или переход на NoSQL (с потерей строгой консистентности).
  • Монолит тяжело масштабировать — вся копия целиком, даже если перегружен только один модуль.

Производительность (Performance)

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

Две основные метрики

Latency (задержка) — время между отправкой запроса и получением ответа. Измеряется в миллисекундах или секундах. Если задержка слишком велика, пользователи уходят.

Throughput (пропускная способность) — количество операций в единицу времени (запросов в секунду, RPS; транзакций в секунду, TPS). Показывает, какую нагрузку система способна переварить.

Почему Latency и Throughput конфликтуют

Увеличение throughput часто ведёт к росту latency, и наоборот.

  • Добавили потоков → вырос throughput. Но если потоков слишком много, они начинают конкурировать за CPU, и каждый отдельный запрос выполняется дольше.
  • Включили батчинг → вырос throughput. Но первый запрос в пачке ждёт, пока наберётся пачка (дополнительная задержка).

Как улучшить производительность

Кэширование. Результат часто выполняемого запроса хранится в быстром хранилище (Redis, CDN, in-memory cache). Резко улучшает latency, но несёт риск несвежих данных.

Асинхронность. Долгую операцию (отправка email, генерация отчёта) можно отправить в очередь, а пользователю сразу вернуть “принято в обработку”.

Уменьшение блокировок. Чем меньше синхронизации между потоками, тем выше производительность. Иногда допускается eventual consistency.

Параллелизм. Независимые запросы обрабатываются в разных потоках (если только это не упирается в батарейку на телефоне).

Для аналитика важно сформулировать требования к производительности количественно: вместо “быстрый ответ” нужно писать “p95 latency GET /orders/ должно быть меньше 200 мс в час пик, при нагрузке 1000 RPS”. Иначе команда разработки и тестирования не поймут, когда задача выполнена.

Удобство сопровождения (Maintainability)

Удобство сопровождения — это то, как легко систему изменять: добавлять фичи, исправлять баги, откатывать изменения, разворачивать на новом окружении.

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

Стоимость поддержки в 3–10 раз выше стоимости разработки. За 5 лет жизни системы основные затраты приходятся не на первое написание кода, а на его изменение.

Признаки хорошей сопровождаемости

  • Низкая связанность (loose coupling): изменение в одном модуле не требует изменений в десятке других.
  • Высокая связность внутри модуля (high cohesion): модуль отвечает за одну чёткую задачу.
  • Чистая архитектура (бизнес-логика не зависит от фреймворков и деталей хранения).
  • Хорошие тесты (unit, интеграционные, E2E).
  • Инфраструктура как код (Infrastructure as Code) — окружения разворачиваются из репозитория, а не руками.
  • Документация: для чего компонент, как им пользоваться, какие у него зависимости.

Измеримые метки сопровождаемости

  • Время от коммита до деплоя.
  • Среднее время разрешения инцидента.
  • Количество багов на 1000 строк кода.
  • Время онбординга нового разработчика (сколько надо дней, чтобы сделать полезный коммит).

Архитектурные выборы и компромиссы

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

Для аналитика сопровождаемость важна потому, что её последствия видны на длинной дистанции. Если сейчас выбрать “самый быстрый путь”, через год добавление кнопки займёт две недели.

Безопасность (Security)

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

Основные аспекты

Конфиденциальность (Confidentiality). Данные доступны только тем, кому разрешено.

Целостность (Integrity). Данные не могут быть изменены без разрешения.

Доступность (Availability). Авторизованные пользователи имеют доступ к системе (здесь важна и доступность через DDoS).

Архитектурные меры безопасности

  • Аутентификация (кто?) и авторизация (что можно?) — на уровне API Gateway или централизованного сервиса.
  • Шифрование данных в транзите (TLS) и в покое (encryption at rest).
  • Токенизация чувствительных данных (например, номера карт вместо хранения в открытом виде).
  • Аудит действий (кто и когда заходил, что менял).
  • Защита от DDoS — rate limiting, WAF (Web Application Firewall).
  • Регулярное обновление зависимостей (чтобы закрыть известные уязвимости).

Безопасность как компромисс

Безопасность почти всегда конфликтует с удобством (чем больше паролей, тем неудобнее), с производительностью (шифрование требует ресурсов) и стоимостью (наём security-инженеров, покупка сертификатов, сканеров уязвимостей).

Сравнительная таблица критериев

КритерийВопрос, на который отвечаетКак измеряетсяКомпромиссы
ДоступностьСистема отвечает?% времени без простояСтоимость резервирования, сложность отказоустойчивости
НадёжностьОтвет корректный?Частота ошибок, MTBFДороже, нужно контролировать качество данных
МасштабируемостьМожет расти?Ускорение от добавления ресурсовСложность архитектуры (шардирование, репликация)
ПроизводительностьКак быстро и сколько?Latency (мс), Throughput (RPS)Часто конфликтует со стоимостью и надёжностью
СопровождаемостьЛегко ли изменять?Время от идеи до релизаЧистая архитектура требует больше работы сейчас
БезопасностьДоступ только своим?Количество уязвимостей, время их устраненияКонфликтует с удобством и производительностью

Резюме для системного аналитика

При проектировании или анализе системы вы должны:

  • Собирать требования по каждому критерию. Не только “система должна быть быстрой”, а “p95 latency GET /orders не более 100 мс при 1000 RPS”.
  • Понимать компромиссы. Высокая доступность требует резервирования. Высокая безопасность замедляет отклик.
  • Приоритезировать. Для банка безопасность важнее скорости. Для поискового сервиса скорость важнее безопасности.
  • Прогнозировать точки роста. Куда система упрётся через год? В CPU? В сеть? В сложность кода?

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