...
...
...

что замедляет работу Apache и как получить максимум от PHP?

Приложения, использующие архитектуру LAMP (Linux, Apache, MySQL, PHP/Perl), постоянно совершенствуются и все шире используются. Но системный администратор часто не имеет полного контроля за самими приложениями, поскольку они написаны кем-то другим. Эта статья сфокусирована на действиях, которые вы можете выполнить для оптимизации Apache и PHP.

настройка Apache

Apache - часть программного обеспечения, легко поддающаяся настройке. Он имеет множество функций, и каждая является ценной. Настройка Apache отчасти состоит в надлежащем распределении ресурсов и подразумевает отключение ненужных настроек.

конфигурирование мультипроцессорных модулей





Приложение Apache является модульным, в том смысле, что вы легко можете добавлять и удалять его элементы. Эту модульную функциональность в ядре Apache - управление сетевыми соединениями и отправку запросов - обеспечивают мультипроцессорные модули (Multi-Processing Modules, MPM). Модули позволяют вам использовать потоки или даже перемещать Apache в другую операционную систему.

Одновременно может быть активен только один мультипроцессорный модуль и он должен быть скомпилирован статически при помощи --with-
mpm=(worker|prefork|event).

Традиционная модель "один процесс на запрос" назвается prefork. Более новая, модель с потоками (thread), называемая worker, использует несколько процессов, каждый с несколькими потоками, для получения более высокой производительности при более низких накладных расходах. Наконец, event - экспериментальный модуль, который содержит особые группы потоков для различных задач. Чтобы определить, какой мультипроцессорный модуль вы сейчас используете, выполните

# httpd -l

Выбор мультипроцессорного модуля зависит от многих факторов. Отключение модуля event до тех пор, пока он имеет экспериментальный статус, -- это выбор между потоками и их отсутствием. Внешне кажется, что использовать потоки лучше, чем использовать fork, если все основные модули являются безопасными потоками, включая все используемые PHP-библиотеки. Prefork - более безопасный выбор; если вы выбрали worker, вы должны провести тщательное тестирование. Рост производительности также зависит от входящих в дистрибутив библиотек и вашего оборудования.

Независимо от того, какой мультипроцессорный модуль вы выбрали, вы должны соответствующим образом сконфигурировать его. Вообще, конфигурирование модуля подразумевает определение, как Apache контролирует количество запущенных worker'ов, являются ли они потоками или процессами. Ниже показаны важные опции конфигурирования модуля prefork.

StartServers 50
MinSpareServers 15
MaxSpareServers 30
MaxClients 225
MaxRequestsPerChild 4000


В модуле prefork новый процесс создан при помощи запроса. Резервные процессы простаивают, чтобы общаться с поступающими запросами, что уменьшает время ожидания запуска. Предыдущая конфигурация запускает 50 процессов, как только стартует веб-сервер, и старается поддерживать в наличии от 10 до 20 простаивающих запущенных серверов. Жесткий лимит процессов определяется при помощи MaxClients. Даже если процесс может общаться с множеством последовательных запросов, Apache убивает процессы после 4000 соединений, что уменьшает риск утечки памяти.

Конфигурирование мультипроцессорных модулей с поддержкой потоков производится подобным образом, за исключением того, что вы должны определить, сколько потоков и процессов должно использоваться. Документация Apache дает разъяснения по всем параметрам и необходимым расчетам.

Выбор используемых значений подразумевает некий метод проб и ошибок. Наиболее важное значение - MaxClients. Цель состоит в том, чтобы разрешить достаточное количество процессов worker или потоков, чтобы сервер не занимался исключительно свопингом. Если поступает больше запросов, чем может быть обработано, то по крайней мере те, которые поступили, обрабатываются; другие блокируются.

Если MaxClients слишком высок, все клиенты получают недостаточно высокий уровень сервиса, поскольку веб-сервер пробует выгрузить один процесс, чтобы позволить выполняться другому. Установка слишком низкого значения приводит к тому, что вы можете необоснованно отказать в обслуживании. Проверка количества процессов, запущенных в момент повышенной нагрузки, и анализ объема памяти, используемой всеми процессами Apache, дает вам хорошую идею относительно установки этого значения. Если вы устанавливаете значение MaxClients выше 256, вы должны установить то же значение для ServerLimit; внимательно прочтите документацию по мультипроцессорным модулям, чтобы узнать о соответствующих предостережениях.

Настройка числа запускаемых серверов и наличие запасных зависит от роли сервера. Если на сервере выполняется только Apache, вы можете поставить невысокое значение, поскольку вы можете использовать машину в полной мере. Если система используется еще и базой данных или другим сервером, вы должны ограничить число запасных запущенных серверов.

эффективное применение опций и переопределений

Каждый запрос, который обрабатывает Apache, проходит через сложный набор правил, которые диктуют любые ограничения или специальные инструкции, которым должен следовать веб-сервер. Доступ к папке может быть ограничен IP-адресом для определенной папки, или могут быть сконфигурированы имя пользователя и пароль. Эти опции также включают обработку определенных файлов, например, если предоставляется листинг каталога, они определяют, как будут обрабатываться определенные типы файлов, или должен ли быть сжат вывод.

Эти конфигурации имеют вид контейнеров в httpd.conf, например, <Directory> определяет, что конфигурация обращается к местоположению на диске, или <Location> задает отсылку на путь, указанный в URL. В качестве примера покажем контейнер Directory, применяемый к каталогу root

<Directory />
AllowOverride None
Options FollowSymLinks
</Directory>


Эта конфигурация, ограниченная тегами <Directory> и </Directory>, применяется к данному каталогу и его содержимому - в этом случае к каталогу root. Здесь тег AllowOverride определяет, что пользователям не разрешается отменять любые опции (более подробно об этом позже). Опция FollowSymLinks разрешена, что позволяет Apache видеть прошлые символьные линки для обслуживания запроса, даже если файл не входит в каталог, содержащий веб-файлы. Это означает, что если файл в вашем веб-каталоге является символьным линком на /etc/passwd, веб-сервер успешно обслужит файл, если поступит запрос. Использование -FollowSymLinks отключит эту возможность, и тот же самый запрос будет причиной возврата ошибки клиенту.

Последний сценарий - повод для беспокойства на двух фронтах. Первый - вопрос производительности. Если FollowSymLinks отключен, Apache должен проверять каждый компонент имени файла (каталоги и собственно файл), чтобы убедиться, что они не являются символьными линками. Это влечет дополнительные накладные расходы в форме нагрузки на диск. Сопутствующая опция FollowSymLinksIfOwnerMatch следует за символьным линком, если владелец файла тот же, что и владелец линка. Это оказывает такое же воздействие на производительность, как и отключение следования символьным линкам. Для наилучшей производительности используйте опции, приведенные выше.

Читатели, которых волнуют вопросы безопасности, уже должны быть обеспокоены. Безопасность - всегда компромисс между функциональностью и риском. В этом случае функциональность - это скорость, и риск предполагает неавторизованный доступ к файлам системы. Смягчающим фактором является то, что серверы приложений LAMP обычно предназначены для определенной функции, и пользователи не могут создавать потенциально опасные символьные линки. Если жизненно необходимо разрешить проверку символьной ссылки, вы можете разрешить это только в определенной области файловой системы:

<Directory />
Options FollowSymLinks
</Directory>

<Directory /home/*/public_html>
Options -FollowSymLinks
</Directory>


Теперь любой каталог public_html в домашнем каталоге пользователя имеет опцию FollowSymLinks, отключенную для этого и всех вложенных каталогов. Как вы видели, опции могут конфигурироваться на покаталожной основе через конфигурацию главного сервера. Пользователи могут самостоятельно отменить конфигурацию сервера (если администратором разрешено AllowOverride) через файл .htaccess. Этот файл содержит дополнительные директивы сервера, которые загружаются и применяются к каждому запросу каталога, в котором содержится файл .htaccess.

Несмотря на то, что директива AllowOverride препятствует пользователям в совершении тех действий, которые вы хотите им запретить, Apache по- прежнему должен искать файл .htaccess, чтобы выяснить, нужно ли что-нибудь сделать. Родительский каталог может определить директивы, которые должны быть обработаны запросом дочернего каталога, что означает, что Apache должен также исследовать каждый компонент дерева каталогов, ведущий к запрашиваемому файлу. По понятным причинам это является причиной высокой дисковой активности по каждому запросу.

Самое простое решение - не позволять любые переопределения, которые отменяют необходимость проверки Apache файла .htaccess. Любые специальные конфигурации затем помещаются непосредственно в httpd.conf. Ниже показано, что нужно добавить в httpd.conf, чтобы позволить проверку пароля для пользовательского каталога project, вместо того чтобы помещать информацию в файл .htaccess и надеяться на AllowOverride.

<Directory /home/user/public_html/project/>
AuthUserFile /home/user/.htpasswd
AuthName "uber secret project"
AuthType basic
Require valid-user
</Directory>


Если конфигурация помещена в httpd.conf и AllowOverride отключен, интенсивность использования диска может уменьшиться. Каталог пользователя project может не привлечь большого количества обращений, но учитывайте мощь этого метода применительно к сайту, работающему с большой нагрузкой. Иногда невозможно исключить использование файлов .htaccess. в следующем примере выбор ограничен определенной частью файловой системы; возможность отмены также может быть ограничена.

<Directory />
AllowOverrides None
</Directory>

<Directory /home/*/public_html>
AllowOverrides AuthConfig
</Directory>


Теперь Apache все же ищет файлы .htaccess в родительском каталоге, но прекращает поиск в каталоге public_html. Например, если запрашивается файл /home/user/public_html/project/notes.html, то его успешное отображение произойдет только в том случае, если каталоги public_html и project будут найдены.

Уместно сделать одно последнее замечание относительно относящихся к отдельным каталогам конфигураций. Любой документ о настройке Apache дает указание запретить DNS lookup через директиву HostnameLookups off, поскольку попытки обратно разрешить соединения всех IP-адресов с вашим сервером - излишняя трата ресурсов. Однако любые ограничения, базирующиеся на имени хоста, вынуждают веб-север выполнять обратный lookup на IP- адресе клиента и прямой lookup на основании результата проверки подлинности имени. Поэтому благоразумно избегать использования средств контроля доступа, базирующихся на имени хоста, и, когда они необходимы, проверять их, как описано.

постоянные соединения

Когда клиент соединяется с веб-сервером, разрешается порождение множественных запросов по одному и тому же TCP-соединению, что уменьшает время ожидания, связанное с многократными соединениями. Это полезно, когда веб-страница содержит несколько изображений: клиент может запросить страницу и затем все изображения в течение одного соединения. Обратная сторона состоит в том, что процесс worker на сервере должен ожидать закрытия сеанса клиентом, прежде чем он сможет перейти к следующему запросу.

Apache позволяет вам определять, как будут обработаны постоянные соединения, называемые keepalives. KeepAlive 5 на глобальном уровне httpd.conf позволяет серверу обработать 5 запросов на соединение, прежде чем соединение будет насильственно прервано. Установка этого числа в 0 запретит использование постоянных соединений. KeepAliveTimeout, тоже на глобальном уровне, определяет, как долго Apache будет ожидать другого запроса, прежде чем сессия закроется.

Обработка постоянных соединений не является конфигурацией типа "один-размер-годится всем". Некоторые веб-сайты функционируют лучше, если keepalives запрещены (KeepAlive 0), а в некоторых случаях их включение может принести огромную пользу. Единственное решение - попробовать оба варианта и выяснить все самостоятельно. Тем не менее, разумно использовать низкий таймаут, например, 2 секунды, при помощи KeepAliveTimeout 2, если вы разрешили keepalives. Это даст гарантии, что любой клиент, желающий сделать другой запрос, будет иметь достаточное количество времени, и что процессы worker не останутся без работы, пока будут ждать другого запроса, который может никогда не поступить.

сжатие

Веб-сервер может сжимать вывод, прежде чем возвратить его клиенту. В результате уменьшается объем страницы, посылаемой по Интернету, но все это - за счет циклов CPU на веб-сервере. Для тех серверов, которые могут позволить себе высокую нагрузку на CPU, это отличный способ создания быстро загружаемых страниц — размер страницы может после сжатия уменьшиться втрое.

Изображения обычно уже сжаты, поэтому необходимо сжимать только текстовый вывод. Apache предусматривает сжатие при помощи mod_deflate. Несмотря на то, что mod_deflate может быть просто отключен, он содержит множество сложных моментов, которые описаны в соответствующей документации.

настройка PHP

PHP - движок, который запускает код приложений. Вы должны установить только модули, которые планируете использовать, и сконфигурировать ваш веб- сервер для использования PHP только для файлов скриптов (обычно те файлы, названия которых заканчиваются на .php) а не всех статических файлов.

кеширование кода операции

Когда запрашивается скрипт, PHP читает его и собирает в то, что называется код операции Zend, бинарное представление кода, который будет выполнен. Этот код операции затем выполняется движком PHP и теряется. Кэш кода операции сохраняет его и в следующий раз при запросе страницы вновь использует. Это экономит немало времени. Доступно несколько реализаций кэша кода операции доступны; я успешно использовал eAccelerator. Инсталляция eAccelerator требует наличия в компьютере библиотек разработки PHP. Поскольку разные дистрибутивы Linux помещают файлы в разные места, получите инструкции по инсталляции непосредственно с веб-сайта eAccelerator'а. Также возможно, что ваш дистрибутив уже содержит нужный софт, и вы должны просто установить соответствующий пакет.

Независимо от того, каким образом вы установили на своей системе eAccelerator, есть несколько вариантов конфигурации. Конфигурационным файлом обычно бывает /etc/php.d/eaccelerator.ini. Директива eaccelerator.shm_size определяет размер кэша совместно используемой памяти, где хранятся скомпилированные скрипты. Значение измеряется в мегабайтах. Определение подходящего размера зависит от приложения. eAccelerator предоставляет скрипт для показа статуса кэша, который включает использование памяти; 64 мегабайта - хорошее значение для начала:

eaccelerator.shm_size="64"

Вы также можете настроить максимальный размер для shared memory, если выбранное вами значение не было принято. Добавьте

kernel.shmmax=67108864

в /etc/sysctl.conf и запустите sysctl -p, чтобы настройки вступили в силу. Значение kernel.shmmax измеряется в байтах.

Если превышен объем выделяемой shared memory, eAccelerator должен удалить из памяти старые скрипты. По умолчанию это отключено. Директива

eaccelerator.shm_ttl = "60"

устанавливает, что когда eAccelerator исчерпывает размер shared memory, любой скрипт, доступ к которому не был получен в течение 60 секунд, должен быть удален.

Другая популярная альтернатива eAccelerator -- Alternative PHP Cache (APC). Создатели Zend также имеют коммерческий кэш кода операции, включающий оптимизатор для дальнейшего повышения эффективности.

php.ini

Вы конфигурируете PHP в php.ini. Четыре важных параметра настройки определяют, какое количество системных ресурсов может потреблять PHP, как показано в таблице 1.

Таблица 1. Параметры настройки php.ini, связанные с ресурсами.


ПараметрОписаниеРекомендуемое значение
max_execution_timeСколько CPU-секунд может потреблять скрипт30
max_input_timeКак долго (в секундах) скрипт может ждать входных данных60
memory_limitКакое количество памяти (в байтах) может расходовать скрипт, прежде чем он будет убит32M
output_bufferingКакое количество данных (в байтах) накапливается в буфере, прежде чем они будут отправлены клиенту4096


Размер этих значений обычно зависит от приложения. Если вы принимаете от пользователей большие файлы, max_input_time может быть увеличен или в php.ini, или путем его переопределения в коде. Подобным образом, для программ, потребляющих большое количество CPU или памяти могут потребоваться более высокие значения. Цель состоит в том, чтобы уменьшить воздействие "прожорливой" программы, поэтому глобальная отмена этих настроек не рекомендуется. Другое замечание относительно max_execution_time: это относится ко времени, затраченному CPU на процесс, а не к абсолютному времени. Таким образом, программа, совершающая большое количество вводов/выводов и небольшое количество вычислений, может выполняться намного дольше, чем max_execution_time. max_input_time также может быть больше, чем max_execution_time.

Количество записей лога, которые может сделать PHP, может настраиваться. В продакшне экономят место на диске, отменяя все журналы, кроме самых критических. Если журналы необходимы для диагностики проблем, вы можете вернуть то журналирование, которое необходимо. Директива

error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR

включает журналирование, достаточное для выявления проблем, но удаляет из скриптов лишнюю информацию.

заключение

Эта статья сфокусирована на настройке веб-сервера, как Apache, так и PHP. С Apache главная идея состоит в том, чтобы исключить лишние проверки, которые должен делать веб-сервер, например, обработку файла .htaccess. Вы также должны настроить мультипроцесорный модуль (MPM), который позволит сбалансировать используемые системные ресурсы и простаивающие worker'ы для входящих запросов. Лучшее, что вы можете сделать для PHP - установить кэш кода операции. Наблюдение за несколькими параметрами настройки ресурсов также гарантирует, что скрипты не завладеют ресурсами и не замедлят работу системы.



Шон Волберг, старший сетевой инженер, P.Eng




© Сетевые решения