Apache Bench нюансы

Решил протестировать свой PHP сайт с помощью Apache Bench (ab), а именно авторизацию.

Некоторые параметры утилиты AB

-A auth-username:password - передать данные для базовой аутентификации. То есть, фактически можно тестировать даже если доступ закрыт с помощью базовой аутентификации (htpasswd).

-c concurrency - количество параллельных запросов в единицу времени. По умолчанию, один реквест в единицу времени (можно считать, что в секунду).

 cookie-name=value - добавлять куки. Задается в виде пары имя=значение. Это поле можно повторять.

-f protocol - задает SSL/TLS протокол (SSL2, SSL3, TLS1, or ALL).

-h - отобразить краткую справку по параметрам

-k - включить KeepAlive, то есть осуществлять множество запросов в течение одной HTTP-сессии. По умолчанию данная возможность отключена.

-n requests - количество запросов, которое необходимо выполнить в течение сессии тестирования. По умолчанию, выполняется только один запрос, что не дает общей картины.

-q - подавляет вывод некоторых сообщений о процессе тестирования.

-t timelimit - максимальное количество секунд, которое необходимо затратить на тестирование. Это подразумевает значание параметра -n равное 50000. По умолчанию временной лимит не установлен.

-v verbosity - устанавливает уровень "разговорчивости": 4 и выше отображает информацию о заголовках, 3 и выше - информацию о кодах ответа (404, 200 и т. д.), 2 и выше - выводить предупреждения и прочую информацию.

-V - отобразить версию и выйти.

-w - вывести результаты в виде HTML-таблицы. По умолчанию таблица состоит из двух колонок с белым фоном.

-x <table>-attributes - строка для использования в качестве атрибутов для <table>. Атрибуты вставляются <table СЮДА >.

-y <tr>-attributes - строка атрибутов для <tr>.

-z <td>-attributes - строка атрибутов для <td>.

-X proxy[:port] - использовать прокси-сервер для запросов.

С полным набором параметров можно ознакомиться выполнив команду man ab в командной строке.

Первый запрос всегда не параллелен

Например следующий запрос отправляет 1 запрос, ожидает его ответ и только потом отправляет сразу 3 запроса (итого 4):

ab -p post-data.txt -T application/json -c 4 -n 4 'http://localhost/api/page'

Это подтверждают логи nginx - позволяющие отслеживать параллельность запросов с помощью log_format в nginx.

А проверять удобно например php-скриптом:

<?php
sleep(10); echo 1; exit;

Все ответы должны быть идентичны

Для этого я должен POST-запросом послать логин и пароль, в моем случае нужно отправить еще и значение кнопки, по которой кликает пользователь:

$LoginFormUr = array( 'username' => 'root', 'password' => 'zzz');

$loginButtonValue = 'Вход';

Поэтому, я создаю файл post-data.txt с следующим содержимым:

LoginFormUr%5Busername%5D=root&LoginFormUr%5Bpassword%5D=zzz&loginButtonValue=%D0%92%D1%85%D0%BE%D0%B4

И наконец отправляю запрос:

ab -p post-data.txt -T application/json -H 'Authorization: abcd1234' -c 2 -n 2 'https://site.ru/index.php?r=login/corporate'

в результате Apache Bench сообщил, что все хорошо, но есть ошибки:

...
Failed requests: 499
    (Connect: 0, Length: 499, Exceptions: 0)
...

В данном случае ошибка про длину ответа, ab предполагает, что все ответы одинаковы. Он просматривает длину содержимого первого ответа и затем сравнивает другие с этим.

На странице man:

Document Length
This is the size in bytes of the first successfully returned document.
If the document length changes during testing, the response is
considered an error.

Итак, если ваш первый запрос содержит следующие данные:

{"serverip":"1.2.3.4"}

А следующий:

{"serverip":"1.2.3.45"}

ab завершится с ошибкой Length, так как вывод будет на один символ длиннее.

HTTP/1.0

При выполнении запроса (например POST), к адресу добавляется максимальная версия HTTP-протокола, которую поддерживает клиент (в нашем случае ab), например:

POST /gateway/applications/add-service/add HTTP/1.0

Таким образом сервер знает, что некоторые заголовки посылать клиенту нет смысла или если не поддерживает устаревшую версию HTTP-протокола, то может вернуть ответ:

426 Upgrade Required

Именно так поступает, например Istio, таким образом запрос даже не доходит до приложения и обрывается на уровне веб-сервера, который стоит перед приложением.

О том, что ab поддерживает только HTTP/1.0 написано на официальной странице (внизу)

Напомню, что следующие заголовки были добавлены только в 1.1: Accept, Accept-Charset, Accept-Encoding, Accept-Language


03.05.2018 08:13