Требование к API сформулировано как «система должна быстро отвечать». Что в нём нужно изменить, чтобы его можно было принять по измеримому критерию?
Нужно заменить слово «быстро» на измеримое нефункциональное требование: указать операцию, профиль нагрузки, допустимую задержку, процент запросов, условия измерения и последствия превышения. Например: «При 500 одновременно работающих клиентах 95-й перцентиль времени ответа операции поиска не превышает 300 мс, а 99-й — 800 мс».
Такое требование можно проверить нагрузочным тестом или наблюдением в рабочей среде. Одного среднего времени ответа недостаточно: оно скрывает медленные запросы и не показывает, при какой нагрузке получен результат.
Нефункциональные свойства систем — производительность, доступность, безопасность и восстанавливаемость — долго описывались оценочными словами: «быстро», «надёжно», «удобно». Такие формулировки возникли потому, что заинтересованным сторонам проще назвать желаемое качество, чем заранее определить способ его измерения.
По мере усложнения систем и появления распределённых интеграций субъективных оценок стало недостаточно. Измеримые критерии появились как практический способ связать ожидание бизнеса с архитектурным решением, тестированием и условиями приёмки.
Фраза «система должна быстро отвечать» не определяет, что именно измерять. Непонятно, для какой операции, при каком объёме данных, количестве пользователей, размере запроса и состоянии зависимых сервисов предъявляется требование.
Если оставить формулировку без уточнений, разработчик может измерить среднее время ответа на тестовом стенде, а заказчик — оценивать самый медленный запрос в рабочее время. Оба результата формально не противоречат требованию, но система всё равно может быть признана неудовлетворительной.
Неверно заданное требование приводит к спорной приёмке, неправильному выбору инфраструктуры и оптимизации не того сценария. Кроме того, команда не сможет понять, является ли проблема нарушением требования или просто изменением нагрузки.
Требование следует разложить на несколько частей:
Перцентиль показывает значение, ниже которого укладывается заданная доля наблюдений. Если 95-й перцентиль равен 300 мс, это означает, что 95% измеренных запросов завершились не дольше 300 мс, но не описывает оставшиеся 5%. Для пользовательских сценариев часто отдельно задают высокий перцентиль, чтобы контролировать редкие, но существенные задержки.
Важно не смешивать нефункциональное требование с решением. Формулировка «использовать определённый тип кэша» задаёт способ реализации, а не требуемый результат. Сначала фиксируют измеримый уровень качества, затем выбирают архитектуру и проверяют, что она его обеспечивает.
Критерий должен быть реалистичным и экономически обоснованным. Более жёсткая задержка может потребовать репликации, кэширования, увеличения ресурсов или отказа от некоторых функций, поэтому требования к производительности согласуют с ценностью сценария и стоимостью достижения результата.
Следует также разделять SLO как целевой уровень качества сервиса и критерий приёмки конкретной версии. SLO обычно контролируется длительно и допускает анализ тренда, тогда как приёмочный критерий проверяет, соответствует ли реализованная функция согласованному условию.
Для поиска заказов команда получила требование «результаты должны появляться быстро». Были рассмотрены три варианта.
Первый — задать среднее время ответа не более 200 мс. Плюс такого варианта — простота. Минус — среднее скрывает редкие задержки: небольшое число запросов может выполняться несколько секунд, не изменив показатель существенно.
Второй — потребовать фиксированные 200 мс для каждого запроса. Это легко трактовать, но критерий чрезмерно строг: единичные сетевые сбои или редкие большие запросы могут сделать его невыполнимым, хотя пользовательский опыт в целом приемлем.
Третий — описать профиль: поиск по последним двум годам данных, до 20 результатов, 300 запросов в секунду, 95-й перцентиль не более 400 мс и 99-й не более 1 секунды. Этот вариант сложнее согласовать, зато он отражает реальную нагрузку и явно учитывает хвост распределения.
Выбрали третий вариант. На тесте выяснилось, что средняя задержка соответствует ожиданиям, но 99-й перцентиль нарушен из-за запросов без ограниченного диапазона дат. Команда добавила обязательное ограничение периода и отдельную оптимизацию индекса. В результате критерий стал не только средством приёмки, но и способом обнаружить конкретную причину деградации.
Среднее значение зависит от всех наблюдений и может выглядеть хорошим при наличии небольшого числа очень медленных запросов. Для пользователя именно такие задержки часто заметны сильнее всего, особенно если запросы участвуют в последовательной цепочке действий.
Перцентили показывают хвост распределения и позволяют отдельно контролировать обычный и редкий сценарий. При этом сам выбор перцентиля не универсален: для массового пользовательского действия и для критичной операции могут потребоваться разные уровни контроля.
Одинаковая система может укладываться в 100 мс при десяти запросах в секунду и превышать несколько секунд при тысяче запросов. Без профиля невозможно воспроизвести проверку и понять, относится ли результат к реальной эксплуатации.
Профиль должен включать не только интенсивность, но и характер запросов: размеры ответов, долю разных операций, объём данных и параллельность. Иначе команда может оптимизировать искусственный тест, который не представляет рабочую нагрузку.
Да. Жёсткий порог может привести к дорогой архитектуре, чрезмерному запасу ресурсов или отказу от полезной функциональности ради редких случаев. Поэтому порог связывают с пользовательской ценностью, бизнес-последствиями задержки и стоимостью достижения.
Практичный подход — задать целевой уровень, допустимый максимум и условия пересмотра при изменении нагрузки. Также важно определить границы ответственности: задержка внешней системы, которую сервис не контролирует, должна учитываться отдельно, иначе исполнителю предъявят критерий, на который он не может влиять.