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