Нагрузочное тестирование и стресс-тестирование: различия, метрики и примеры k6

  1. Главная
  2. Блог
  3. Тестирование программного обеспечения

Тестирование программного обеспечения

Нагрузочное тестирование и стресс-тестирование: Различия, метрики и примеры k6

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

9 мин чтения
Нагрузочное тестирование против стресс-тестирования: различия, метрики и примеры k6

Главное

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

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

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

Короткий ответ

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

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

Нагрузочное тестирование и стресс-тестирование бок о бок

Аспект Нагрузочное тестирование Стресс-тестирование
Главный вопрос Достигаем ли мы целевых показателей при ожидаемой нагрузке? Где и как мы ломаемся?
Уровень трафика От нормального до ожидаемого пика За пределами ожидаемого пика
Узор Набирайте темп, держитесь устойчиво Продолжайте увеличивать до отказа
Неудача Неудачный тест Ожидаемый результат
Ключевые показатели Время отклика, пропускная способность, ошибки Точка разрушения, режим отказа, время восстановления
Типичное время Перед каждым крупным релизом или событием После того, как система стабилизируется под нагрузкой
Результат Пройти или провалиться против целей Ограничение мощности и список слабых мест

Что такое нагрузочное тестирование?

Нагрузочное тестирование имитирует ожидаемый реалистичный трафик и измеряет поведение системы. Ему нужна цель для тестирования, например: «при 500 одновременных пользователях 95% запросов на оформление завершаются в течение 800 мс, с ошибками менее 1%.»

Вот как это может выглядеть в виде сценария k6. Тесты k6 написаны на JavaScript и thresholds превращают ваши цели в результат «пройден» или «не пройден»:

import http from "k6/http";
import { sleep } from "k6";

export const options = {
  stages: [
    { duration: "5m", target: 500 },   // ramp up
    { duration: "20m", target: 500 },  // hold at expected peak
    { duration: "2m", target: 0 },     // ramp down
  ],
  thresholds: {
    http_req_duration: ["p(95)<800"],
    http_req_failed: ["rate<0.01"],
  },
};

export default function () {
  http.get("https://staging.example.com/products");
  sleep(1);   // think time, as real users pause
}

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

Что такое стресс-тестирование?

Стресс-тестирование намеренно выходит за рамки ожидаемых уровней. Вы не пытаетесь пройти. Вам нужны ответы на такие вопросы, как:

  • На каком уровне производительность начинает падать?
  • Какой компонент выходит из строя первым: база данных, серверы приложений или сторонний вызов?
  • Происходит ли он корректно с явными ошибками или происходит сбой и потеря данных?
  • Восстанавливается ли он сам при падении трафика?
export const options = {
  stages: [
    { duration: "5m", target: 500 },    // expected peak
    { duration: "5m", target: 1000 },   // beyond it
    { duration: "5m", target: 2000 },   // further
    { duration: "5m", target: 4000 },   // likely to break
    { duration: "10m", target: 0 },     // recovery: does it come back?
  ],
};

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

Шип, замачивание и другие типы

Нагрузочные и стресс-тесты относятся к более широкому семейству тестов производительности:

Тип Узор Что он находит
Дым (спектакль) Несколько пользователей, кратко Работают ли вообще скрипт и система
Загрузить Ожидаемый пик, удержан Достигнуты ли цели
Стресс Рост прошлых мощностей Пределы и режимы отказа
Спайк Внезапный прыжок, затем падение Автомасштабирование и поведение очереди
Замачивание (выносливость) Нормальная нагрузка в течение нескольких часов Утечки памяти, кончающиеся соединения
Емкость Постепенное увеличение Максимальная нагрузка в пределах ваших целей

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

Метрики, которые имеют значение

Метрика Значение Следите за
Время ответа (процентили) Сколько времени занимают запросы p95 и p99 повышаются
Пропускная способность Запросов, обрабатываемых в секунду Сглаживание по мере увеличения числа пользователей
Частота ошибок Процент неудачных запросов Любой внезапный подъем
Процессор и память Использование ресурсов сервера Насыщение, или устойчивый рост
База данных Медленные запросы, использование пула соединений Бассейн исчерпан, замок ждет
Глубина очереди Работа ожидает обработки Рост, который никогда не истощается

Почему средние значения вводят в заблуждение

Средние значения скрывают медленные запросы, на которые жалуются реальные люди. Чтобы продемонстрировать это, мы сгенерировали 100 смоделированных времен отклика, из которых 95 были быстрыми (от 80 до 200 мс), а 5 — очень медленными (от 2,5 до 4 секунд), а затем рассчитали общую статистику:

import math, random, statistics

random.seed(3)
times = [random.randint(80, 200) for _ in range(95)] \
      + [random.randint(2500, 4000) for _ in range(5)]

def pct(values, p):
    values = sorted(values)
    return values[math.ceil(p / 100 * len(values)) - 1]

print("avg", round(statistics.mean(times)), "p50", pct(times, 50),
      "p95", pct(times, 95), "p99", pct(times, 99), "max", max(times))

# avg 302 p50 150 p95 199 p99 3740 max 3896

Посмотрите внимательно на эти цифры. Среднее значение 302 мс никого не характеризует. Типичные запросы занимали около 150 мс, а медленные — более 3 секунд. Даже p95 выглядит здоровым на 199 мс, и только p99 выявляет проблему. Такая цифра, как p95, означает, что 95% запросов были такими же быстрыми или быстрее.

И один процент запросов – явление не редкое. Если страница отправляет 50 запросов, медленный p99 влияет на большую долю просмотров страниц. Установите цели для важных для вас процентилей и рассмотрите несколько из них вместе.

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

Инструменты

Инструмент Сценарии Известный
к6 JavaScript Удобен для разработчиков, пороговые значения подходят для CI
JMeter Графический интерфейс и XML Зрелый, поддерживает множество протоколов
Гатлинг Scala, Java, Kotlin и другие. На основе кода, эффективный
Саранча Питон Простое поведение пользователя на основе Python

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

Как спланировать тест

  1. Установите цели. Используйте реальную аналитику, чтобы определить пиковый трафик и определить цели.
  2. Выбирайте путешествия. Моделируйте реалистичное поведение пользователей, например просмотр, поиск и оформление заказа, в реалистичных пропорциях. Посещение только домашней страницы мало что доказывает.
  3. Используйте реалистичную среду. Крошечный промежуточный сервер не может предсказать производительность. Обратите внимание на любые различия.
  4. Подготовьте данные. Используйте реалистичные объемы, поскольку запрос, который быстро обрабатывает 100 строк, может просканировать 10 миллионов.
  5. Предупредите людей. Сообщите об этом своей операционной команде и третьим лицам и не запускайте случайное нагрузочное тестирование платежной системы. Имитируйте внешние сервисы, где это возможно.
  6. Начните с малого. Сначала проведите небольшой дым-тест, чтобы убедиться, что ваш скрипт работает.
  7. Мониторьте все. Без показателей сервера вы увидите, что он замедлился, но не почему.
  8. Повторите. Запускайте его снова после каждого исправления и сохраняйте базовый уровень для сравнения.

Чтение результатов

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

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

Распространенные ошибки

  • Запутывает пользователей запросами. Уточните, означает ли цель количество одновременных пользователей или количество запросов в секунду.
  • Не хватает времени на размышления. Это увеличивает трафик и приводит к вводящим в заблуждение результатам.
  • Тестирование слишком позднее. Неделя до запуска не оставляет времени на исправление проблем с архитектурой.
  • Использование одной конечной точки. Реальный трафик смешивает операции чтения, записи и поиска.
  • Кэширование скрывает всё. Идентичные повторяющиеся запросы могут только проверить ваш кеш, поэтому меняйте данные.
  • Тестирование один раз. Производительность меняется с каждым выпуском, поэтому запускайте тесты регулярно.

Итоги

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

Часто задаваемые вопросы

В чем основная разница между нагрузочным и стресс-тестированием?

Нагрузочное тестирование проверяет поведение при ожидаемом трафике на соответствие установленным целям. Стресс-тестирование выходит за рамки возможности найти переломный момент и способ восстановления системы.

Должен ли я сначала запустить нагрузочное тестирование или стресс-тестирование?

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

В чем разница между стресс-тестом и спайк-тестом?

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

Что такое время отклика p95?

Это означает, что 95% запросов выполняются в это время или раньше. Он описывает опыт большинства пользователей лучше, чем в среднем.

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

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

Продолжайте учиться

Работайте с Stack Quora

Нужна помощь с тестированием, WordPress или SEO?

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

Продолжайте читать

Больше руководств по тестирование, искусственный интеллект и современные разработки

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

Искусственный интеллект

Объяснение галлюцинаций искусственного интеллекта: почему языковые модели все выдумывают и как их уменьшить

Галлюцинации ИИ объяснили: что это такое, почему языковые модели их создают, распространенные типы, как уменьшить их с помощью заземления и подсказо…

Читать статью →
DevOps

Объяснение переменных среды: файлы .env, секреты и правильно выполненная конфигурация

Переменные среды объясняются на примерах Python, которые мы запускали: их чтение и установка, почему каждое значение является строкой, файлы .env, н…

Читать статью →
Разработка ПО

Объяснение ограничения скорости API: алгоритмы, заголовки и обработка ошибок 429

Ограничение скорости API объясняется с помощью проведенного нами моделирования: сегмент токенов, фиксированное окно, скользящее окно, 429 ответов, з…

Читать статью →
Автоматизация тестирования

Издевательство в Python: unittest.mock, патч и ошибки, из-за которых тесты лгут

Издевательство на Python с помощью unittest.mock, протестировано: Mock и return_value, Side_effect, исправление использования имени, спецификация и …

Читать статью →
Тестирование ПО

Объяснение покрытия кода: покрытие линий или ветвей и что на самом деле означает 100%

Покрытие кода объяснено с помощью реального запуска покрытия.py: покрытие строк, ветвей и условий, чтение отчета, почему 100%-ное покрытие все еще м…

Читать статью →
Базы данных и SQL

DELETE, TRUNCATE и DROP в SQL: различия, откат и когда использовать каждый из них

Объяснение DELETE, TRUNCATE и DROP на примере протестированного SQL: что каждый из них удаляет, откат, триггеры, сброс идентификаторов, скорость и ч…

Читать статью →
Базы данных и SQL

Объяснение представлений SQL: создавайте, используйте и избегайте ловушек, с примерами

Представления SQL, объясненные с помощью запросов, которые мы выполняли: создание представления, результаты в реальном времени, скрытие столбцов, пр…

Читать статью →
Разработка ПО

Интерфейс TypeScript и тип: реальные различия, протестированные с помощью компилятора

Интерфейс TypeScript против типа, проверенный реальным компилятором: что могут делать оба, что может делать только один, слияние объявлений, расшире…

Читать статью →
Разработка ПО

Объяснение Python *args и **kwargs: гибкие функции с понятными примерами

Python *args и **kwargs, объясненные с помощью кода, который мы запускали: упаковка и распаковка, порядок параметров, аргументы только по ключевым с…

Читать статью →
Разработка ПО

Лямбда-функции Python: синтаксис, реальное использование и когда их не следует использовать

Лямбда-функции Python, объясненные с помощью кода, который мы запускали: синтаксис, сортировка с помощью ключа, карты и фильтра, замыкания, ловушка …

Читать статью →
Искусственный интеллект

Что такое ИИ-агенты? Как они работают: можно запустить простой цикл агента

Что такое агенты ИИ? Простое руководство по циклу агента, инструментам, памяти и ограничениям, с небольшим циклом Python, который мы запустили, реал…

Читать статью →
DevOps

Мониторинг и наблюдаемость: реальная разница с журналами, метриками и трассировками

Объяснение мониторинга и наблюдаемости: известные и неизвестные сбои, журналы, метрики и трассировки, пошаговое руководство по инцидентам при оформл…

Читать статью →
DevOps

Docker Volumes против Bind Mounts: правильное сохранение данных контейнера

Объяснение томов Docker и монтирования привязки: почему исчезают данные контейнера, именованные тома, монтирование привязки, tmpfs, примеры создания…

Читать статью →
Автоматизация тестирования

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

TDD и BDD объясняются с помощью одной функции скидки, созданной в обоих направлениях: красно-зеленый рефакторинг с кодом, который мы запускали, сцен…

Читать статью →
Тестирование ПО

Пользовательское приемочное тестирование (UAT): процесс, контрольный список и реальные примеры

Приемочное тестирование пользователей объяснило: кто его проводит, чем оно отличается от контроля качества, семиэтапный процесс, шаблон тестового сц…

Читать статью →
Базы данных и SQL

Объяснение значений NULL в SQL: IS NULL, COALESCE, NULLIF и ловушки, которых следует избегать

Значения SQL NULL объяснены с помощью запросов, которые мы выполнили: трехзначная логика, IS NULL, COALESCE, NULLIF, как агрегаты, соединения и сорт…

Читать статью →
Базы данных и SQL

Оператор SQL CASE WHEN: синтаксис, реальные примеры и распространенные ошибки

SQL CASE WHEN объяснен с помощью запросов, которые мы выполняли: простые формы и формы для поиска, порядок условий, повороты с помощью SUM, трюки CO…

Читать статью →
Разработка ПО

Что такое JWT? Веб-токены JSON, объясненные на рабочем примере

Что такое JWT? Объяснение JSON Web Tokens: три части: токен, созданный и измененный в коде, который мы запускали, JWT и сеансы, хранилище, токены об…

Читать статью →
Разработка ПО

Объяснение цикла событий JavaScript: стек вызовов, микрозадачи и таймеры с примерами

Цикл событий JavaScript объясняется с помощью кода, который мы запускали: стек вызовов, очереди задач и микрозадач, почему setTimeout 0 не является …

Читать статью →
Разработка ПО

Генераторы Python и объяснение доходности: экономьте память с помощью реальных примеров

Генераторы Python и доходность, объясненные с помощью кода, который мы запускали: как они приостанавливаются и возобновляются, измеряют экономию пам…

Читать статью →
Искусственный интеллект

Что такое вложения? Простое объяснение векторов и косинусного сходства

Что такое вложения? Простое руководство по векторам, косинусному подобию и семантическому поиску с небольшим примером, который мы использовали, общи…

Читать статью →
DevOps

Сине-зеленое и канареечное развертывание: различия, компромиссы и как выбрать

Объяснение сине-зеленого и канареечного развертывания: как каждый из них работает, стоимость, риски и откат, стабильное группирование пользователей,…

Читать статью →
Автоматизация тестирования

Ненадежные тесты: что их вызывает и как их исправить навсегда

Ненадежные тесты объясняются на демонстрациях, которые мы запускали: основные причины, способы подтверждения и диагностики, правильные исправления в…

Читать статью →
Тестирование ПО

Нагрузочное тестирование и стресс-тестирование: различия, метрики и примеры k6

Объяснение нагрузочного и стресс-тестирования: что доказывает каждое из них, тесты на всплески и выдержки, важные метрики, почему средние значения в…

Читать статью →
Тестирование ПО

Тестовый пример и тестовый сценарий: ключевые различия, примеры и когда использовать каждый

Объяснение тестового случая и тестового сценария: четкие определения, параллельная таблица, одна функция сброса пароля, взятая из сценариев в случаи…

Читать статью →
Базы данных и SQL

Оптимизация SQL-запросов: чтение планов выполнения и исправление медленных запросов с указанием времени

Оптимизация SQL-запросов проверена на миллионе строк: читайте планы выполнения, добавляйте правильные индексы, исправляйте неразмещаемые фильтры, ис…

Читать статью →
Базы данных и SQL

SQL UNION против UNION ALL: различия, примеры и проверка производительности

SQL UNION и UNION ALL объяснены с помощью запросов, которые мы выполнили: дубликаты, правила, которым следуют оба, реальная ошибка данных, измеренна…

Читать статью →
Разработка ПО

Учебное пособие по API JavaScript Fetch: GET, POST, обработка ошибок и тайм-ауты

Учебное пособие по API JavaScript Fetch, протестированное на локальном сервере: GET и POST, почему не выдается ошибка 404, многоразовый помощник, ст…

Читать статью →
Разработка ПО

Обработка файлов Python: чтение, запись, CSV, JSON и pathlib с примерами

Обработка файлов Python объясняется с помощью кода, который мы запускали: открытые режимы, чтение больших файлов, CSV, JSON, pathlib, двоичные файлы…

Читать статью →
Разработка ПО

Классы и объекты Python: учебник ООП с реальными примерами

Классы и объекты Python, объясненные с помощью кода, который мы запускали: __init__, методы, атрибуты класса и экземпляра, наследование, свойства, м…

Читать статью →
Искусственный интеллект

Что такое большая языковая модель? Как работают LLM, объяснено без шумихи

Что такое большая языковая модель? LLM объясняется простым языком: токены, встраивания, внимание, обучение, температурные и контекстные окна, крошеч…

Читать статью →
DevOps

Команды Linux для начинающих: основное руководство по терминалу с примерами

Команды Linux для начинающих, сгруппированные по задачам: навигация, файлы, просмотр журналов, grep, каналы, разрешения, процессы и архивы, с практи…

Читать статью →
Автоматизация тестирования

Selenium vs Playwright: ключевые различия, сравнение кода и что выбрать

Сравнение Selenium и Playwright: архитектура, ожидание, поддержка браузера и языка, отладка, одинаковый тест в обоих инструментах, советы по миграци…

Читать статью →
Тестирование ПО

Разделение эквивалентности: метод проектирования тестов, объясненный на рабочих примерах

Объяснение эквивалентного разделения: как найти действительные и недействительные разделы, рабочие примеры для возрастов, паролей и купонов, проведе…

Читать статью →
Тестирование ПО

Серьезность и приоритет в тестировании программного обеспечения: различия, матрица и реальные примеры

Объяснение серьезности и приоритета при тестировании программного обеспечения: четкие определения, четырехсторонняя матрица с примерами, шкалы уровн…

Читать статью →
Базы данных и SQL

Учебное пособие по подзапросам SQL: типы, коррелирующие подзапросы и EXISTS с примерами

Руководство по подзапросам SQL с выполненными нами запросами: скалярные подзапросы, IN, FROM и SELECT, коррелированные подзапросы, EXISTS, ловушка N…

Читать статью →
Базы данных и SQL

Объяснение транзакций SQL и ACID: COMMIT, ROLLBACK и уровни изоляции

Транзакции SQL и ACID, объясненные с помощью банковского перевода, который мы выполнили: COMMIT, ROLLBACK, точки сохранения, блокировки, уровни изол…

Читать статью →
Разработка ПО

Git merge vs rebase: отличия, примеры и когда что использовать

Git merge vs rebase с реальным выводом log, сравнительной таблицей, золотым правилом rebase и безопасным рабочим процессом для команды.

Читать статью →
Разработка ПО

Генераторы списков в Python: синтаксис, примеры и когда их избегать

Генераторы списков в Python: синтаксис, фильтры, if-else, вложенные циклы, измеренное время и случаи, когда обычный цикл for лучше.

Читать статью →
Базы данных и SQL

SQL JOIN: объяснение с примерами (Inner, Left, Right, Full)

Разберите SQL JOIN шаг за шагом на примерах таблиц и запросов: INNER, LEFT, RIGHT, FULL, CROSS и SELF, а также частые ошибки и советы по производите…

Читать статью →