Повышение производительности Apache

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

По умолчанию Apache компилируют с mpm mod_prefork.c. Проверим с какими модулями он собран:

1
2
3
4
5
6
[root@localhost# httpd -l
Compiled in modules:
core.c
prefork.c
http_core.c
mod_so.c

Перед установкой apache рассмотрим два варианта которые влияют на производительность и посмотрим как это работает:

Worker VS Prefork

Worker

С этим MPM мы улучшаем нашу производительность за счет снижения потребления памяти. Apache запускается как одиночный процесс и запускает множество потоков серверного процесса. Мы можем ограничить количество потоков через директиву apache — ThreadsPerChild.

Преимущества:

  • Сервер может обслуживать больше клиентов с меньшими ресурсами.

Недостатки:

  • Крах одного процесса нарушит работу сразу ВСЕХ потоков принадлежащих процессу.
  • Не совместимо с установкой php в виде модуля (mod_php), потребуется установить fastcgi (запуск PHP как независимого процесса).
  • Требует больше конфигурирования.

Директивы влияющие на производительность модуля worker:

  • MinSpareThreads: Минимальное количество запасных потоков. В зависимости от значения Apache сохраняет минимальное количество ресурсов для обработки запроса, таким образом новым пользователям не придется ожидать ответа сервера пока он выделит им ресурсы.
  • MaxSpareThreads: Максимальное количество запасных потоков.
  • ThreadsPerChild: Постояное число потоков создаваемых дочерним процессом.
  • ThreadLimit: Максимальное число потоков сконфигурированных в ThreadsPerChild для всего процесса apache.

Основная настройка среднего вебсервера с 2-3 гигабайтами памяти:

1
2
3
4
5
6
7
8
<ifModule worker.c>
StartServers 4
MaxClients 320
MinSpareThreads 40
MaxSpareThreads 80
ThreadsPerChild 40
MaxRequestsPerChild 0
</ifModule>

Prefork

С модулем prefork существует основной процесс и на каждый запрос apache создает еще один подпроцесс. Родительский процесс стартует от имени root,  и каждый дочерний подпроцесс запускается от имени и группы согласно заданным директивам  apache.
Таким образом получается изоляция для каждого запущенного процесса, так что проблема одиночного процесса не будет вам сниться в ночных кошмарах ;)

Плюсы:

  • Не требуется специализированной настройки.
  • Совместимо с mod_php.
  • Изоляция проблемных запросов.
  • Совместимость с непоточными возможностями.

Минусы:

  • Большая нагрузка на процессор и память.
  • Хуже масштабируемость.

Директивы влияющие на производительность модуля prefork:

  • MinSpareServers: Минимальное число дочерних процессов находящихся в ожидании.
  • MaxSpareServers: Максимальное число дочерних процессов в ожидании.
  • MaxRequestPerChild: Устанаваливает предел запросов обрабатываемых дочерними процессами. После превышения лимита процесс умирает, что избавляет нас от утечек памяти.

Основная настройка среднего вебсервера с 2-3 гигабайтами памяти:

1
2
3
4
5
6
7
8
<ifModule prefork.c>
StartServers 4
MinSpareServers 25
MaxSpareServers 50
ServerLimit 270
MaxClients 270
MaxRequestsPerChild 10000
</ifModule>

Основная конфигурация Apache

  • MaxClients: максимальное количество запросов которое сервер будет обрабатывать одновремено. Все запросы превышающие это число будут поставлены в очередь на основе числа заданного в директиве ListenBacklog.
    Оптимальное число может быть разным в зависимости от того сколько памяти у вашего сервера, посчитать его можно так:[(Всего памяти — Память используемая другими процессами) / размер памяти каждого процесса apache или его потока]
    Для того чтобы узнать размер процесса :

    1
    # ps -ylC httpd --sort rss
  • ServerLimit: Для модуля prefork устанавливает максимальное значение для MaxClients на весь процесс apache. При использовании модуля worker используется в сочетании с директивой ThreadLimit. Минумум этого значения должен быть таким же как и MaxClients, иначе эта директива не будет иметь эффекта.
  • TimeOut: Время которое Apache ждет три вещи:
    1- Полное время получения запроса GET.
    2- Интервал времени между TCP пакета в POST или PUT запросах.
    3- Интервал времени между ACK для ответных пакетов TCP. По хорошему это значение должно быть в районе 30 секунд до закрытия подключения, большее значение может повлиять на большее число выделеных, но не используемых ресурсов.

    1
    TimeOut 30
  • KeepAlive: Обеспечивает несколько ответов на запросы через одно TCP подключение.
    1
    KeepAlive On
  • MaxKeepAliveRequests: количество запросов на одно подключение. Вы можете вычислить это значение по тому сколько запросов делает один посетитеть, число может оказаться огромным, но не выставляйте его слишком большим, одна атака может положить положить весь процесс в одной сессии.
    1
    MaxKeepAliveRequests 70
  • KeepAliveTimeout: Количество секунд в течении которых Apache ждет подзапрос до того как закроет подключение. Как только запрос будет получен значение таймаута изменится на то которое задано в директиве TimeOut.
    1
    KeepAliveTimeout 2
  • Отключение выполнения файла .htacess запрещает apache проверять существование файла .htaccess на каждом уровне переданного пути.
    1
    2
    3
    <directory />
    AllowOverride None
    </directory>
  • Включение символьных ссылок:
    1
    2
    3
    <directory />
    Options FollowSymLinks
    </directory>
  • Запрет апачу проверять кто является владельцем символьной ссылки.
    1
    2
    3
    <directory /document/path>
    Options +FollowSymLinks -SymLinksIfOwnerMatch
    </directory>

Если вы настроены решительно и хотите еще больше оттюнинговать ваш Apache то вам сюда: http://httpd.apache.org/docs/2.2/mod/#core

Автор: Mirivlad

Скромный труженик консоли и окошек.