Устранение неполадок соединений, застрявших в состоянии ожидания CLOSE

У меня есть приложение Java, работающее в WebLogic 11g на Windows, которое через несколько дней перестает отвечать. Один подозрительный симптом, который я заметил, заключается в том, что большое количество соединений (около 3000) появляется в netstat со статусом CLOSE_WAIT, даже когда сервер простаивает. Поскольку сервер приложений управляет клиентскими подключениями, я не уверен, что это вызывает. Мы также делаем несколько вызовов веб-служб, которые возвращаются на тот же сервер, но я считаю, что эти соединения получают правильно закрыт. Что еще может вызвать это и как можно устранить такую проблему?

6 ответов


у меня была такая же проблема, и я изучал сокеты, чтобы избавиться от этой проблемы.

позвольте мне сказать несколько слов, но прежде я должен сказать, что я не программист Java.

Я не буду объяснять, что такое close_wait, так как Брайан Уайт уже сказал Все, что нужно сказать.

чтобы избежать close_wait, вам нужно убедиться, что ваш сервер не закрывает соединение после того, как он отправляет ответ, потому что тот, кто отключается первым, застревает close_wait состояние и TIME_WAIT, прежде чем. Итак, если ваш сервер застрял в close_wait, он говорит мне, что он отключается после отправки ответа.

вы должны избежать этого, сделав несколько вещей.

1-Если ваше клиентское приложение не использует протокол http 1.1, вы должны установить его для использования из-за 'keep-alive опция заголовка http.

2-Если клиент работает с http 1.1 и это не работает, или, если вы должны использовать http 1.0, вы должны установить соединение свойство заголовка запроса:

connection: keep-alive

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

3-в вашем клиенте повторно используйте сокет. Если вы создаете много клиентов сокетов в цикле, например, вы должны создать сокет один раз, и они используют его каждый раз, когда вам нужно отправить запрос. Подход, который я использовал в своем приложении, - иметь сокет пул и получите один доступный сокет (который уже подключен к серверу и имеет свойство keep-alive). Затем я использую его, и когда я закончу, я положу его обратно в бассейн для повторного использования.

4 - Если вам действительно нужно отключить после отправки запроса, убедитесь, что ваш клиент это и сохранить connection: keep-alive.

и да, у вас могут возникнуть проблемы, когда у вас много close_waits или time_waits на стороне сервера.

проверить это [ссылке][1], которые объясняют, что keep-alive - это.

Я надеюсь, это было полезно. С этими вещами мне удалось решить свою проблему.

[1]: http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01.html#Persistent подключения


CLOSE_WAIT - Это состояние, в котором находится локальный компьютер состояния TCP, когда удаленный хост отправляет FIN (закрывает его соединение), но локальное приложение не сделало то же самое и отправило ответ FIN. На данный момент локальная машина все еще может отправлять данные, хотя клиент не может их получить (если только он не сделал только половину закрытия соединения).

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

Я мало знаю о Java и ничего о WebLogic, но я полагаю, что возможно, что приложение не обрабатывает ошибку чтения должным образом и, таким образом, никогда не закрывает соединение.


на CLOSE_WAIT статус означает, что другая сторона инициировала закрытие соединения, но приложение на локальной стороне еще не закрыло сокет.

похоже, у вас есть ошибка в вашем локальном приложении.


проблема заключалась в ошибке, вызванной установкой" Use JSSE SSL " в true в webLogic. Использование собственной реализации SSL WebLogic вместо JSSE не является проблемой для нашего приложения, поэтому я просто снял эту настройку, и проблема исчезла.


Я нашел эту цитату о close_wait pileups: "что-то либо мешает прогрессу происходят в сеансе HTTP (мы застряли, поэтому никогда не заканчиваем вызов close), или была введена ошибка, которая предотвращает закрытие сокета. Есть несколько способов это может произойти."

подумайте: есть ли способ, которым ваше приложение может застрять при обработке запроса? Или сама WebLogic?

Examine: можете ли вы сделать Java-дампы потоков (kill-SIGQUIT может быть используется для этого в Oracle JVM для Linux), чтобы попытаться увидеть, действительно ли какой-либо из ваших потоков застревает?

Проверьте клиентскую сторону: Во-первых, узнайте IP-адрес или имя хоста клиентов, которые подключены к сокетам CLOSE_WAIT. Затем посмотрите, не происходит ли что-нибудь подозрительное с этими клиентами.


Это может означать, что вы не вызываете "закрыть" в сокете из вашего вызова accept ().