Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

Ответ 2

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

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

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

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

Вам следует избегать этого, делая несколько вещей.

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

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

connection: keep-alive

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

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

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

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

Посмотрите на это [link] [1], которые объясняют, что такое keep-alive.

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

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

Ответ 3

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

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

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

Ответ 4

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

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

Ответ 5

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

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

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

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

Ответ 6

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