Назад | Перейти на главную страницу

Как НЕ получать столько подключений apache CLOSE_WAIT?

netstat показывает, что 153 соединения находятся в состоянии CLOSE_WAIT. Связи никогда не закрываются. Таким образом, сверхурочно сервер заполняется этими соединениями, которые заполняют оперативную память, и теперь веб-сайты не загружаются.

netstat показывает многие из следующих:

tcp      160      0 my_server_name:http         my_server_name:51584        CLOSE_WAIT
tcp      160      0 my_server_name:http         my_server_name:51586        CLOSE_WAIT
tcp        0      0 my_server_name:http         my_server_name:50827        CLOSE_WAIT
tcp        0      0 my_server_name:http         my_server_name:50830        CLOSE_WAIT
tcp      312      0 my_server_ip.static.:http rate-limited-proxy-72:61249 CLOSE_WAIT
tcp      382      0 my_server_ip.static.:http b3090792.crawl.yahoo.:58663 CLOSE_WAIT
tcp      382      0 my_server_ip.static.:http b3090792.crawl.yahoo.:34655 CLOSE_WAIT
tcp      382      0 my_server_ip.static.:http b3090792.crawl.yahoo.:56681 CLOSE_WAIT
tcp      382      0 my_server_ip.static.:http b3090792.crawl.yahoo.:40829 CLOSE_WAIT
tcp      576      0 my_server_ip.static.:http b3090792.crawl.yahoo.:38278 CLOSE_WAIT
tcp       47      0 my_server_ip.static.:http 203.200.5.143.ill-bgl:49379 CLOSE_WAIT

Если я посмотрю на appache error_log, до того, как возникнет ситуация CLOSE_WAIT, появятся строки, подобные следующим

[warn] child process 15670 still did not exit, sending a SIGTERM
[error] child process 15670 still did not exit, sending a SIGKILL
[notice] child pid 3511 exit signal Segmentation fault (11)

Моя установка Apache 2.2.3 RAM 1024 МБ (пакетная 2048 МБ) CentOS версии 5.3 (Final) с двумя установками WPMU 2.9.2

Задний план

Socket переходит в состояние CLOSE_WAIT, когда удаленный конец завершает соединение, отправляя пакет с установленным флагом FIN. Затем в этом состоянии он ожидает, пока локальное приложение close() сокет, а затем отправляет свой собственный FIN клиенту и переводит сокет в состояние LAST_ACK. Смотрите также диаграмма перехода состояний TCP и RFC 793.

Также обратите внимание, что CLOSE_WAIT не имеет отношения к печально известному TIME_WAIT, поскольку первый происходит на пассивной закрытой ветви (удаленный конец закрывается первым), а второй - на активной закрытой ветви (локальный конец закрывается первым).

Описание проблемы

Обычно соединения переходят с CLOSE_WAIT на LAST_ASK довольно быстро. Если удаленный адрес и порт продолжают быстро меняться, то достаточное количество соединений в состоянии CLOSE_WAIT может быть просто следствием того, что очень большое количество соединений открыто, используется и закрывается. Следует проверить производительность системы, но само по себе это не является проблемой.

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

С другой стороны, если удаленный адрес и порт остаются постоянными, а количество соединений в состоянии CLOSE_WAIT продолжает расти, это, скорее всего, указывает на проблему с приложением. Это частный случай ошибки утечки ресурсов: приложение пропускает открытые сокеты вместо того, чтобы своевременно их закрывать. Это потребляет память ядра и в конечном итоге приведет к сбою приложения, когда оно достигнет максимального числа открытых файловых дескрипторов.

Однако обратите внимание, что скорость утечки может быть медленной. Часто такие ошибки возникают в результате неспособности обработать исключение в середине запроса, прерывая поток выполнения в рабочем потоке, что впоследствии может помешать очистке (включая закрытие сокета). Оскорбительное исключение может возникать редко.

Временное решение

Временное решение проблемы - увеличить ограничения на дескрипторы открытых файлов и периодически перезапускать приложение, когда (желательно раньше) проблема начинает влиять на производительность. Обратите внимание, что это может непреднамеренно повлиять на открытые в данный момент соединения. Наличие резервных серверов и балансировка нагрузки могут помочь скрыть проблему от пользователей.

Постоянное решение

Постоянное решение проблемы - развернуть версию приложения без ошибки. Степень, в которой временное решение наносит вред пользователям и бизнесу, готовность исправленного выпуска и состояние последнего рабочего выпуска помогают решить, следует ли откатиться к последней рабочей версии приложения или дождаться исправления.