5 шагов для ускорения работы Apache
Ускорить работу Apache можно на двух основных стадиях:
- Во время компиляции – настройки при установке сервера.
- Во время выполнения — установка параметров, влияющих на сервер во время его работы.
Настройки для ускорения Apache во время компиляции
Нужно выбирать вариант установки Apache, исходя из ваших требований. Это поможет создать быстрый и эффективный веб-сервер.
Загружайте только нужные модули
В Apache функциональность реализуется путем добавления модулей. Они бывают двух типов: статические и динамические (общие).
Чтобы посмотреть список модулей, поддерживаемых вашим сервером, используйте команду apachectl -M. Статические модули компилируются в бинарные файлы httpd, а динамические загружаются непосредственно во время выполнения.
Статические и динамические модулиключевые различия
Статические модули | Динамические модули |
Компилируются в бинарные файлы | Добавляются во время выполнения |
Требуют перекомпиляции кода | Перекомпиляция не требуется |
Быстро загружаются | Замедляют веб-сервер |
Чем больше статических модулей в бинарных файлах, тем быстрее работает веб-сервер. Но они требуют перекомпиляции Apache каждый раз, когда нужно что-то изменить. Из-за этого динамические модули или DSO используются чаще, поскольку они могут быть скомпилированы отдельно и загружены во время выполнения.
Но большое количество динамических или общих модулей может замедлить работу сервера Apache и сайта
Поэтому при выборе модулей требуется соблюдать осторожность
Чтобы увеличить скорость работы и производительность, используйте минимальное количество динамических модулей, поскольку они уменьшают объем доступной памяти.
Выберите правильный MPM
В Apache используются MPM (мульти-процессинговые модули), которые обрабатывают запросы, приходящие на сервер. Они прослушивают сетевые порты сервера, принимая запросы и создавая дочерние процессы.
MPM бывают двух типов: Prefork и Worker. В MPM Prefork каждый процесс httpd обрабатывает один сетевой запрос. Это более безопасно по сравнению с MPM Worker, но требует большего количества памяти и ресурсов.
MPM – Prefork и Worker
MPM Prefork | MPM Worker |
Один поток | Несколько потоков |
Использует больше ресурсов | Использует меньше памяти |
Отказоустойчив | Справляется с большим трафиком |
При использовании MPM Worker Apache работает в режиме многопоточного сервера, где каждый отвечает за свой запрос. Этот вариант подходит для обработки большего трафика при ограниченных мощностях сервера.
По умолчанию большинство установок Apache используют модуль Prefork. Он применяется для обработки больших объемов трафика. Вы можете проверить, какой модуль MPM использует ваш сервер при помощи следующей команды:
Определение типа MPM на вашем веб—сервере Apache
В Apache 2.4 появилась поддержка э MPM модуля Event, который может обрабатывать множественные запросы внутри одного потока. Поэтому он работает даже быстрее, чем модуль Worker.
3: Ограничьте количество процессов Apache
Многие операционные системы используют конфигурации по умолчанию, которые не очень подходят маленьким серверам – 25 дочерних процессов. Если каждый дочерний процесс Apache требует 120 Мб RAM, то сервер будет тратить 3 Гб только на Apache.
Веб-браузер одного пользователя может запрашивать 4 элемента сайта за раз, а значит всего 7-8 человек способны перенагрузить сервер. Веб-страницы зависают или грузятся очень медленно.
Сервер часто поддерживает такие мертвые процессы Apache в активном состоянии, пытаясь обслужить запрашиваемый контент, а это снижает количество доступных процессов для обслуживания пользователей и объем памяти. В результате вы получаете плохой пользовательский опыт.
Определите, сколько RAM требуется вашему приложению и сколько памяти остается, а затем выделите большую часть оставшейся памяти для Apache.
К примеру, у вас есть три процесса php-fpm для обработки динамического контента, где каждый процесс использует до 70 Мб памяти, а также сервер MySQL, который берет до 120 Мб RAM. В результате получается, что приложение использует 330 Мб памяти. Если у вас маленький сервер, вы можете выделить для Apache около 150 Мб памяти.
Когда веб-сервер Apache запущен, запустите команду top. Она выводит множество полезной информации. Ниже приведен фрагмент ее результата:
Найдите значение в столбце RES для Apache (например, 9 644) и запишите его. На данный момент веб-сервер использует почти 10 Мб памяти. Если ограничить количество дочерних процессов Apache до 15, 150 Мб выделенной памяти будет вполне достаточно.
Отредактируйте конфигурационный файл Apache (в Ubuntu и Debian это /etc/apache2/apache2.confand) и найдите раздел mpm_prefork_module. Найдите строку MaxClients и введите 15, а затем сохраните файл и перезапустите веб-сервер.
По умолчанию значение MaxClients может быть очень большим. Его нужно уменьшить.
Когда количество клиентов достигает предела, новые клиенты получат ошибку. Перезагрузив страницу, они смогут получить доступ к сайту.
Это звучит плохо, но все же лучше быстро закрыть эти соединения и сохранить нормальную работу сервера, чем ждать, пока сервер перестанет виснуть.
В некоторых ситуациях меньшее количество дочерних процессов помогает увеличить производительность сервера.
Ускорение работы Apache изменениями во время выполнения
Чтобы повысить производительность сервера, нужно регулярно измерять производительность и осуществлять тонкую настройку конфигурации. Наиболее важные параметры, которые нужно оптимизировать:
Поиск DNS
Apache может тратить время на определение хоста каждого IP, с которого приходит запрос. Это замедляет обработку запроса, а также приводит к пустой трате ресурсов. Чтобы избежать этого, нужно отключить опцию HostnameLookups.
При настройке директив Allow from или Deny from используйте IP-адреса вместо доменных имён. Иначе будет осуществляться двойной поиск имени DNS, который уменьшит производительность сервера.
Настройка AllowOverride
Если задана опция AllowOverride, то Apache попытается открыть файл .htaccess в каждой папке, которую он посещает. Эти дополнительные запросы к файловой системе увеличивают время отправки ответа с сервера.
Поэтому лучше отключить эту опцию. Если переопределение настроек в файлах .htaccess необходимо в определённой папке, нужно разрешить это только для данного каталога.
Настройки FollowSymLinks и SymLinksIfOwnerMatch
Настройка Apache FollowSymLinks сообщает серверу, что нужно проверять символические ссылки и проходить по ним. Если она имеет значение Off, Apache придётся выполнять дополнительные проверки, что замедлит его работу.
Если установлена директива SymLinksIfOwnerMatch, сервер будет проходить по символическим ссылкам, только если владелец целевого файла тот же, что и владелец ссылки. Это также влияет на скорость работы Apache.
Лучше всего активировать директиву FollowSymLinks и выключить директиву ‘SymLinksIfOwnerMatch’. Но это может привести к проблемам с безопасностью, поэтому окончательное решение остается за вами.
Согласование содержимого (Content Negotiation)
Согласование содержимого позволяет клиентам выбирать формат данных, получаемых от сервера. Рекомендуется избегать согласования содержимого для быстрого ответа.
Если согласование содержимого необходимо для сайта, можно снизить задержки, используя файлы type-map вместо директивы Options MultiViews. Ее применение увеличивает задержку.
Настройка MaxClients
Настройка MaxClients устанавливает лимит количества одновременных запросов, которое может поддерживаться Apache. Если это значение слишком мало, запросы станут в очередь, и не будут обрабатываться.
Большое значение параметра может загрузить оперативную память и повлиять на скорость ответов Apache. Необходимо выбрать оптимально значение исходя из объёма доступной памяти и ресурсов, потребляемых процессом.
Настройки MinSpareServers, MaxSpareServers и StartServers
MaxSpareServers и MinSpareServers определяют количество дочерних процессов, которые будут находиться в состоянии ожидания обработки запросов. Эти параметры важны, потому что создание дочернего процесса отнимает ресурсы.
Если значение MinSpareServers слишком низкое, и на сервер поступает одновременно несколько запросов, Apache создаст дополнительные дочерние процессы. Это снижает возможность быстрого ответа на запрос клиента.
Значение MaxSpareServers не должно быть слишком большим. Так как стоящие в очереди на обработку дочерние процессы потребляют лишние серверные мощности. Нужно установить эти значения в оптимальном диапазоне, чтобы сбалансировать использование ресурсов и производительность.
Директива StartServers устанавливает количество дочерних серверных процессов, которые создаются при старте сервера. Если запросов много, а Apache часто перезагружается, нужно установить относительно большое значение.
Настройка MaxRequestsPerChild
Директива MaxRequestsPerChild устанавливает лимит количества запросов, которое будет обрабатывать каждый дочерний процесс. Слишком малое значения может привести к перегрузке сервера при создании новых процессов. Поэтому нужно установить это значение в диапазоне нескольких тысяч, чтобы ускорить работу Apache.
Настройка KeepAlive и KeepAliveTimeout
KeepAlive используется для поддержки единого соединения для передачи данных веб-страницы. Благодаря чему не тратится время на создание нового подключения для каждого файла.
KeepAliveTimeout определяет время ожидания следующего запроса. Если значение большое, дочерние процессы могут расходовать ресурсы, ожидая следующего запроса. Оптимальное значение – 2-5 секунд для небольших объемов трафика и 10 секунд для высоконагруженных серверов.
Timeout
Устанавливает время ожидания запроса от посетителя. При больших объемах трафика значение параметра должно быть не менее 120 секунд. Но лучше держать это значение минимальным. Это позволяет предотвратить излишнее расходование ресурсов.
Тестирование системы
AB (Apache Benchmark) — простой инструмент тестирования нагрузки от Apache Foundation. Еще одна программа для тестирования — Siege. Также доступен инструмент на основе Python — Locust.
После установки Locust нужно будет создать файл locust в каталоге, из которого вы запускаете приложение:
from locust import HttpLocust, TaskSet, task class UserBehavior(TaskSet): @task(1) def index(self): self.client.get("/") @task(2) def shop(self): self.client.get("/?page_id=5") @task(3) def page(self): self.client.get("/?page_id=2") class WebsiteUser(HttpLocust): task_set = UserBehavior min_wait = 300 max_wait = 3000
Затем запускаем инструмент из командной строки:
locust --host=https://my-website.com
Применение перечисленных выше средств создает эффект DDoS-атаки, поэтому рекомендуется ограничить тестирование собственными сайтами.
Оптимизация обслуживания HTTP-запросов
Различные сайты написаны на различных языках программирования. Соответственно, для обслуживания HTTP-запросов к ним и их полноценной работы Apache использует интерпретаторы языков. Взаимодействие веб-сервера и интерпретатора обеспечивается соответствующими модулями. Для это mod_php, а для Ruby – mod_rails. Это «стандартные» модули, предоставляемые базовой поставкой Apache. Однако, они разработаны только с учётом обеспечения дополнительной функциональности без каких-либо решений по оптимизации производительности и потребления ресурсов.
Так, например, модуль mod_php способен потреблять около 100 Мб RAM для работы всего одного процесса, обслуживающего как минимум один HTTP-запрос. Следовательно, чем больше запросов, тем больше потребляемая память только от одного PHP-модуля. В данной ситуации в качестве альтернативы, но уже с куда более оптимизированными производительностью и потреблением памяти существует модуль . Этот модуль позволяет обрабатывать HTTP-запросы к веб-приложениям, написанным на PHP, используя технологию Fast CGI. Аналогичными решениями являются uWSGI для Python и Unicorn для Ruby.
Дело в том, что при использовании модуля php-fpm и ему подобных, изначально в памяти создаётся постоянный процесс для интерпретатора PHP ( Python или Ruby). И только после этого происходит перенаправление запросов от Apache к этому процессу для дальнейшей обработки. Таким образом, динамический контент обрабатывается всего двумя процессами. При этом потребление памяти может снизиться более чем в 8 раз.
Назначение параметров Apache prefork MPM и worker MPM
Перед началом конфигурации параметров prefork MPM и worker MPM модулей для apache рассмотрим их смысловое назначение.
StartServers N — определяет число (N) процессов стартующих при запуске apache.
ServerLimit N — это мутный параметр и согласно документации apache (http://www.apache.com/docs/httpd-docs-2.2.13.en/mod/mpm_common.html#serverlimit) ServerLimit в сочетании с ThreadLimit устанавливает максимальное значение для жизни процесса Apache из MaxClients. Если ServerLimit установлен в значение намного выше, чем это необходимо, дополнительные, неиспользованная память будет выделена. Если значение ServerLimit и MaxClients установлено выше, чем система может выдержать, Apache может не запуститься или система может стать нестабильной. Обычно значение ServerLimit и MaxClients устанавливаются равными друг-другу. С MPM Prefork, используйте эту директиву, только если вам нужно установить MaxClients выше, чем 256 (по умолчанию). Не устанавливайте значение этой директивы выше, чем значение в MaxClients. С Apache-MPM worker используйте эту директиву только если значения MaxClients и ThreadsPerChild установлены больше чем 16 процессов сервера (по умолчанию)
Не устанавливайте значение этой директивы выше, чем количество серверных процессов, что установлены для MaxClients и ThreadsPerChild — вероятно имеется ввиду не превышать суммарное значение директив MaxClients и ThreadsPerChild.ВНИМАНИЕ!!! В стандартной компиляции веб сервера Апаче существует жесткое ограничение ServerLimit 20000 (для Prefork MPM 200000).
MinSpareServers N — определяет минимальное число (N) свободных процессов, т.е. тех которые ничем не заняты, при их уменьшении по мере занятости, apache будет создавать новые резервные процессы, чтобы не снизить скорость выполнении скриптов имея в запасе свободные ресурсы.
MaxSpareServers N — определяет макисмальное число (N) процессов, высящих без дела, при превышении этого числа процессы будут уничтожатся
Выставление этого параметра очень сильно зависит от характера скриптов, и загруженности в целом сервера. Если число поступающих к вам запросов превышает число серверов в пуле, заданное параметром StartServers, буфер серверов увеличивается для обслуживания запросов. Эти дополнительные процессы-серверы не завершаются после обработки запроса, ради которого они были запущены; они остаются в памяти. Директива MaxSpareServers позволяет настраивать число свободных серверов, находящихся в пуле. Если их больше, чем указано в директиве MaxSpareServers, то лишние процессы завершаются. Аналогично, если свободных серверов в пуле меньше, чем допускает директива MinSpareServers, то в преддверии наплыва запросов создаются дополнительные копии сервера.
MaxClients N — определяет максимальное число (N) запускаемых в единицу времени процессов, фактически определяет сколько клиентов смогут одновременно подключиться к веб серверу. Слишком большое значение подвергает веб сервер опасности быть атакованным и сваленным в своп, а также грозит полным отказом в обслуживании.
MaxRequestsPerChild N — значение (N) определяет максимальное количество обрабатываемых одним потоком запросов, после выполнения количества которых процесс будет заколбашен. Очень нужный параметр! Рекомендуется устанавливать значение этого параметра до 4000. При утечке оперативной памяти в скриптах, апаче будет освобождать ее после 4К выполненных этим процессом запросов.
ThreadsPerChild N — значение этого параметра определяет количество потоков создаваемых каждым порождённым процессом. При использовании MPM как mpm_winnt, где есть только один дочерний процесс, это число должно быть достаточно высоким, чтобы обрабатывать всю нагрузку на сервер. При использовании MPM как Apache-MPM worker, где есть несколько дочерних процессов, общее количество потоков также должно быть достаточно высоким, чтобы справиться с большой нагрузкой на сервер. Обычно значение по умолчанию для ThreadsPerChild составляет 64 при использовании с mpm_winnt и 25 при использовании с другими MPM модулями.
Значения параметров Apache prefork MPM и worker MPM следует подбирать сугубо индивидуально для каждого отдельного случая принимая во внимание загруженность сервера, количество оперативной памяти, силу ЦП, жестких дисков и пр.
Модули в Apache
Первое, самое основное, что-то типа «спасибо-кэп» — Apache нужно запускать с необходимыми модулями, чтобы уменьшить потребление памяти.
Для их отключения можно воспользоваться командами a2dismod <имя_модуля> а потом перезапустить конфигурацию сервера. Если вы отключите что-то не то, то включить модуль можно командой a2enmod <имя_модуля>. Опять же смотрите что отключайте, иначе какие-то функции ваших проектов могут перестать работать.
Кстати, как правило, кроме этих перечисленных модулей вам больше ничего не нужно:
mod_alias mod_authz_host mod_deflate mod_dir mod_expires mod_headers mod_mime mod_rewrite mod_log_config mod_autoindex mod_negotiation mod_setenvif
mod_cache
Модуль mod_cache с mod_disc_cache является одной из самых лучших возможностей увеличения производительности вашего сервера. Несмотря на то, что у нас хранится примерно 3 терабайт контента (примерно 6 миллионов файлов), только небольшая его часть популярна в определенное время. В определенное 6-часовое окно скачивается 50,000 различных файлов, что в совокупности представляет только 10Гб уникального контента.
Наши файловые хранилища обслуживаются дисками 7200 RPM IDE, поэтому будет очень хорошо, если мы сможим снизить нагрузку на наши файловые хранилища. Также мы создали 36 Gb RAID-0 хранилище, используя два 18 Гб 15k RPM SCSI диска. Комбинация RAID-0 и 15k RPM дисков делает это хранилище значительно быстрее.
mod_disc_cache кеширует файлы в заданное место при первой их обработке. Повторные запросы обрабатываются уже из кеша, обходя более медленные файловые хранилища. mod_disk_cache содержит хороший пример конфигурации, но в нашей конфигурации мы увеличили CacheDirLevel до 5, чтобы увеличить количество файлов, которое помещается в кеш.
<IfModule mod_cache.c><IfModule mod_disk_cache.c>
CacheRoot
CacheEnable disk /
CacheDirLevels 5
CacheDirLength 3</IfModule></IfModule>
Но следует учесть, что mod_disk_cache до сих пор является экспериментальным в Apache 2.0 и в Apache 2.1, и, вероятно, не удовлетворяет требованиям производственного использования. Тем не менее, если есть время для аккуратного исследования его поведения, то он может стать источником большого повышения производительности.
Еще одна вещь, которую нужно учесть, это то, что Apache не занимается очисткой кеша. Некоторое время для этой цели мы использовали комбинацию find, xargs и rm, однако теперь Apache 2.1 включает утилиту htcacheclean, которая используется для очистки кеша.
htcacheclean запускается либо cron-ом, либо в качестве демона, и периодически очищает кеш. Необходимо только убедиться, что ваше хранилище обладает необходимым объемом свободного места.
Примечание: Многие вопросы повышения производительности приведены в 8 главе книги «Apache для профессионалов». Подробнее о книге…
Sendfile
Sendfile — это системный вызов, доступный во многих операционных системах. Он позволяет программам передать ядру ОС работу по передаче файлов TCP сокету. Следовательно, лучше заботы о распределении памяти и об оптимальном размере буфера передать ядру, которое оптимизирует все операции чтения.
Использование sendfile включается по умолчанию во время компиляции в случае, если Apache определит, что операционная система поддерживает эту возможность. Следующая директива в конфигурационном файле включает использование sendfile:
EnableSendfile On
Постоянное использование sendfile существенно повысит производительность и эффективность. К сожалению, в нашем случае работа sendfile на нашем оборудовании приводила к порче IPv6 сессий.
Примечание: Это происходило из-за ошибки при расчете контрольной суммы TCP почти на всех сетевых интерфейсах. И Linux использует неверную контрольную сумму при вызове sendfile. Данный баг был обнаружен при помощи Джо Ортона (Joe Orton). Так как HEanet работает с IPv6 так же, как и с IPv4, то простое выключение поддержки IPv6 неприемлемо для нас.
Решение заключалось в исправлении кода сервера, чтобы просто не использовать sendfile, когда поступивший запрос использует IPv6. Теперь эта возможность добавлена в Apache Portable Runtime (APR).
Новое на сайте
13 май
почтовый сервер на основе Postfix с пользователями в MySQL и Dovecot как MDA
как установить почтовый сервер Postfix (MTA) для произвольного числа доменов и Dovecot 2.x в качестве MDA, использовать MySQL и PostfixAdmin, задействовать квоты, обеспечить защиту от спама и вирусов используя цифровую подпись DKIM, dspam и ClavaAV
подробнее…
18 апр
До опредленного времени, нежелательные сайты в офисе блокировались «прозрачным» SQUID-ом. Однако SQUID3 не может работать с SSL соединениями в режиме transparent и, соответственно, не может блокировать социалки, доступные по https. iptables нам поможет!
подробнее…
22 сент
настройка прозрачного squid3 с пулами задержки или как навести порядок в офисе
Работа в типичном офисе и социальные сети не совместимы. Любой администратор рано или поздно решает задачу — как запретить развлекательный контент и социальные сети в офисе и ограничить скорость Интернета. В этих начинаниях нам поможет Squid3.
подробнее…
18 мар
конечно можно настроить sftp или даже ftp на худой конец и деплоить каждый чих в своем приложении/сайте прямо из вашей любимой IDE, однако удобнее использовать опцию shared folders, которая идёт с VirtualBox прямо «из коробки».
подробнее…
17 фев
монтируем новый жёсткий диск в Debian или решаем проблемы со свободным местом
Знакомая ситуация — заканчивается место на жёстком диске на виртуальном сервере разработки Debian (VirualBox). Разберёмся, как подключить новый жесткий диск, создать на нём ext4 раздел и смонтировать его через fstab по UUID.
подробнее…
06 янв
быстрый старт bower + grunt или дань моде
Часто приходится настраивать связку bower+grunt. Bower — незаменимый менеджер пакетов. Grunt — замечательное средство для автоматизации рутинны со статикой проекта. Ах да, для установки всего этого безобразия нам ещё потребуется Node.js
подробнее…
09 сент
настройка почтового сервера как резервного (backup MX) или пересылка почты для домена клиента
Нобходимо настроить наш сервер как резервный Backup MX для отдельных клиентов. Ситуацию усложняет необходимость иметь несколько активных ящиков на нашем сервере, вне зависимости есть они или нету на основном почтовом сервере. Зачем же это было нужно?
подробнее…
22 май
настройка квоты домена в MDA Dovecot используя dict + mysql
Дело вкуса, но жизнь требует возможности настройки квот на уровне домена по той или иной причине. Как же настроить квоты для доменов в Dovecot, если используется mysql и dict соответственно. Ответ прост — никак. Детали — под катом.
подробнее…
16 май
настройка «greylisting» для postfix (postgrey) или борьба со спамом продолжается
Еще один инструмент для борьбы со спамом – грейлистинг. Суть – временно отклонять почту от новых отправителей со словами «зайдите завтра». Добропорядочный сервер обязательно «зайдет». Типичный спаммер – нет. Итак, Postgray для Postfix.
подробнее…
15 май
настройка Fail2Ban для защиты служб сервера от атак извне или как сделать логи аккуратными
Благая цель – избавить сервер от лишней работы (нагрузки) и блокировать попытки перебора паролей и хакерских атак – крайне благородна. Настроим инструмент fail2ban для мониторинга лог-файлов служб на сервере и блокирования вредителей по IP…
подробнее…
E-mail:Skype: dmitry_rendov
Тел.:
включите javascript чтобы видеть номер
Все обновления в Twitter twitter.com/DmitryRendov
Недостатки
Данная многозадачная архитектура полезна, если обработка запросов клиента занимает некоторое время или состояние сессии соединения необходимо хранить на (дочернем) сервере, в случае если обмен данными между клиентом и сервером не завершается после ответа на первый запрос.
Тем не менее, протокол HTTP не сохраняет сессию. Никакой информации о сессии не хранится на сервере — ему надо только ответить на один запрос и тут же может забыть о нем. HTTP сервер, основанный на архитектуре inetd — неэффективен. Главному серверу необходимо создавать новый процесс для каждого HTTP соединения, который затем обрабатывает это соединение и завершается. Пока главный сервер создает процесс, он не может принимать входящие запросы. Хотя создание процесса и не занимает много времени на современных операционных системах, данная функция главного сервера является “узким местом” для всего сервера в целом.
Дочерний сервер (рабочий)
В данной архитектуре инициализация дочернего сервера является более сложной задачей, так как он обладает более сложной структурой. Сперва главный сервер создает дочерний процесс, который в свою очередь создает “запускающую” нить, которая создает все рабочие нити и одну прослушивающую нить. Это поведение отражено на .
Внутри каждого дочернего процесса, взаимодействие между прослушивателем и всеми рабочими нитями организовано с помощью двух очередей, очередью заданий и очередью простоя. Нить прослушивателя применяется только при разрешающем семафоре, если в очереди простоя есть токен, показывающий, что, по крайней мере, одна свободная рабочая нить ожидает обработки запроса. Если прослушиватель получает семафор, он ожидает поступление нового запроса, а после поступления оного передает данные о запросе в очередь, после чего освобождает разрешающий семафор. Таким образом, это дает гарантию, что входящий запрос будет обслужен немедленно.
После завершения обработки запроса или соединения со множеством запросов (см. ), рабочая нить обозначается как свободная, путем положения токена в очередь простоя, и вновь начинает ожидать новых запросов в очереди заданий.
Достоинствами этого подхода является то, что он совмещает стабильную концепцию многопроцессности и более производительную концепцию многонитеевости. В случае возникновения ошибки, она отразится только на одном процессе. А в многонитеевой модели ошибка в нити может повлиять на все нити, относящиеся к этому родительскому процессу. Однако нити гораздо более легковесны и поэтому требуют меньше ресурсов при запуске и используют меньше памяти при работе.
Дочерний процесс: Прослушиватели и очередь заданий
Рабочий процесс содержит три вида нитей: Одну главную нить, фиксированное число рабочих нитей и одну или несколько прослушивающих нитей. Главная нить создает одну или несколько прослушивающих нитей, которые принимают запросы на соединения и отправляют данные соединений в очередь заданий. Рабочие нити получают данные соединений из очереди, и затем получают и обрабатывают запросы при помощи функций ядра обработки запросов, которое используется всеми многозадачными архитектурами. Взаимодействие между главной и рабочими нитями также происходит через очередь заданий. Если главная нить захочет уменьшить количество рабочих нитей при завершении или ‘перезагрузке’ — она отправляет в очередь ‘мертвые’ работы.
Вместо очереди заданий, МП-модуль версии 2.0 для Windows NT платформ использует IOCP. Преимущество IOCP заключается в том, что он позволяет серверу определять верхнюю границу активных нитей. Все рабочие нити регистрируются для IOCP и приостанавливаются, если зарегистрированы в очереди заданий. При возникновении любого события, IOCP отвечает за ‘пробуждение’ одной рабочей нити для обработки этого события (в Apache это может быть только новый входящий запрос на соединение). Однако если граница активных нитей будет превышена, нити не будут активизироваться для обработки новых запросов, пока другой блок нитей не будет перерегистрирован для IOCP. Эта техника используется для предотвращения чрезмерного переключения контекста большого числа активных нитей.