Введение
По данным Netcraft, Apache — самый популярный веб-сервер в интернет, он
обслуживает множество серверов и сайтов. Часто возникает необходимость
увеличить производительность веб-сервера. Наверное лучший способ это
сделать — перейти к схеме frontend+backend, но это может потребовать
достаточно серьезных изменений в приложении (например, у вас наверняка
отвалятся всяческие индикаторы прогресса аплоада файлов).
Другой способ — просто увеличить производительность сервера — поставить
более быстрый процессор и больше памяти.
Однако и первое и второе требует много времени и ресурсов, так что на
первое время можно попробовать ускорить apache путем оптимизации его
конфигурации. Существуют оптимизации, которые можно применить только
при пересборке apache, другие же можно применять без перекомпиляции
сервера.
Загружайте только необходимые модули
Apache — модульная программа, бОльшая часть функций которой реализуется
в модулях. При этом эти модули могут быть как вкомпилированы, так и
собраны в виде DSO — динамических библиотеках. Большинство современных
дистрибутивов поставляет apache с набором DSO, так что не нужные модули
можно легко отключить без перекомпиляции.
Запускайте apache только с необходимыми модулями, чтобы уменьшить
потребление памяти. Если вы решили скомпилировать apache
самостоятельно, то либо тщательно подходите к выбору списка модулей,
которые вы включите, либо компилируйте их как DSO используя apxs в
apache1 и apxs2 в apache2. Для того чтобы отключить ненужные
DSO-модули, достаточно закомментировать лишние строчки LoadModule в
httpd.conf. Apache со статически скомпилированными модулями будет
потреблять чуть меньше памяти, однако вам придется каждый раз его
перекомпилировать для изменения списка модулей.
Выберете подходящий MPM
В apache каждый запрос обрабатывается в своем процессе или потоке. При
компиляции apache позволяет выбирать один из нескольким MPM
(Multi-processing module), которые отвечают за прослушивание портов,
прием запросов и раздачу этих запросов дочерним процессам или потокам,
в которых эти запросы будут обработаны.
Выбор MPM зависит от нескольких факторов, таких как наличие поддержки
потоков в ОС, количества свободной памяти, а также требований
стабильности и безопасности.
Если безопасность очень важна, следует выбрать peruser MPM, пожертвовав
производительностью.
Если важна именно производительность, то выбор ограничивается двумя
mpm: prefork и worker.
Worker — поточный MPM, т.е. в нем каждый запрос обслуживается в
отдельном потоке одного из дочерних процессов. Потоки — более легкие
для ОС объекты, чем процессы, они более эффективно используют память и
переключения контекста для них происходят быстрее. Однако, из-за того
что каждый поток имеет доступ ко всей памяти процесса, worker mpm более
подвержен сбоям: сбой одного потока может повлечь падение всего
процесса, в котором находился этот поток (именно поэтому worker mpm
запускает несколько дочерних процессов с несколькими потоками в
каждом).
Perfork — mpm использует несколько дочерних процессов, каждый дочерний
процесс обрабатывает одно подключение. Из-за того что процесс — более
тяжелая структура, он использует немного больше ресурсов, зато он менее
подвержен сбоям — обработка каждого отдельного запроса не зависит от
других процессов.
К сожалению, для смены mpm требуется перекомпиляция apache. Тут
проявляют свои достоинства source-based дистрибутивы: вы можете легко
перекомпилировать apache и все зависимые от него пакеты, не превратив
систему в свалку. Бинарные дистрибутивы выходят из этой ситуации
по-разному. Например в RHEL в apache rpm находится сразу две версии
apache — с worker и prefork mpm (prefork используется по умолчанию).
Однако worker mpm не поддерживает php. Так что если вы хотите php и
worker mpm вам придется компилировать его самостоятельно либо искать
сторонние репозитории.
DNS lookup
Директива HostnameLookups включает reverse DNS запросы, так что в логи
будут попадать dns-хосты клиентов вместо ip-адресов. Разумеется, что
это существенно замедляет обработку запроса, т.к. запрос не
обрабатывается пока не будет получит ответ от DNS-сервера. Поэтому
следите чтобы эта директива всегда была выключена (HostnameLookups
Off), а если вам все-таки нужны dns-адреса, вы можете узнать их позже,
прогнав лог в утилите logresolve (которая поставляется с apache).
Кроме того, следите чтобы в директивах Allow from и Deny From
использовались ip-адреса а не доменные имена. Иначе apache будет делать
два dns запроса (обратный и прямой) чтобы убедиться что клиент-тот за
кого себя выдает.
AllowOverride
Если директива AllowOverride не установлена в ‘None’, apache будет
пытаться открыть .htaccess файлы в каждой директории которую он
посещает и во всех директориях выше нее. Например:
DocumentRoot /var/www/html
<Directory /var/www/html/>
AllowOverride all
</Directory>
Если будет запрошен /index.html, apache попытается открыть (и
интерпретировать) файлы /.htaccess, /var/.htaccess, /var/www/.htaccess,
и /var/www/html/.htaccess. Это увеличивает время обработки запроса. Так
что, если вам нужен .htaccess только для одной директории, разрешайте
его только для нее:
DocumentRoot /var/www/html
<Directory />
AllowOverride None
</Directory>
<Directory /var/www/html/>
AllowOverride all
</Directory>
FollowSymLinks и SymLinksIfOwnerMatch
Если для директории включена опция FollowSymLinks, сервер будет
следовать по символическим ссылкам в этой директории. Если для
директории включена опция SymLinksIfOwnerMatch, apache будет следовать
по символическим ссылкам только если владелец файла или директории, на
которую указывает эта ссылка совпадает с владельцем указанной
директории. Так что при включенной опции SymLinksIfOwnerMatch apache
делает больше системных запросов.
Кроме того, дополнительные системные запросы требуются когда
FollowSymlinks НЕ УСТАНОВЛЕН. Т.о. наиболее оптимальная ситуация для
производительности — когда опция FollowSymlinks включена.
Content Negotiatio
Старайтесь избегать content negotiaion.
MaxClients
Директива MaxClients устанавливает максимальное количество параллельных
запросов, которые будет поддерживать сервер. Apache не будет порождать
больше процессов/потоков чем MaxClients. Значение MaxClient не долно
быть слишком маленьким (иначе много клиентов останутся необслуженными),
но и не стоит устанавливать слишком большое количество — лучше не
обслужить часть клиентов чем исчерпать все ресурсы, залезть в своп и
умереть под нагрузкой. Хорошим может быть значение MaxClients =
количество памяти выделенное под веб-сервер / максимальный размер
порожденного процесса или потока. Для статических файлов apache
использует около 2-3 Мб на процесс, для динамики (php, cgi) — зависит
от скрипта, но обычно около 16-32 Мб.
Вы можете прикинуть примерный размер посмотрев на колонку rss в выводе
`ps -ylC httpd —sort:rss`
Если сервер уже обслуживает MaxClients запросов, новые запросы попадут
в очередь, размер которой устанавливается с помощью директивы
ListenBacklog.
MinSpareServers, MaxSpareServers, и StartServers
Т.к. создание потока, и особенно процесса — дорогая операция, apache
создает их заранее. Директивы MaxSpareServers и MinSpareServers
устанавливают как много процессов/потоков должны ожидать в готовности
принять запрос (максимум и минимум). Если значение MinSpareServers
слишком маленькое и неожиданно приходит много запросов, apache вынужден
будет создавать много новых процессов/потоков, что создаст
дополнительную нагрузку в этой стрессовой ситуации. С другой стороны,
если MaxSpareServers слишком велико, apache будет сильно нагружать
систему этими процессами, даже если количество клиентов минимально.
Постарайтесь установить такие MinSpareServers и MaxSpareServers, чтобы
apache не создавал более 4 процессов/потоков в секунду. Если он создаст
более 4, в ErrorLog будет помещено сообщение об этом. Это — сигнал того
что MinSpareServers слишком мало.
MaxRequestsPerChild
Директива MaxRequestsPerChild устанавливает сколько запросов может
обработать один дочерний процесс/поток прежде чем он будет завершен. По
умолчанию значение этой директивы установлено в 0, что означает что
однажды созданный процесс/поток не будет завершен никогда (ну кроме
случаев остановки сервера или краха этого процесса/потока). Рекомендую
установить MaxRequestsPerChild равное какому-нибудь достаточно большому
числу (несколько тысяч). Это не создаст излишней нагрузки, связаной с
тем что apache будет вынужден создавать новые дочерние процессы, в то
же время это поможет избавиться от проблем с утечкой памяти в дочерних
процессах (что очень возможно например если вы используете нестабильную
версию php).
KeepAlive и KeepAliveTimeout
KeepAlive позволяет делать несколько запросов в одном TCP-подключении.
Это особенно полезно для html-страниц с большим количеством
изображений. Если KeepAlive установлен в Off, то для самой страницы и
для каждого изображения будет создано отдельное подключение (которое
нужно будет обработать master-процессу), что плохо и для сервера и для
клиента. Так что для подобных случаев рекомендуется устанавливать
KeepAlive в On. Для других применений (например для download-сервера)
KeepAlive может быть бесполезен и даже вреден, т.к. при включенном
KeepAlive сервер закрывает соединение не сразу, а ждет KeepAliveTimeout
секунд нового запроса. Для того чтобы процессы не висели слишком долго
в бесполезном ожидании, устанавливайте KeepAliveTimeout достаточно
малым, около 5-10 секунд обычно достаточно.
Сжатие
HTTP-сжатие было определено в стандарте HTTP/1.1, и сейчас все
современные клиентские программы и практически все сервера его
поддерживают. Сервер может отдавать ответ в gzip или deflate, а
клиентская программа незаметно для пользователя разжимает данные. Это
уменьшает количество передаваемого трафика (до 75%), но конечно же
повышает использование процессора.
Однако если ваш сервер посещает много клиентов с медленным подключение,
сжатие может снизить нагрузку с вашего сервера из-за того что сервер
сможет быстрее передать сжатый ответ и освободить ресурсы, занятые
дочерним процессом. Особенно сильно этот эффект может быть заметен если
у вас быстрый процессор, но мало памяти.
Кеширование конфигурируется директивами модуля mod_deflate. Имейте в
виду, что не следует устанавливать степень сжатия gzip более 4-5 — это
потребует существенно большего времени CPU, а эффект будет достаточно
невелик. Ну и разумеется не нужно пытаться сжать изображения в jpg, gif
и png, музыку, видео файлы и все другие бинарные файлы, которые уже и
так хорошо сжаты.
Кеширование на стороне клиента
Не забывайте устанавливать Expires заголовки на статические файлы (см.
модуль mod_expires). Если файл не изменяется, то его всегда следует
попробовать закешировать на клиенте. Тогда у клиента будут быстрее
загружаться страницы, а сервер освободится от лишних запросов.
Оригинал: «Configuring Apache for Maximum Performance».
Vishnu Ram V: https://linuxgazette.net/123/vishnu.html
Оригинал: https://greenmice.info/ru/node/98
Просмотров: 1346