Следуя уже сложившейся в последнее время в этом блоге традиции, я постараюсь построить заметку в виде небольшого эксперимента, в ходе которого мы с вами будем наблюдать за происходящим. Итак, поехали.
В качестве PHP-сценария для проведения тестов использовался небольшой скрипт, выбирающий все строки из таблицы БД MySQL и выводящий результаты при помощи var_dump ():
$oPDO = new PDO("mysql:server=localhost;dbname=test;", 'user', 'password'); $oQRes = $oPDO->query("SELECT * FROM test1"); var_dump($oQRes->fetchAll());
Структура таблицы test1 БД следующая:
+-------+---------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | text | YES | | NULL | | +-------+---------+------+-----+---------+----------------+
Таблица содержит 10000 записей, где в каждом поле name записан MD5-хеш случайного числа в диапазоне от 0 до time (). URL сценария, работающего под Apache — http://test.ashep:80/test.php. Давайте посмотрим при помощи siege как сервер будет обрабатывать запросы к этому сценарию.
Эмулируем 10 серий по 10 одновременных запросов:
$ siege -c 10 -r 10 http://test.ashep:80/test.php Transactions: 100 hits Availability: 100.00 % Elapsed time: 109.66 secs Data transferred: 32.65 MB Response time: 10.30 secs Transaction rate: 0.91 trans/sec Throughput: 0.30 MB/sec Concurrency: 9.39 Successful transactions: 100 Failed transactions: 0 Longest transaction: 12.76 Shortest transaction: 3.66
Сервер успешно обработал все запросы, однако время на обработку каждого составило в среднем 10,3 секунд.
Теперь создадим реверс-прокси сервер в Nginx так, как мы это делали в предыдущей статье, в качестве upstream-сервера будем использовать наш Apache по http://test.ashep:80.
server { listen 8080; server_name test.ashep; access_log /var/log/nginx/test.access_log; error_log /var/log/nginx/test.error_log; location / { proxy_pass http://test.ashep:80; } }
Повторим тест, на этот раз уже через Nginx:
$ siege -c 10 -r 10 http://test.ashep:8080/test.php Transactions: 100 hits Availability: 100.00 % Elapsed time: 104.97 secs Data transferred: 32.65 MB Response time: 9.77 secs Transaction rate: 0.95 trans/sec Throughput: 0.31 MB/sec Concurrency: 9.31 Successful transactions: 100 Failed transactions: 0 Longest transaction: 14.54 Shortest transaction: 2.89
Результаты примерно те же. Логично, поскольку Nginx всего лишь транслирует запросы к upstream-серверу, ничего при этом не кэшируя.
И теперь самое интересное. Прежде, чем можно будет оперировать кэшированием в настройках серверов Nginx, сперва нужно определить место для хранения и параметры кэша Nginx. Кэшей в Nginx можно определить больше одного, каждый с нужными вам параметрами и затем использовать их в зависимости от ситуации в том или ином месте конфигурации сервера.
Определять кэш можно лишь в контексте секции http, которая, например, в моём Debian описана в /etc/nginx/nginx.conf. Для определения кэша используется опция proxy_cache_path, которая имеет следующий формат:
proxy_cache_path path [levels=number] keys_zone=zone_name:zone_size [inactive=time] [max_size=size];
В квадратных скобках приведены необязательные параметры. Теперь обо всём по порядку:
В ходе моих экспериментов, рассматриваемых в этой заметке, я использовал следующее значение опции proxy_cache:
proxy_cache_path /var/cache/nginx levels=2:2 keys_zone=default:100m;
Приведённой выше строкой создаётся двухуровневый кэш в каталоге /var/cache/nginx с именем 'default' и размером 100 мегабайт. Теперь определённый кэш default можно использовать в конфигурации серверов Nginx. Слегка дополненная конфигурация сервера, приводившаяся выше:
server { listen 8080; server_name test.ashep; access_log /var/log/nginx/test.access_log; error_log /var/log/nginx/test.error_log; location / { proxy_pass http://test.ashep:80; proxy_cache default; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; } }
Обратите внимание на две новых опции. При помощи параметра proxy_cache мы указываем Nginx какой кэш необходимо использовать при кэшировании данных от upstream-сервера, в данном случае — это 'default', определённый ранее в /etc/nginx/nginx.conf. Опция proxy_cache_valid определяет время в течение которого не устаревшими будут считаться объекты кэша, полученные полученные в результате ответов upstream-сервера. Формат опции следующий:
proxy_cache_valid код_ответа [код_ответа код_ответа ...] время
Таким образом ответы upstream-сервера с кодами 200 и 302 будут кэшироваться на 10 минут, а ошибки 404 — в течение одной минуты.
Сохранив конфиг-файлы и перезапустив Nginx, попробуем провести нагрузочное тестирование с включённым кэшированием:
$ siege -c 10 -r 10 http://test.ashep:8080/test.php Transactions: 100 hits Availability: 100.00 % Elapsed time: 15.68 secs Data transferred: 32.65 MB Response time: 0.73 secs Transaction rate: 6.38 trans/sec Throughput: 2.08 MB/sec Concurrency: 4.65 Successful transactions: 100 Failed transactions: 0 Longest transaction: 9.51 Shortest transaction: 0.02
Среднее время ответа от сервера составило 0,73 секунды. Неплохо, правда? ;)
Источник статьи