Apache Версия 2.0 Сервера HTTP
этот документ не был полностью обновлен, чтобы принять во внимание изменения, сделанные в 2.0 версиях Apacheского Сервера HTTP. Часть информации может все еще быть уместной, но пожалуйста используйте это с заботой.
начинаясь с Apacheских 1.2 бет, люди сообщают о еще многих связях в государстве FIN_WAIT_2 (как сообщено
netstat
) чем они видели использующие старшие версии. Когда сервер закрывает связь TCP, это посылает пакет с ФИНАНСОВЫМ набором бита клиенту, который тогда отвечает пакетом с набором бита ACK. Клиент тогда посылает пакет с ФИНАНСОВЫМ набором бита к серверу, который отвечает ACK, и связь закрыта. Государство, в котором связь находится в течение периода между тем, когда сервер получает ACK от клиента и сервера, добирается, ФИНАНСОВОЕ от клиента известно как FIN_WAIT_2. См.
TCP RFC
для технических деталей государственных переходов.
государство FIN_WAIT_2 несколько необычно в этом нет никакого перерыва, определенного в стандарте для этого. Это означает, что на многих операционных системах, связь в государстве FIN_WAIT_2 останется вокруг, пока система не перезагружена. Если система не имеет перерыва, и слишком много связей FIN_WAIT_2 растут, это может заполнить место, ассигнованное для того, чтобы хранить информацию о связях и разбить ядро. Связи в FIN_WAIT_2 не связывают процесс httpd.
есть многочисленные причины для этого случай, некоторые из них, возможно, еще не полностью ясны. То, что известно, следует.
несколько клиентов имеют ошибку, которая выскочила, имея дело с постоянными связями (иначе keepalives). Когда связь праздна, и сервер закрывает связь (основанный на
KeepAliveTimeout
), клиент запрограммирован так, чтобы клиент не послал назад ФИНАНСОВОЕ и ACK к серверу. Это означает, что пребывание связи в государстве FIN_WAIT_2 до одного из следующего случается:
если Вы получаете шанс, это означает, что кишащий клопами клиент будет полностью близко связь и выпускать ресурсы на вашем сервере. Однако, есть некоторые случаи, где гнездо полностью никогда не закрывается, типа dialup клиента, разъединяющего от их поставщика перед закрытием клиента. Кроме того, клиент мог бы сидеть праздный в течение многих дней, не делая другую связь, и таким образом может считать ее конец гнезда открытым в течение многих дней даже при том, что это не имеет никакого дальнейшего использования для этого. это - ошибка в браузере или в выполнении его операционной системы TCP.
клиенты, на которых эта проблема была проверена, чтобы существовать:
это, кажется, не проблема на:
ожидается, что много других клиентов имеют ту же самую проблему. Какой клиент должен сделать является периодически чеком его открытое гнездо (а), чтобы видеть, были ли они закрыты сервером, и близко их сторона связи, если сервер закрылся. Эта потребность чека только происходит однажды каждые несколько секунд, и может даже быть обнаружена сигналом РТА на некоторых системах ( например. , Win95 и клиенты NT имеют эту способность, но они, кажется, игнорируют это).
Apache не может избежать этих государств FIN_WAIT_2, если это не повреждает постоянные связи для кишащих клопами клиентов, точно так же, как мы рекомендуем делать для Навигатора 2.x клиенты из-за других ошибок. Однако, нестойкие связи увеличивают общее количество связей, необходимых в клиента и медленный поиск загруженной изображением веб-страницы. Так как нестойкие связи имеют их собственное потребление ресурса и короткий период ожидания после того, как каждое закрытие, занятый сервер, возможно, нуждается в постоянстве, чтобы лучше всего служить его клиентам.
насколько мы знаем, вызванная клиентом проблема FIN_WAIT_2 присутствует для всех серверов, которые поддерживают постоянные связи, включая Apacheа 1.1.x и 1.2.
в то время как вышеупомянутая ошибка - проблема, это не целая проблема. Некоторые пользователи наблюдали Номер FIN_WAIT_2 проблемы с Apache 1.1.x, но с 1.2b, достаточно многие связи растут в государстве FIN_WAIT_2, чтобы разбить их сервер. Наиболее вероятный источник для дополнительных государств FIN_WAIT_2 - названная функция
lingering_close()
который был добавлен между 1.1 и 1.2. Эта функция необходима для надлежащей обработки постоянных связей и любого запроса, который включает содержание в тело сообщения (
например.
, ПОМЕЩАЕТ и ПОСТЫ). То, что это делает, прочитано любые данные, посланные клиентом в течение определенного времени после того, как сервер закрывает связь. Точные причины для того, чтобы делать это несколько усложнены, но вовлекают то, что случается, делает ли клиент запрос в то же самое время, сервер посылает ответ и закрывает связь. Без задержки, клиент мог бы быть вынужден перезагрузить ее буфер входа TCP прежде, чем это имеет шанс прочитать ответ сервера, и таким образом понять, почему связь закрылась. См.
appendix
для большего количества деталей.
кодекс в
lingering_close()
кажется, вызывают проблемы для множества факторов, включая изменение в транспортных образцах, которые это вызывает. Кодекс был полностью рассмотрен, и мы не знаем ни о каких ошибках в этом. Возможно, что есть некоторая проблема в BSD TCP стек, кроме нехватки перерыва для государства FIN_WAIT_2, выставленного
lingering_close
кодекс, который вызывает наблюдаемые проблемы.
есть несколько возможных работ к проблеме, некоторые из которых работают лучше чем другие.
очевидная работа должна просто иметь перерыв для государства FIN_WAIT_2. Это не определено RFC, и могло утверждаться, чтобы быть нарушением RFC, но это широко признано как являющийся необходимым. Следующие системы, как известно, имеют перерыв:
ndd
изменять
tcp_fin_wait_2_flush_interval
, но неплатеж должен быть соответствующим для большинства серверов, и неподходящая настройка может иметь отрицательные воздействия.
SO_LINGER
выбор гнезда, который позволяется Apache. Этот параметр может быть приспособлен при использовании
nettune
изменять параметры, типа
tcp_keepstart
и
tcp_keepstop
. в более поздних пересмотрах, есть явный таймер для связей в FIN_WAIT_2, который может быть изменен; свяжитесь с поддержкой HP деталям.
следующие системы, как известно, не имеют перерыв:
есть a patch available чтобы добавлять перерыв к государству FIN_WAIT_2; это было первоначально предназначено для BSD/OS, но должно быть приспосабливаемым к большинству систем, используя BSD, передающий кодекс. Вы нуждаетесь в ядерном исходном тексте, чтобы быть в состоянии использовать это.
lingering_close()
возможно собрать Apacheа 1.2, не используя
lingering_close()
функция. Это приведет к той секции кодекса, являющегося подобным этому, которое было в 1.1. Если Вы делаете это, знать, что это может вызвать проблемы с, ПОМЕЩАЕТ, ПОСТЫ и постоянные связи, особенно если клиент использует конвейерную обработку. Это сказало, это не хуже чем на 1.1, и мы понимаем, что хранение вашего управления сервера весьма важно.
собирать без
lingering_close()
функция, добавить
-DNO_LINGCLOSE
до конца
EXTRA_CFLAGS
линия в вашем
Configuration
файл, запущенный повторно
Configure
и восстановите сервер.
SO_LINGER
as an alternative to
lingering_close()
на большинстве систем, есть названный выбор
SO_LINGER
это может быть установлено с
setsockopt(2)
. это делает кое-что очень подобное
lingering_close()
, за исключением того, что это сломано на многих системах так, чтобы это вызвало гораздо больше проблем чем
lingering_close
. на некоторых системах, это могло возможно работать лучше, таким образом это может стоить попытку, если Вы не имеете никаких других альтернатив.
чтобы пробовать это, добавить
-DUSE_SO_LINGER -DNO_LINGCLOSE
до конца
EXTRA_CFLAGS
линия в вашем
Configuration
файл, запущенный повторно
Configure
и восстановите сервер.
SO_LINGER
и
lingering_close()
в то же самое время, очень вероятно, сделает очень плохие вещи, нет - также .
точный способ увеличивать их может зависеть от вашего РТА; ищите некоторую ссылку на число "mbufs" или "mbuf группы". На многих системах, это может быть сделано, добавляя линию
NMBCLUSTERS="n"
, где
n
является числом mbuf групп, Вы хотите к вашему ядру config файл и восстановление вашего ядра.
если Вы неспособны сделать любой из вышеупомянутых тогда, Вы должны, как последнее прибежище, повредить KeepAlive. Редактируйте ваш httpd.conf и изменение "KeepAlive На" к "KeepAlive Прочь".
ниже - сообщение от Роя Филдинга, один из авторов HTTP/1.1.
потребность в сервере, чтобы задержаться на гнезде после завершения - отмеченные времена пары в HTTP specs, но не объясненная. Это объяснение основано на обсуждениях между мной непосредственно, Henrik Frystyk, Робертом С. То, Дейвом Рагджеттом, и Джоном К. Моллерай в прихожих MIT, в то время как я был в W3C.
если сервер закрывает сторону входа связи, в то время как клиент посылает данные (или планирует послать данные), то стек TCP сервера будет сигнализировать RST (сброс) назад клиенту. По получении RST, клиент смоет его собственный поступающий буфер TCP назад к un-ACKed пакету, обозначенному аргументом пакета RST. Если сервер послал сообщение, обычно ошибочный ответ, клиенту как раз перед завершением, и клиент получает пакет RST прежде, чем его прикладной кодекс прочитал ошибочное сообщение от его поступающего буфера TCP и прежде, чем сервер получил ACK, посланный клиентом по получении того буфера, то RST смоет ошибочное сообщение прежде, чем приложение - клиент имеет шанс видеть это. Результат состоит в том, что клиента оставляют, думая, что связь не терпела неудачу ни по какой очевидной причине.
есть два условия, при которых это, вероятно, произойдет:
решение во всех случаях состоит в том, чтобы послать ответ, закрыть только пишущуюся половину связи (что закрытие должно сделать), и продолжите читать на гнезде, пока это или не закрыто клиентом (имеющий значение, что это наконец прочитало ответ), или перерыв происходит. Именно это ядро должно сделать, если SO_LINGER установлен. К сожалению, SO_LINGER не имеет никакого эффекта на некоторые системы; на некоторых других системах, это не имеет его собственного перерыва и таким образом доли памяти TCP только нагон до следующей перезагрузки (запланированным или не).
пожалуйста отметьте, что просто удаление, задержанный кодекс не будет решать проблему - это только, перемещает это в различный и намного более твердый, чтобы обнаружить.