Нагрузочное тестирование web-сервера при помощи ab






Пока ваш веб-сервер работает стабильно и стабильно отдаёт посетителям запрошенный контент — всё в порядке. Но задавали ли вы себе вопрос: а что будет, если нагрузка на сервер возрастёт? Что, если количество запросов на единицу времени увеличится вдвое? Втрое? В десять раз? Как узнать ответ на это злободневное «а что если?». В сегодняшней заметке мы рассмотрим основы нагрузочного тестирования веб-серверов при помощи утилиты ab — Apache HTTP server benchmarking tool, инструмента, который позволит вам определить максимально возможное количество одновременных запросов, которые сможет обработать ваша инсталляция веб-сервера.


Приготовления

Утилита ab поставляется в комплекте с Apache, так что если он у вас установлен — у вас есть уже всё необходимое. В сегодняшней заметке мы будем упражняться на установленном в конфигурации по умолчанию Apache 2.2.14 в Ubuntu Server 10.04.2 LTS. Конфигурацию оборудования (кому интересно — оно довольно слабенькое) и настроек Apache приводить не буду, ибо нет смысла в рамках данной статьи. Целью данной заметки является небольшой обзор утилиты ab, а не анализ производительности конкретного ПО на конкретном железе. В рамках примера произведём тест отдачи сервером:

  • HTML-файла test.html размером 177 байт;
  • небольшого PHP-сценария test.php, код которого приведён ниже.

Все файлы размещены в корне DocumentRoot сервера. Код PHP-сценария использовался такой:

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

Запрос html-файла

Итак, начнём. Для начала давайте организуем нагрузку нашему серверу в одну тысячу последовательных запросов. Для указания числа запросов используется опция '-n'. Номер порта можно не указывать, если он не отличен от 80-го:

Итак, что у нас получилось (вывод привожу не полностью, опуская несущественные пока моменты). В процессе тестирования утилита будет сообщать вам о ходе работы:

Далее вы увидите информацию о версии ПО сервера, его имени, какой документ загружался и каков его размер:

И далее, собственно, результаты:

Как видно:

  • Concurrency Level: количество одновременно-отправляемых запросов — 1;
  • Time taken for tests: тысяча запросов к серверу заняла 1,5 секунды;
  • Complete requests: успешно получен ответ на всю тысячу запросов;
  • Failed requests: неудавшихся запросов — ноль;
  • Write errors: ошибок записи — ноль;
  • Total transferred: общий объём переданных данных: 453000 байт;
  • HTML transferred: из них «полезного» HTML — 177000 байт;
  • Requests per second: среднее количество запросов в секунду составило 666.58
  • Time per request: среднее время на один запрос 1,5 миллисекунды
  • Transfer rate: скорость обмена данными с сервером составила 294.88 килобайта в секунду.

Далее в выводе идёт информация о времени, затраченном на сетевые подключения:

И на обслуживание запросов сервером:

Как видим, сервер успешно справился с тысячей последовательных загрузок статического файла небольшого размера. Давайте теперь посмотрим, как сервер поведёт себя, если вся эта тысяча запросов будет направлена к нему одновременно, указав это при помощи опции '-c':

Здесь тест не смог быть завершён по причине того, что после одновременной отправки 804 запросов сервер перестал принимать входящие соединения. Опытным путём, снижая количество одновременных запросов, было установлено что безболезненно мой Apache в текущей конфигурации может обрабатывать  примерно 300 одновременных не Keep-Alive запросов.

Естественно, с Keep-Alive запросами дело будет обстоять ещё хуже, поскольку занимаемые Apache'м ресурсы сервера освобождаются не так быстро. Для выполнения теста с Keep-Alive-соединениями просто добавьте опцию '-k':

Запрос PHP-сценария

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

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

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




Нагрузочное тестирование web-сервера при помощи ab: 9 комментариев

  1. Ну и наворотил ты.

    $ ab -n 1000 -c 300 aserver.ashep:80/test.html

    Percentage of the requests served within a certain time (ms)

    50% 648

    66% 654

    75% 668

    80% 785

    90% 7003

    95% 7243

    98% 7384

    99% 7425

    100% 13650 (longest request)

    10% запросов обрабатывались 7 секунд, что не очень-то и хорошо. Увеличивая число подключений можно получить худшее время, правильная настройка кэширования nginx дала бы одинаковое время для 99% запросов.

    $ ab -n 1000 -c 300 aserver.ashep:80/test.php

    Percentage of the requests served within a certain time (ms)

    50% 2470

    66% 2983

    75% 4412

    80% 5575

    90% 14254

    95% 32750

    98% 33302

    99% 33589

    100% 44106 (longest request)

    Большинство пользователей получило страницу за 2,5 — 3 секунды, 10% за 5 секунд, и 10% за 30 секунд. Совсем не ахти, у тебя, видимо, совсем нет кэширования результатов работы php скриптов.

    Вот мой тест, 200 одновременных подключений:

    $ siege -c 200 -b www.ashep.org/2011/nagruz...nie-web-servera/

    Transactions: 235 hits

    Availability: 24.18 %

    Elapsed time: 88.99 secs

    Data transferred: 2.25 MB

    Response time: 36.95 secs

    Transaction rate: 2.64 trans/sec

    Throughput: 0.03 MB/sec

    Concurrency: 97.59

    Successful transactions: 235

    Failed transactions: 737

    Longest transaction: 40.35

    Shortest transaction: 0.57

    Страница отдавалась от половины секунды до 40 секунд, прошло только 24% запросов, остальное время сервер был слишком обработкой других запросов — страницу получил лишь каждый четвертый пользователь.

    Кстати, вот результаты моего тестового сервера, почти не настроенного — сейчас делаю новый, настраивая его уже как надо: pastebin.com/Xq6Vx7p5

    99% запросов были обработаны в 1.3 секунды, скорость обработки — 81 запрос в секунду.

    Нынешний сервер — голый апач, так что с ним так играть не надо.

  2. Dmitry Paskal, спасибо, очень познавательно. Хорошее дополнение к статье. Только ты, видимо, пропустил тот момент, что эта статья не о производительности моего тестового сервера, собранного из 800-го целерона, а об основах работы с ab для начинающих. Но всё равно — благодарю за твой вклад ;)

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

  3. С падением Amazon EBS я решил новый сервер настроить получше, а у тебя в то же время вышли статьи про nginx и нагрузочное тестирование:)

    Пишу статью на хабр, когда допишу — приглашу поиграться с производительностью.

    Спасибо за интересные статьи:) Я редко когда добавляю в rss технические блоги.

    1. Aleksdem, к сожалению, пока не готов рассказать, поскольку не «щупал» его сам. Может быть попозже. В любом случае, спасибо за идею ;) И не говорите ни о какой «наглости». Пишу я в конце-концов для читателей, а не для себя. Поэтому рад любым мыслям и предложениям.

  4. Срипт возвращает 404 ошибку, Failed requests: 0. Скрипт возвращает, 500 ошибку. Failed requests: 0. Что ж ему вернуть та надо )

Комментарии запрещены.