Скорее всего вы уже имеете базовые знания о принципах работы и возможностях http сервера Apache, однако все равно начнем с небольшого экскурса в теорию. Большинство администраторов, которые работают с Apache, знают о двух моделях, с помощью которых Apache сервер отвечает на запросы — это prefork и mpm-worker.
Типы мультипроцессовых модулей.
Мультипроцессовых модулей (Multi-Processing Module) много (если судить по википедии), относительной популярностью пользуются три:
- prefork — классический MPM, реализующий модель мульти-процессинга. Каждый поток обрабатывается в отдельном процессе. Другими словами — «отдельный процесс для запроса». При такой схеме каждый процесс апача использует уникальные от других процессов буферами, процессорные мощности и память. Apache поддерживает «простой» процесса, как результат из-за большого количества ожидающих запросов, может наступить нехватка ресурсов. Не самый производительный вариант, но наиболее стабильный. Используется по умолчанию.
- worker — MPM, основанный на потоках. Сервер порождает несколько процессов, по несколько потоков в каждом. Один запрос — один поток. Производительнее prefork, но менее стабилен.
- event — событийный MPM. Вместо потоков запросы обрабатываются, используя событийную модель, похожую на ту, что применяется в nginx. Наиболее производительный MPM, но и наименее стабильный (находится в экспериментальной стадии разработки).
Для понимания процесса, необходимо знать о типах «воркеров».
Основных типов два — это процесс и поток, для улучшения производительности иногда используют оба типа одновременно, порождая несколько процессов и кучу потоков в каждом:
- Процесс: Различные worker’ы могут быть процессами. В этом случае они не взаимодействуют между собой, и данные различных worker’а полностью независимы друг от друга.
- Поток: Потоки, в отличие от процессов, имеют общие, разделяемые структуры данных. В коде worker’а должна быть реализована синхронизация доступа, чтобы одновременная запись одной и той же структуры не привела к хаосу.
Как определить MPM с которым работает Ваш веб сервер?
Заходим на сервер по SSH:
apachectl -t -D DUMP_MODULES | grep mpm mpm_prefork_module (static) Syntax OK # httpd -V | grep MPM Server MPM: Prefork -D APACHE_MPM_DIR="server/mpm/prefork"
Переходим с prefork на worker на Apache.
В /etc/sysconfig/httpd снимаем комментарий со строчки и перегружаем демона:
HTTPD=/usr/sbin/httpd.worker
В конфигурации apache настраиваем режим работы модуля:
StartServers 1 MaxClients 50 MinSpareThreads 15 MaxSpareThreads 35 ThreadsPerChild 25 MaxRequestsPerChild 2000
- StartServers – количество процессов запускаемых при старте
- MinSpareThreads/MaxSpareThreads – количество свободных потоков. Свободные потоки – это сумма потоков во всех процессах
- MaxClients – максимально количество одновременных клиентов, то есть максимальное количество потоков во всех процессах
- ThreadsPerChild – количество потоков создаваемое каждым процессом, то есть если мы разделить MaxClients на ThreadsPerChild, то получим число процессов которое будет создано при максимальной загрузке.
- ServerLimit – количество максимальных процессов. Число должно быть не меньше MaxClients/ThreadsPerChild – числа процессов при максимальной нагрузке.
- MaxRequestsPerChild – через сколько запросов уничтожается процесс.
Скорость обработки запросов.
ab -c 1 -n 10 http://example.com/index.html
Опция -c задает количество одновременных соединений, -n общее количество запросов.
В итоге получим среднюю суммарная скорость запроса в миллисекундах.
При с=1 — поведение характерно для единичного (случайного) посещения сайта, т.е. низкой нагрузки. Для дальнейшего тестирования увеличиваем количество моделируемых одновременных пользователей до ста.
Из статистики видим, имеем не такую уж большую разницу, для всех серверов. Расхождение в пределах 10% друг от друга.
Во втором тесте измерили время, требуемое серверу, для обработки большого количества запросов.
Запрашивали порядка 400 файлов с 1000 одновременно открытых соединений, т.е. порядка 400 000 статических страниц.
siege -b -c 1000 -r 403 —file=urls.txt
По статистике получили схожую картину.
Однако по процессору и памяти результаты разнились намного сильнее.
Для Nginx и Lighttpd загрузка процессора составила 40-50%, в то же время для остальных демонов загрузка процессора была порядка 70-90%.
Самое большое потребление памяти было во время работы Apache PreFork — 328 Мб оперативной памяти, самое низкое было для Apache worker — 237 Мб оперативной памяти.