Apache. Документация на русском


Разделы:   1    2    3    4    5    6    7    8    9      10      11    12    13    14    15    16  

Раздел 10. Модули Апача

Пункты:   85    86    88      89      90    91    92    93    94    95    96    97    98    99    100    101    102    103    104    105    106    107    108    109    110    111    112    113    114    115    116    117    118    119    120    121    122    123    124    125    126    127    128    129    130    131    132    133    134    135    136    137    138    139    140    141    142    143    144    145    146    147    148    149    150    151    152    153    154    155    156    157    158    159    160    161    163    164    165    166    167    168    170    171    172    173    174    175    176    177    178    179    180    181    182    183    184    185    186    187    188    189    190    191    192    193    194    195    196    197    198    199    200    201    203    204    205    206    207    208    209    210    211    212    213  

 <         > 
  RU            EN  

Пункт 89. Событие Apache MPM

Многопроцессорный event модуль (MPM) предназначен для одновременного обслуживания большего количества запросов путем передачи части обработки потокам прослушивателей, освобождая рабочие потоки для обслуживания новых запросов.

Чтобы использовать event MPM, добавьте --with-mpm=event к configure аргументам скрипта при создании файла httpd .

Отношения с рабочим MPM

event основан на worker MPM, который реализует гибридный многопроцессорный многопоточный сервер. Один управляющий процесс (родительский) отвечает за запуск дочерних процессов. Каждый дочерний процесс создает фиксированное количество серверных потоков, как указано в ThreadsPerChild директиве, а также поток прослушивателя, который прослушивает подключения и передает их рабочему потоку для обработки, когда они прибывают.

Директивы конфигурации во время выполнения идентичны директивам, предоставляемым worker , с единственным добавлением расширения AsyncRequestWorkerFactor .

Как это работает

Этот MPM пытается исправить «проблему поддержания активности» в HTTP. После того, как клиент выполнит первый запрос, он может оставить соединение открытым, отправляя последующие запросы с использованием того же сокета и экономя значительные накладные расходы при создании TCP-соединений. Однако HTTP-сервер Apache традиционно держит весь дочерний процесс/поток в ожидании данных от клиента, что имеет свои недостатки. Чтобы решить эту проблему, этот MPM использует выделенный поток прослушивателя для каждого процесса для обработки обоих сокетов прослушивания, всех сокетов, которые находятся в состоянии Keep Alive, сокетов, в которых обработчик и фильтры протоколов выполнили свою работу, и тех, в которых остались только оставшиеся. что нужно сделать, это отправить данные клиенту.

Эта новая архитектура, использующая неблокирующие сокеты и современные функции ядра, предоставляемые APR (например, epoll в Linux), больше не требует настройки, mpm-accept Mutex чтобы избежать проблемы громогласного стада.

Общее количество соединений, которые может обрабатывать один блок процессов/потоков, регулируется директивой AsyncRequestWorkerFactor .

Асинхронные соединения

Для асинхронных соединений потребуется фиксированный выделенный рабочий поток с предыдущими MPM, но не с событием. На странице состояния mod_status отображаются новые столбцы в разделе асинхронных подключений:

Письмо
При отправке ответа клиенту может случиться так, что буфер записи TCP переполнится из-за слишком медленного соединения. Обычно в этом случае a write() в сокет возвращается EWOULDBLOCK или EAGAIN , чтобы снова стать доступным для записи после простоя. Рабочий процесс, удерживающий сокет, может разгрузить ожидающую задачу потоку прослушивателя, который, в свою очередь, переназначит ее первому доступному бездействующему рабочему потоку, как только для сокета будет вызвано событие (например, «сокет теперь доступен для записи"). Пожалуйста, ознакомьтесь с разделом Ограничения для получения дополнительной информации.
Keep-alive
Обработка Keep Alive — это самое основное улучшение по сравнению с рабочим MPM. Как только рабочий поток заканчивает сбрасывать ответ клиенту, он может передать обработку сокета потоку прослушивателя, который, в свою очередь, будет ждать любого события от ОС, например «сокет доступен для чтения». Если от клиента приходит какой-либо новый запрос, то прослушиватель пересылает его первому доступному рабочему потоку. И наоборот, если это KeepAliveTimeout происходит, сокет будет закрыт слушателем. Таким образом, рабочие потоки не несут ответственности за простаивающие сокеты, и их можно повторно использовать для обслуживания других запросов.
Закрытие
Иногда MPM необходимо выполнить затяжное закрытие, а именно отправить обратно клиенту раннюю ошибку, пока он все еще передает данные на httpd. Отправка ответа и последующее немедленное закрытие соединения не является правильным решением, поскольку клиент (все еще пытающийся отправить остальную часть запроса) получит сброс соединения и не сможет прочитать ответ httpd. Таким образом, в таких случаях httpd пытается прочитать остальную часть запроса, чтобы клиент мог использовать ответ. Затянувшееся закрытие ограничено по времени, но может занять относительно много времени, поэтому рабочий поток может переложить эту работу на слушателя.

Эти улучшения действительны для соединений HTTP/HTTPS.

Изящное завершение процесса и использование Scoreboard

В прошлом этот mpm демонстрировал некоторые узкие места масштабируемости, что приводило к следующей ошибке: « табло заполнено, а не в MaxRequestWorkers ». MaxRequestWorkers ограничивает количество одновременных запросов, которые будут обслуживаться в любой момент времени, а также количество разрешенных процессов ( / MaxRequestWorkers ) ThreadsPerChild , в то время как Scoreboard представляет собой представление всех запущенных процессов и состояния их рабочих потоков. Если таблица результатов заполнена (поэтому все потоки находятся в состоянии не бездействия), но количество обслуженных активных запросов не равно MaxRequestWorkers , это означает, что некоторые из них блокируют новые запросы, которые могли бы быть обслужены, но вместо этого поставлены в очередь (до предел, установленный ListenBacklog ). В большинстве случаев потоки застревают в состоянии Graceful, а именно они ожидают завершения своей работы с TCP-соединением, чтобы безопасно завершить и освободить слот таблицы результатов (например, обработка длительных запросов, медленных клиентов или соединений с поддержкой активности). включено). Очень распространены два сценария:

  • Во время изящного перезапуска. Родительский процесс сигнализирует всем своим дочерним процессам, чтобы они завершили свою работу и завершились, в то время как он перезагружает конфигурацию и разветвляет новые процессы. Если старые дети продолжают бежать некоторое время, прежде чем остановиться, табло будет частично занято до тех пор, пока их слоты не будут освобождены.
  • Когда нагрузка на сервер снижается таким образом, что httpd останавливает некоторые процессы (например, из-за MaxSpareThreads ). Это особенно проблематично, потому что, когда нагрузка снова возрастет, httpd попытается запустить новые процессы. Если шаблон повторяется, количество процессов может значительно увеличиться, что приведет к смешению старых процессов, пытающихся остановиться, и новых, пытающихся выполнить какую-то работу.

Начиная с версии 2.4.24, mpm-event стал умнее и лучше справляется с изящными завершениями. Некоторые из улучшений:

  • Разрешить использование всех слотов табло до ServerLimit . MaxRequestWorkers и ThreadsPerChild используются для ограничения количества активных процессов, при этом ServerLimit также учитываются те, которые выполняют изящное закрытие, чтобы при необходимости освободить дополнительные слоты. Идея состоит в том, чтобы использовать ServerLimit для указания httpd о том, сколько общих процессов допустимо, прежде чем воздействовать на системные ресурсы.
  • Заставьте изящно завершить процессы, чтобы закрыть их соединения в состоянии проверки активности.
  • Во время корректного завершения работы, если запущенных рабочих потоков больше, чем открытых подключений для данного процесса, завершите эти потоки, чтобы быстрее освободить ресурсы (что может потребоваться для новых процессов).
  • Если табло заполнено, не допускайте корректного завершения других процессов из-за снижения нагрузки до тех пор, пока не будут завершены старые процессы (в противном случае ситуация ухудшится, когда нагрузка снова возрастет).

Описанное в последнем пункте поведение полностью просматривается в mod_status сводной таблице подключений через две новые колонки: «Слот» и «Остановка». Первый указывает PID, а второй указывает, останавливается процесс или нет; дополнительное состояние «Да (старое поколение)» указывает на то, что процесс все еще выполняется после плавного перезапуска.

Ограничения

Улучшенная обработка соединений может не работать для определенных фильтров соединений, которые объявили себя несовместимыми с событием. В этих случаях этот MPM вернется к поведению MPM worker и зарезервирует один рабочий поток для каждого соединения. Все модули, поставляемые с сервером, совместимы с MPM событий.

Аналогичное ограничение в настоящее время присутствует для запросов, включающих выходной фильтр, которому необходимо прочитать и/или изменить все тело ответа. Если соединение с клиентом блокируется, пока фильтр обрабатывает данные, а количество данных, созданных фильтром, слишком велико для буферизации в памяти, поток, используемый для запроса, не освобождается, пока httpd ожидает, пока ожидающие данные не будут обработаны. отправлено клиенту.
Чтобы проиллюстрировать этот момент, мы можем подумать о следующих двух ситуациях: обслуживание статического актива (например, файла CSS) и обслуживание контента, полученного с FCGI/CGI или прокси-сервера. Первое предсказуемо, а именно событие MPM имеет полную видимость в конце содержимого и может использовать события: рабочий поток, обслуживающий содержимое ответа, может сбрасывать первые байты до тех пор, пока или не будет возвращен, делегируя остальные EWOULDBLOCK приемнику EAGAIN . Этот, в свою очередь, ожидает события в сокете и делегирует работу по сбросу остального содержимого первому бездействующему рабочему потоку. Между тем, в последнем примере (FCGI/CGI/прокси-контент) MPM не может предсказать конец ответа, и рабочий поток должен завершить свою работу, прежде чем вернуть управление слушателю. Единственной альтернативой является буферизация ответа в памяти, но это не самый безопасный вариант из-за стабильности сервера и занимаемой памяти.

Справочный материал

Модель событий стала возможной благодаря внедрению новых API в поддерживаемые операционные системы:

  • Эполл (Линукс)
  • очередь (BSD)
  • порты событий (Solaris)

До того, как эти новые API стали доступными, приходилось использовать традиционные select и API. poll Эти API работают медленно, если используются для обработки большого количества соединений или если скорость изменения набора соединений высока. Новые API позволяют отслеживать гораздо больше соединений, и они работают намного лучше, когда набор соединений для мониторинга часто меняется. Таким образом, эти API-интерфейсы позволили написать событие MPM, которое намного лучше масштабируется с типичным шаблоном HTTP для многих бездействующих соединений.

MPM предполагает, что базовая apr_pollset реализация в разумных пределах потокобезопасна. Это позволяет MPM избежать чрезмерной блокировки высокого уровня или необходимости пробуждать поток прослушивателя, чтобы отправить ему сокет проверки активности. В настоящее время это совместимо только с KQueue и EPoll.

Требования

Этот MPM зависит от атомарных операций сравнения и замены APR для синхронизации потоков. Если вы компилируете для цели x86 и вам не нужно поддерживать 386, или вы компилируете для SPARC и вам не нужно работать на чипах до UltraSPARC, добавьте аргументы --enable-nonportable-atomics=yes сценария configure . Это заставит APR реализовать атомарные операции с использованием эффективных кодов операций, недоступных в старых ЦП.

Этот MPM плохо работает на старых платформах, которым не хватает хорошей многопоточности, но требование EPoll или KQueue делает это спорным.

  • Для использования этого MPM во FreeBSD рекомендуется FreeBSD 5.3 или выше. Однако этот MPM можно запустить на FreeBSD 5.2.1, если вы используете libkse (см. Ресурсы man libmap.conf ).
  • Для NetBSD рекомендуется как минимум версия 2.0.
  • Для Linux рекомендуется ядро 2.6. Также необходимо убедиться, что ваша версия glibc была скомпилирована с поддержкой EPoll.


Директива AsyncRequestWorkerFactor

Описание:Ограничение одновременных подключений на процесс
Синтаксис: AsyncRequestWorkerFactor factor
По умолчанию: 2
Контекст:конфигурация сервера
Положение дел:МПМ
Модуль:событие
Совместимость:Доступно в версии 2.3.13 и выше

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

Чтобы смягчить эту проблему, событие MPM делает две вещи:

  • он ограничивает количество подключений, принимаемых на процесс, в зависимости от количества бездействующих обработчиков запросов;
  • если все рабочие процессы заняты, он закроет соединения в состоянии проверки активности, даже если время ожидания проверки активности не истекло. Это позволяет соответствующим клиентам повторно подключаться к другому процессу, в котором все еще могут быть доступны рабочие потоки.

Эту директиву можно использовать для точной настройки лимита соединений для каждого процесса. Процесс будет принимать новые соединения только в том случае, если текущее количество соединений (не считая соединений в состоянии «закрытие») меньше, чем :

ThreadsPerChild + ( AsyncRequestWorkerFactor * количество бездействующих работников )

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

( ThreadsPerChild + ( AsyncRequestWorkerFactor * количество бездействующих работников )) * ServerLimit

Пример

 ThreadsPerChild = 10
Лимит серверов = 4
Асинкрекуестворкерфактор = 2
Максрекуестворкерс = 40
idle_workers = 4 (среднее значение для всех процессов для простоты)
max_connections = (ThreadsPerChild + (AsyncRequestWorkerFactor * idle_workers)) * ServerLimit
 = (10 + (2 * 4)) * 4 = 72 

Когда все рабочие потоки простаивают, абсолютное максимальное количество одновременных подключений можно вычислить более простым способом:

( AsyncRequestWorkerFactor + 1) * MaxRequestWorkers

Пример

 ThreadsPerChild = 10
Лимит серверов = 4
Максрекуестворкерс = 40
Асинкрекуестворкерфактор = 2 

Если у всех процессов все потоки простаивают, то:

 бездействующие_работники = 10 

Мы можем рассчитать абсолютное максимальное количество одновременных подключений двумя способами:

 max_connections = (ThreadsPerChild + (AsyncRequestWorkerFactor * idle_workers)) * ServerLimit
 = (10 + (2 * 10)) * 4 = 120
max_connections = (AsyncRequestWorkerFactor + 1) * MaxRequestWorkers
 = (2 + 1) * 40 = 120 

Для настройки AsyncRequestWorkerFactor требуются знания о трафике, обрабатываемом httpd в каждом конкретном случае использования, поэтому изменение значения по умолчанию требует тщательного тестирования и сбора данных из файлов mod_status .

MaxRequestWorkers вызывался MaxClients до версии 2.3.13. Приведенное выше значение показывает, что старое имя не совсем точно описывает свое значение для события MPM.

AsyncRequestWorkerFactor может принимать нецелые аргументы, например "1.5".



 <         > 

Пункты:   85    86    88      89      90    91    92    93    94    95    96    97    98    99    100    101    102    103    104    105    106    107    108    109    110    111    112    113    114    115    116    117    118    119    120    121    122    123    124    125    126    127    128    129    130    131    132    133    134    135    136    137    138    139    140    141    142    143    144    145    146    147    148    149    150    151    152    153    154    155    156    157    158    159    160    161    163    164    165    166    167    168    170    171    172    173    174    175    176    177    178    179    180    181    182    183    184    185    186    187    188    189    190    191    192    193    194    195    196    197    198    199    200    201    203    204    205    206    207    208    209    210    211    212    213  

Рейтинг@Mail.ru