Apache Версия 2.0 Сервера HTTP
Apache 2.0 - webserver общего назначения, разработанный, чтобы обеспечить баланс гибкости, мобильности, и работы. Хотя это не было разработано определенно, чтобы установить эталонные отчеты, Apache 2.0 способен к высокой эффективности во многих ситуациях реального мира.
по сравнению с Apache 1.3, выпуск 2.0 содержит много дополнительной оптимизации, чтобы увеличить пропускную способность и масштабируемость. Большинство этих усовершенствований позволяется по умолчанию. Однако, есть, собирают разовые и выборы конфигурации во время выполнения, которые могут значительно затронуть работу. Этот документ описывает варианты, которые администратор сервера может формировать, чтобы настроить работу Apacheских 2.0 установок. Некоторые из этих вариантов конфигурации позволяют httpd лучше использовать в своих интересах способности аппаратных средств и РТА, в то время как другие позволяют администратору торговать функциональные возможности для скорости.
единственная самая большая проблема аппаратных средств, затрагивающая webserver работа - RAM. webserver когда-либо никогда не придется обменивать, как обмен увеличений время ожидания каждого запроса вне пункта, что пользователи рассматривают "достаточно быстро". Это заставляет пользователей поражать остановку и перезаряжать, далее увеличивая груз. Вы можете и должны управлять
MaxClients
урегулирование так, чтобы ваш сервер не породил очень много детей, которых это начинает обменивать. Эта процедура для того, чтобы делать это проста: определите размер вашего среднего Apacheского процесса, смотря на ваш список процесса через инструмент, типа
top
, и разделите это на вашу полную доступную память, оставляя некоторую комнату для других процессов.
кроме того остальные являются мирскими: получите достаточно быстрый центральный процессор, достаточно быструю карту сети, и достаточно быстро диски, где "достаточно быстро" является кое-чем что потребности, которые будут определены экспериментированием.
операционный выбор системы - в значительной степени вопрос местных проблем. Но некоторые руководящие принципы, которые оказались вообще полезными:
бежать последним устойчивым выпуском и patchlevel операционной системы, которую Вы выбираете. Много поставщиков РТА ввели существенные усовершенствования работы их стекам TCP и пронизывают библиотеки в последние годы.
если ваш РОТ поддерживает a
sendfile(2)
запрос системы, удостоверьтесь, что Вы устанавливаете выпуск, и/или участки должны были позволить это. (С Linux, например, это означает использовать Linux 2.4 или позже. Для ранних выпусков Solaris 8, Вы, возможно, должны применить участок.) На системах, где это доступно,
sendfile
позволяет Apacheским 2 поставить статическое содержание быстрее и с более низким использованием центрального процессора.
Связанные Модули | Связанные Директивы |
---|---|
до Apacheа 1.3,
HostnameLookups
defaulted к
On
. это добавляет время ожидания к каждому запросу, потому что это требует, чтобы поиск DNS закончил прежде, чем запрос закончен. На Apacheских 1.3 этих неплатежах урегулирования к
Off
. если Вы должны иметь адреса в ваших файлах системного журнала, решенных к hostnames, используйте
logresolve
программа, которая идет с Apache, на одной из многочисленной регистрации, сообщая о пакетах, которые являются доступными.
рекомендуется, чтобы Вы сделали этот вид постобработки ваших файлов системного журнала на некоторой машине кроме машины сервера сети производства, чтобы эта деятельность не неблагоприятно затронула работу сервера.
если Вы используете любого
или
Allow
от области
директивы (то есть, используя hostname, или название области, а не IP адрес) тогда Вы заплатите за двойной обратный поиск DNS (перемена, сопровождаемая передовым, чтобы удостовериться, что перемена не spoofed). Для лучшей работы, поэтому, IP адресов использования, а не названий, используя эти директивы, если возможно.
Deny
от области
отметить, что это возможно к возможностям директивы, типа в пределах a
<Location /server-status>
секция. В этом случае поиски DNS только выполнены на запросах, соответствующих критериям. Вот - пример, который повреждает поиски за исключением
.html
и
.cgi
файлы:
HostnameLookups off
<Files ~ "\.(html|cgi)$">
HostnameLookups on
</Files>
но даже все еще, если Вы только нуждаетесь в названиях DNS в некотором CGIs, Вы могли бы рассмотреть выполнение
gethostbyname
звонить в определенных CGIs, которые нуждаются в этом.
везде, где в вашем МЕСТЕ URL Вы не имеете
Options FollowSymLinks
, или Вы действительно имеете
Options SymLinksIfOwnerMatch
Apache должен будет выпустить дополнительные запросы системы выяснить symlinks. Один дополнительный запрос в компонент имени файла. Например, если Вы имели:
DocumentRoot /www/htdocs
<Directory />
Options SymLinksIfOwnerMatch
</Directory>
и запрос сделан для ТУРОВ
/index.html
. тогда Apache выполнит
lstat(2)
на
/www
,
/www/htdocs
, и
/www/htdocs/index.html
. результаты их
lstats
никогда не прячутся про запас, таким образом они произойдут на каждом отдельном запросе. Если Вы действительно желаете, чтобы symlinks безопасность, проверяющая Вас могла сделать кое-что как это:
DocumentRoot /www/htdocs
<Directory />
Options FollowSymLinks
</Directory>
<Directory /www/htdocs>
Options -FollowSymLinks +SymLinksIfOwnerMatch
</Directory>
это по крайней мере избегает дополнительных чеков на
DocumentRoot
дорожка. Отметьте, что Вы будете должны добавить подобные секции, если Вы будете иметь любого
Alias
или
RewriteRule
дорожки вне вашего корня документа. Для самой высокой работы, и никакой symlink защиты, набора
FollowSymLinks
всюду, и никогда набор
SymLinksIfOwnerMatch
.
везде, где в вашем МЕСТЕ URL Вы позволяете, отвергает (типично
.htaccess
файлы), Apache попытается открыться
.htaccess
для каждого компонента имени файла. Например,
DocumentRoot /www/htdocs
<Directory />
AllowOverride all
</Directory>
и запрос сделан для ТУРОВ
/index.html
. тогда Apache попытается открыться
/.htaccess
,
/www/.htaccess
, и
/www/htdocs/.htaccess
. решения подобны предыдущему случаю
Options FollowSymLinks
. для самого высокого использования работы
AllowOverride None
всюду в вашей файловой системе.
если вообще возможно, избегите довольных переговоров, если Вы действительно интересуетесь каждой последней унцией работы. Практически выгоды переговоров перевешивают штрафы работы. Есть один случай, где Вы можете ускорить сервер. Вместо того, чтобы использовать групповой символ, типа:
DirectoryIndex index
использовать полный список вариантов:
DirectoryIndex index.cgi index.pl index.shtml index.html
где Вы перечисляете самый общий выбор сначала.
также отметьте это явно создающий a
type-map
файл обеспечивает лучшую работу чем использование
MultiViews
, поскольку необходимая информация может быть определена, читая этот единственный файл, вместо того, чтобы иметь необходимость просматривать справочник для файлов.
если ваши переговоры содержания потребностей участка рассматривают использование
type-map
файлы, а не
Options MultiViews
директива, чтобы достигнуть переговоров. См.
Content Negotiation
документация для полного обсуждения методов переговоров, и инструкций для создания
type-map
файлы.
в ситуациях, где Apacheские 2.0 потребности смотреть на содержание поставляемого файла - например, делая обработку "сторона сервера включают" - это обычно карты памяти файл, если РОТ поддерживает некоторую форму
mmap(2)
.
на некоторых платформах, эта картография памяти улучшает работу. Однако, есть случаи, где картография памяти могла повредить работу или даже стабильность httpd:
на некоторых операционных системах,
mmap
не измеряет так же как
read(2)
когда число увеличений центральных процессоров. На мультипроцессоре серверы Solaris, например, Apache 2.0 иногда поставляет разобранные сервером файлы быстрее когда
mmap
является инвалидами.
если Вы карта памяти файл, расположенный на УСТАНОВЛЕННОЙ NFS файловой системе и процессе на другой машине клиента NFS удаляет или усекает файл, ваш процесс может получить автобусную ошибку в следующий раз, когда это пробует получить доступ к нанесенному на карту содержанию файла.
для сооружений, где любой из этих факторов применяется, Вы должны использовать
EnableMMAP off
повредить картографию памяти поставленных файлов. (Примечание: Эта директива может быть отвергнута на в-справочник основании.)
в ситуациях, где Apache 2.0 может игнорировать содержание файла, который будет поставлен - например, служа статическому содержанию файла - это обычно использует ядро sendfile, поддерживают файл, если РОТ поддерживает
sendfile(2)
операция.
на большинстве платформ, используя sendfile улучшает работу, устраняя отдельный прочитанный и посылать механику. Однако, есть случаи, где использование sendfile может вредить стабильности httpd:
некоторые платформы, возможно, нарушили поддержку sendfile, которую строящаяся система не обнаруживала, особенно если наборы из двух предметов были основаны на другой коробке и перемещались в такую машину со сломанным sendfile поддержка.
с УСТАНОВЛЕННЫМИ NFS файлами, ядро может быть неспособным надежно служить файлу сети через свой собственный тайник.
для сооружений, где любой из этих факторов применяется, Вы должны использовать
EnableSendfile off
повредить sendfile поставку содержания файла. (Примечание: Эта директива может быть отвергнута на в-справочник основании.)
до Apacheа 1.3
MinSpareServers
,
MaxSpareServers
, и
StartServers
параметры настройки все имели решительные эффекты на эталонные результаты. В частности Apache требовал периода "ската наверх", чтобы достигнуть множества детей, достаточных, чтобы служить применяемому грузу. После начального порождения
StartServers
дети, только один ребенок в секунду был бы создан, чтобы удовлетворить
MinSpareServers
урегулирование. Так сервер, получаемый доступ 100 одновременными клиентами, используя неплатеж
StartServers
из
5
взял бы секунды заказа 95, чтобы породить достаточно многих детей, чтобы обращаться с грузом. Это работает прекрасное практически на реальных серверах, потому что они не повторно начаты часто. Но делает действительно плохо на точках отсчета, которые могли бы только бежать в течение десяти минут.
одно-в-секунду правило было осуществлено, чтобы избежать затоплять машину с запуском новых детей. Если машина занята, порождая детей, это не может обслужить запросы. Но это имеет такой решительный эффект на воспринятую работу Apacheа, что это должно было быть заменено. На Apacheа 1.3, кодекс расслабит одно-в-секунду правило. Это будет метать икру один, ждать секунда, затем метать икру два, ждать секунда, затем метать икру четыре, и это продолжится по экспоненте, пока это не порождает 32 детей в секунду. Это остановится всякий раз, когда это удовлетворяет
MinSpareServers
урегулирование.
это, кажется, достаточно отзывчивое, который почти ненужно вертеть
MinSpareServers
,
MaxSpareServers
и
StartServers
кнопки. Когда больше чем 4 ребенка порождены в секунду, сообщение испустится к
ErrorLog
. если Вы видите, что много этих ошибок затем рассматривает настройку этих параметров настройки. Использование
mod_status
продукция как гид.
связан, чтобы обработать создание смерть процесса, вызванная
MaxRequestsPerChild
урегулирование. По умолчанию это
0
, что означает, что нет никакого предела числу запросов, обработанных в ребенка. Если ваша конфигурация в настоящее время имеет этот набор к некоторому очень низкому числу, типа
30
, Вы можете хотеть увеличить это значительно. Если Вы управляете SunOS или старой версией Solaris, ограничиваете это
10000
или так из-за утечек памяти.
когда держат-alives, находятся в использовании, дети будут сохранены занятым выполнением ничего ждущего большего количества запросов на уже открытой связи. Неплатеж
KeepAliveTimeout
из
15
секунды пытаются минимизировать этот эффект. Обмен здесь - между полосой пропускания сети и ресурсами сервера. Ни в коем случае не должен Вы поднимать это выше о
60
секунды, как
most of the benefits are lost
.
Apache 2.x поддерживает pluggable модели параллелизма, названные
Multi-Processing Modules
(MPMs). Строя Apacheа, Вы должны выбрать MPM, чтобы использовать. Есть определенные для платформы MPMs для некоторых платформ:
beos
,
mpm_netware
,
mpmt_os2
, и
mpm_winnt
. для общих систем Типа Unix, есть несколько MPMs, чтобы выбрать. Выбор MPM может затронуть скорость и масштабируемость httpd:
worker
MPM использует многократные детские процессы со многими нитями каждый. Каждая нить обращается с одной связью одновременно. Рабочий вообще - хороший выбор для высоких транспортных серверов, потому что это имеет меньший след памяти чем MPM предвилки.
prefork
MPM использует многократные детские процессы с одной нитью каждый. Каждый процесс обращается с одной связью одновременно. На многих системах, предвилка сопоставима в скорости рабочему, но это использует больше памяти. Проект threadless предвилки имеет преимущества перед рабочим в небольшом количестве ситуаций: это может использоваться с "не, пронизывают безопасные" имеющие отношение к третьей стороне модули, и легче отладить на платформах с бедной нитью, отлаживая поддержку.
для получения дополнительной информации о этом и другом MPMs, пожалуйста см. MPM documentation .
так как использование памяти - такое важное рассмотрение в работе, Вы должны попытаться устранить модули что youare не фактически использование. Если Вы строили модули как
DSOs
, устранение модулей - простой вопрос комментария связанное
LoadModule
директива для того модуля. Это позволяет Вам экспериментировать с удалением модулей, и наблюдения, если ваш участок все еще функционирует в их absense.
если, с другой стороны, Вам связали модули статически в ваш Apache набор из двух предметов, Вы будете должны повторно собрать Apacheа, чтобы удалить нежелательные модули.
связанный вопрос, который возникает, вот, конечно, в каких модулях Вы нуждаетесь, и которые Вы не делаете. Ответ здесь, конечно, изменится от одного вебсайта до другого. Однако,
минимальный
список модулей, с которыми Вы можете пройти, имеет тенденцию включать
mod_mime
,
mod_dir
, и
mod_log_config
.
mod_log_config
, конечно, дополнительное, поскольку Вы можете управлять вебсайтом без файлов системного журнала. Этому, однако, не рекомендуют.
некоторые модули, типа
mod_cache
и недавнее развитие строит из MPM рабочего, атомного программного интерфейса приложения АПРЕЛЯ использования. Этот программный интерфейс приложения обеспечивает атомные операции, которые могут использоваться для легкой синхронизации нити.
по умолчанию, АПРЕЛЬ осуществляет эти операции, используя самый эффективный механизм, доступный на каждой целевой платформе РТА/ЦЕНТРАЛЬНОГО ПРОЦЕССОРА. Много современных центральных процессоров, например, имеют инструкцию, которая делает атомный сравнивать-и-обменивать (си-эй-эс) операция в аппаратных средствах. На некоторых платформах, однако, неплатежи АПРЕЛЯ к более медленному, mutex-базирующемуся выполнению атомного программного интерфейса приложения, чтобы гарантировать совместимость старшими моделями центрального процессора, что нехватку такие инструкции. Если Вы строите Apacheа для одной из этих платформ, и Вы планируете бежать только на более новых центральных процессорах, Вы можете выбрать более быстрое атомное выполнение в, строят время, формируя Apacheа с
--enable-nonportable-atomics
выбор:
./buildconf
./configure --with-mpm=worker --enable-nonportable-atomics=yes
--enable-nonportable-atomics
выбор уместен для следующих платформ:
--enable-nonportable-atomics
, однако, АПРЕЛЬ производит кодекс, который использует SPARC v8plus opcode для быстрых аппаратных средств, сравнивать-и-обменивать. Если Вы будете формировать Apacheа с этим выбором, то атомные операции будут более эффективными (учет более низкого использования центрального процессора и более высокого параллелизма), но выполнимое окончание будет бежать только на чипсах UltraSPARC.
--enable-nonportable-atomics
, однако, АПРЕЛЬ производит кодекс, который использует 486 opcode для быстрых аппаратных средств, сравнивать-и-обменивать. Это приведет к более эффективным атомным операциям, но выполнимое окончание будет бежать только на 486 и более поздние чипсы (а не на 386).
если Вы включаете
mod_status
и Вы также устанавливаете
ExtendedStatus On
строя и при управлении Apacheа, затем на каждом Apacheе запроса выполнит два звонка
gettimeofday(2)
(или
times(2)
в зависимости от вашей операционной системы), и (пред1.3) несколько дополнительных звонков
time(2)
. это все сделано так, чтобы сообщение статуса содержало признаки выбора времени. Для самой высокой работы, набора
ExtendedStatus off
(который является неплатежом).
эта секция не была полностью обновлена, чтобы принять во внимание изменения, сделанные в 2.0 версиях Apacheского Сервера HTTP. Часть информации может все еще быть уместной, но пожалуйста используйте это с заботой.
это обсуждает недостаток в программном интерфейсе приложения гнезда Unix. Предположим ваши многократные использования сервера сети
Listen
утверждения, чтобы слушать или на многократных портах или на многократных адресах. Чтобы проверять каждое гнездо, чтобы видеть, является ли связь готовые Apacheские использования
select(2)
.
select(2)
указывает, что гнездо имеет
ноль
или
по крайней мере один
связь, ждущая на этом. Модель Apacheа включает многократных детей, и весь праздный тест на новые связи в то же самое время. Наивное выполнение выглядит кое-что как это (эти примеры не соответствуют кодексу, они изобретены в педагогических целях):
for (;;) {
for (;;) {
fd_set accept_fds;
FD_ZERO (&accept_fds);
for (i = first_socket; i <= last_socket; ++i) {
FD_SET (i, &accept_fds);
}
rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
if (rc < 1) continue;
new_connection = -1;
for (i = first_socket; i <= last_socket; ++i) {
if (FD_ISSET (i, &accept_fds)) {
new_connection = accept (i, NULL, NULL);
if (new_connection != -1) break;
}
}
if (new_connection != -1) break;
}
process the new_connection;
}
но это наивное выполнение имеет серьезную проблему голодания. Вспомните, что многократные дети выполняют эту петлю в то же самое время, и таким образом многократные дети блокируют в
select
когда они - промежуточные запросы. Все те блокированные дети пробудят и возвратятся из
select
то, когда единственный запрос появляется на любом гнезде (число детей, которые пробуждают, изменяется в зависимости от операционной системы и рассчитывающих проблем). Они будут все тогда падать в петлю и пробовать к
accept
связь. Но только один преуспеет (предполагающий, что есть все еще только одна готовая связь), остальные будут
блокированный
в
accept
. это эффективно захватывает тех детей в обслуживание запросам от того одного гнезда и никаких других гнезд, и они застрянут там, пока достаточно многие новые запросы, кажется, на том гнезде не будят их всех. Эта проблема голодания была сначала зарегистрирована в
PR#467
. есть по крайней мере два решения.
одно решение состоит в том, чтобы сделать неблокирование гнезд. В этом случае
accept
не будет блокировать детей, и им будут позволять продолжить немедленно. Но это тратит впустую время центрального процессора. Предположим, что Вы имеете десять праздных детей в
select
, и одна связь прибывает. Тогда девять из тех детей пробудятся, пробовать к
accept
связь, терпите неудачу, и петля назад в
select
, выполнение ничего. Тем временем ни один из тех детей не обслуживает запросы, которые произошли на других гнездах, пока они не рассердились к
select
снова. Повсюду это решение не кажется очень плодотворным, если Вы не имеете так много праздных центральных процессоров (в коробке мультипроцессора), поскольку Вы имеете праздных детей, не вероятную ситуацию.
другое решение, тот, используемый Apache, состоит в том, чтобы преобразовать в последовательную форму вход во внутреннюю петлю. Петля похожа на это (выдвинутые на первый план различия):
for (;;) {
accept_mutex_on ();
for (;;) {
fd_set accept_fds;
FD_ZERO (&accept_fds);
for (i = first_socket; i <= last_socket; ++i) {
FD_SET (i, &accept_fds);
}
rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
if (rc < 1) continue;
new_connection = -1;
for (i = first_socket; i <= last_socket; ++i) {
if (FD_ISSET (i, &accept_fds)) {
new_connection = accept (i, NULL, NULL);
if (new_connection != -1) break;
}
}
if (new_connection != -1) break;
}
accept_mutex_off ();
process the new_connection;
}
The functions
accept_mutex_on
и
accept_mutex_off
осуществить взаимный семафор исключения. Только один ребенок может иметь mutex в любое время. Есть несколько выборов для того, чтобы осуществить эти mutexes. Выбор определен в
src/conf.h
(пред1.3) или
src/include/ap_config.h
(1.3 или позже). Немного архитектуры не имеет никакого выбора захвата сделанным, на этой архитектуре, которую опасное использовать многократный
Listen
директивы.
директива
AcceptMutex
может использоваться, чтобы изменить отобранное mutex выполнение во времени выполнения.
AcceptMutex flock
этот метод использует
flock(2)
запрос системы захватить файл замка (расположенный
LockFile
директива).
AcceptMutex fcntl
этот метод использует
fcntl(2)
запрос системы захватить файл замка (расположенный
LockFile
директива).
AcceptMutex sysvsem
(1.3 или позже), Этот метод использует семафоры SysV-стиля, чтобы осуществить mutex. К сожалению семафоры SysV-стиля имеют некоторые плохие побочные эффекты. Каждый - это, это - возможный Apache, умрет, не моя семафор (см.
ipcs(8)
страница человека). Другой - то, что программный интерфейс приложения семафора учитывает опровержение нападения обслуживания любым CGIs, управляющим под тем же самым uid как webserver (
то есть.
, весь CGIs, если Вы не используете кое-что как
suexec
или
cgiwrapper
). По этим причинам этот метод не используется ни на какой архитектуре кроме IRIX (где предыдущие два предельно дороги на большинстве коробок IRIX).
AcceptMutex pthread
(1.3 или позже) Этот метод использует POSIX mutexes и должен воздействовать на любую архитектуру, осуществляя полный POSIX, пронизывает спецификацию, однако кажется, только воздействуют на Solaris (2.5 или позже), и даже тогда только в определенных конфигурациях. Если Вы экспериментируете с этим, Вы должны не упустить ваше вывешивание сервера и не ответ. Статическое содержание только серверы может работать только прекрасное.
AcceptMutex posixsem
(2.0 или позже), Этот метод использует семафоры POSIX. Собственность семафора не возвращена если нить в процессе, держа mutex segfaults, приводя к вешению сервера сети.
если ваша система имеет другой метод преобразования в последовательную форму, которое не находится в вышеупомянутом списке тогда, это может быть стоящий кодекс добавления для этого до апреля.
другое решение, которое рассмотрели, но никогда не осуществился, состоит в том, чтобы частично преобразовать в последовательную форму петлю - то есть, впустить определенное число процессов. Это только представляло бы интерес на коробках мультипроцессора, где это - возможные многократные дети, мог бежать одновременно, и преобразование в последовательную форму фактически не использует в своих интересах полную полосу пропускания. Это - возможная область будущего исследования, но приоритет остается низким, потому что очень параллельные серверы сети не норма.
идеально Вы должны управлять серверами без многократного
Listen
утверждения, если Вы хотите самую высокую работу. Но продолжают читать.
вышеупомянутое прекрасно и денди для многократных серверов гнезда, но что относительно единственных серверов гнезда? В теории они не должны испытать ни одной из этих тех же самых проблем, потому что все дети могут только блокировать в
accept(2)
пока связь не прибывает, и никакие результаты голодания. Практически это скрывает почти то же самое поведение "вращения", обсужденное выше в решении неблокирования. Путь, которым большинство стеков TCP осуществлено, ядро фактически, пробуждает все процессы, блокированные в
accept
когда единственная связь прибывает. Один из тех процессов получает связь и возвращается к пользовательскому месту, остальные вращаются в ядре и возвращаются, чтобы спать, когда они обнаруживают, что нет никакой связи для них. Это вращение скрыто от кодекса пользовательской земли, но это - там тем не менее. Это может привести к тому же самому грузу-spiking расточительное поведение, что решение неблокирования многократного случая гнезд может.
по этой причине мы нашли, что много архитектуры ведут себя "более приятно", если мы преобразовываем в последовательную форму даже единственный случай гнезда. Таким образом это - фактически неплатеж в почти всех случаях. Сырые эксперименты под Linux (2.0.30 на двойном Pentium про 166 w/128Mb RAM) показали, что преобразование в последовательную форму единственного случая гнезда вызывает меньше чем 3%-ое уменьшение в запросах в секунду по непреобразованному в последовательную форму единственному гнезду. Но непреобразованное в последовательную форму единственное гнездо показало дополнительное 100ms время ожидания на каждом запросе. Это время ожидания - вероятно мыть на линиях долгого пути, и только проблема о ЛВС. Если Вы хотите отвергнуть единственное преобразование в последовательную форму гнезда, Вы можете определить
SINGLE_LISTEN_UNSERIALIZED_ACCEPT
и затем серверы единственного гнезда не будут преобразовывать в последовательную форму вообще.
как обсуждено в draft-ietf-http-connection-00.txt секция 8, для сервера HTTP к надежно осуществить протокол, это нуждается к закрытию в каждом руководстве коммуникации независимо (вспомните, что связь TCP двунаправлена, каждая половина независима от другого). Этот факт часто пропускается другими серверами, но правильно осуществлен в Apacheе на 1.2.
когда эта особенность была добавлена к Apacheу, это вызвало волнение проблем на различных версиях Unix из-за близорукости. Спецификация TCP не заявляет что
FIN_WAIT_2
государство имеет перерыв, но это не запрещает это. На системах без перерыва, Apache 1.2 вызывает много гнезд, прикрепленных навсегда в
FIN_WAIT_2
государство. Во многих случаях этим можно избежать, просто модернизируя к последним участкам TCP/IP, поставляемым продавцом. В случаях, где продавец никогда не выпускал участки (
то есть.
, SunOS4 - хотя люди с исходной лицензией могут исправить это непосредственно), мы решили повредить эту особенность.
есть два способа достигнуть этого. Каждый - выбор гнезда
SO_LINGER
. но поскольку судьба имела бы это, это никогда не осуществлялось должным образом в большинстве стеков TCP/IP. Даже на тех стеках с надлежащим выполнением (
то есть.
, Linux 2.0.31), этот метод, оказывается, более дорогой (cputime) чем следующее решение.
главным образом, Apache осуществляет это в названной функции
lingering_close
(в
http_main.c
). Функция примерно походит на это:
void lingering_close (int s)
{
char junk_buffer[2048];
/* shutdown the sending side */
shutdown (s, 1);
signal (SIGALRM, lingering_death);
alarm (30);
for (;;) {
select (s for reading, 2 second timeout);
if (error) break;
if (s is ready for reading) {
if (read (s, junk_buffer, sizeof (junk_buffer)) <= 0) {
break;
}
/* just toss away whatever is here */
}
}
close (s);
}
это естественно добавляет некоторый расход в конце связи, но это требуется для надежного выполнения. Поскольку HTTP/1.1 становится более распространенным, и все связи постоянны, этот расход амортизируется свыше большего количества запросов. Если Вы хотите играть с огнем, и повреждать эту особенность Вы можете определить
NO_LINGCLOSE
, но этому не рекомендуют вообще. В частности как HTTP/1.1 pipelined постоянные связи входят в использование
lingering_close
является абсолютной потребностью (и
pipelined connections are faster
, таким образом Вы хотите поддержать их).
родитель Apacheа и дети сообщают друг с другом кое через что названное табло. Идеально это должно быть осуществлено в совместно используемой памяти. Для системы операционных, что мы или имеем доступ к, или дались детализированные порты для, это типично, осуществляются, используя совместно используемую память. Остальные неплатеж к использованию на-диске файла. На-диске файл не только медленен, но и это ненадежно (и менее показано). Просмотрите
src/main/conf.h
файл для вашей архитектуры и ищет также
USE_MMAP_SCOREBOARD
или
USE_SHMGET_SCOREBOARD
. определение одного из тех двух (так же как их компаньоны
HAVE_MMAP
и
HAVE_SHMGET
соответственно), позволяет поставляемый кодекс совместно используемой памяти. Если ваша система имеет другой тип совместно используемой памяти, редактируйте файл
src/main/http_main.c
и добавьте крюки, необходимые использовать это в Apacheе. (Пошлите нам назад, участок также нравится.)
если Вы не имеете никакого намерения использовать динамически загруженные модули (Вы вероятно не делаете, если Вы читаете это и настраиваете ваш сервер для каждой последней унции работы), тогда, Вы должны добавить
-DDYNAMIC_MODULE_LIMIT=0
строя ваш сервер. Это спасет RAM, которую это ассигновало только для того, чтобы поддержать динамически загруженные модули.
вот - след запроса системы Apacheа 2.0.38 с MPM рабочего на Solaris 8. Этот след был забран, используя:
truss -l -p
httpd_child_pid
.
-l
выбор говорит связке регистрировать удостоверение личности LWP (легкий процесс - форма Солариса нити ядерного уровня), который призывает каждый запрос системы.
другие системы могут иметь различные утилиты рассмотрения запроса системы, типа
strace
,
ktrace
, или
par
. они все производят подобную продукцию.
в этом следе, клиент просил 10 КБ статический файл от httpd. Следы нестатических запросов или запросов с довольными переговорами выглядят дико отличными (и весьма уродливый в некоторых случаях).
/67: accept(3, 0x00200BEC, 0x00200C0C, 1) (sleeping...) /67: accept(3, 0x00200BEC, 0x00200C0C, 1) = 9
в этом следе, нить слушателя бежит в пределах LWP #67.
accept(2)
преобразование в последовательную форму. На этой специфической платформе, MPM рабочего использует непреобразованный в последовательную форму, принимают по умолчанию, если это не слушает на многократных портах.
/65: lwp_park(0x00000000, 0) = 0 /67: lwp_unpark(65, 1) = 0
после принятия связи, нить слушателя пробуждает нить рабочего, чтобы сделать обработку запроса. В этом следе, нить рабочего, которая обращается с запросом, нанесена на карту к LWP #65.
/65: getsockname(9, 0x00200BA4, 0x00200BC4, 1) = 0
чтобы осуществлять действительных хозяев, Apache должен знать, что местный адрес гнезда имел обыкновение принимать связь. Возможно устранить этот запрос во многих ситуациях (типа того, когда нет никаких действительных хозяев, или когда
Listen
директивы используются, которые не имеют адресов группового символа). Но никакое усилие не было все же предпринято, чтобы сделать эту оптимизацию.
/65: brk(0x002170E8) = 0 /65: brk(0x002190E8) = 0
brk(2)
запросы ассигнуют память от кучи. Редко видеть их в следе запроса системы, потому что httpd использует таможенные лица, ведующие распределением памяти (
apr_pool
и
apr_bucket_alloc
) для большинства обработки запроса. В этом следе, был только что начат httpd, таким образом это должно звонить
malloc(3)
получить блоки сырой памяти, чтобы создать таможенные лица, ведующие распределением памяти.
/65: fcntl(9, F_GETFL, 0x00000000) = 2 /65: fstat64(9, 0xFAF7B818) = 0 /65: getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B910, 2190656) = 0 /65: fstat64(9, 0xFAF7B818) = 0 /65: getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B914, 2190656) = 0 /65: setsockopt(9, 65535, 8192, 0xFAF7B918, 4, 2190656) = 0 /65: fcntl(9, F_SETFL, 0x00000082) = 0
Затем, нить рабочего помещает связь с клиентом (описатель файла 9) в неблокировании способа.
setsockopt(2)
и
getsockopt(2)
запросы - побочный эффект того, как libc Солариса обращается
fcntl(2)
на гнездах.
/65: read(9, " G E T / 1 0 k . h t m".., 8000) = 97
нить рабочего читает запрос от клиента.
/65: stat("/var/httpd/apache/httpd-8999/htdocs/10k.html", 0xFAF7B978) = 0 /65: open("/var/httpd/apache/httpd-8999/htdocs/10k.html", O_RDONLY) = 10
этот httpd формировался с
Options FollowSymLinks
и
AllowOverride None
. таким образом это не нуждается к
lstat(2)
каждый справочник в дорожке, ведущей до требуемого файла, ни чека на
.htaccess
файлы. Это просто звонит
stat(2)
проверять что файл: 1) существует, и 2) - регулярный файл, не справочник.
/65: sendfilev(0, 9, 0x00200F90, 2, 0xFAF7B53C) = 10269
в этом примере, httpd в состоянии послать удар головой ответа HTTP и требуемый файл с единственным
sendfilev(2)
запрос системы. Семантика Sendfile изменяется среди операционных систем. На некоторых других системах, необходимо сделать a
write(2)
или
writev(2)
звонить, чтобы послать удары головой перед запросом
sendfile(2)
.
/65: write(4, " 1 2 7 . 0 . 0 . 1 - ".., 78) = 78
это
write(2)
запрос делает запись запроса в регистрации доступа. Отметьте, что одна вещь, отсутствующая от этого следа - a
time(2)
звонить. В отличие от Apacheа 1.3, Apacheских 2.0 использований
gettimeofday(3)
искать время. На некоторых операционных системах, как Linux или Соларис,
gettimeofday
имеет оптимизированное выполнение, которое не требует так много наверху как типичный запрос системы.
/65: shutdown(9, 1, 1) = 0 /65: poll(0xFAF7B980, 1, 2000) = 1 /65: read(9, 0xFAF7BC20, 512) = 0 /65: close(9) = 0
нить рабочего делает вялое близко связи.
/65: close(10) = 0 /65: lwp_park(0x00000000, 0) (sleeping...)
наконец нить рабочего закрывает файл, который это только что поставило и блоки, пока слушатель не назначает это другая связь.
/67: accept(3, 0x001FEB74, 0x001FEB94, 1) (sleeping...)
тем временем, нить слушателя в состоянии принять другую связь, как только это послало эту связь с нитью рабочего (подчиненный небольшому количеству логики контроля потока в MPM рабочего, которое душит слушателя, если все доступные рабочие заняты). Хотя это не очевидно от этого следа, следующего
accept(2)
может (и обычно делает, при высоких условиях груза) происходят параллельно с обработкой нити рабочего только-принятой связи.