Сокет заканчивается в CLOSE_WAIT при использовании Jython

#java #python #sockets #jython

#java #python #сокеты #jython

Вопрос:

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

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

В моей реализации я использую org.python.util.PythonInterpreter, но я также смог воспроизвести его через jyhton CLI. (Такая же проблема возникает как для версии 2.5.3, так и для версии 2.7b2).

Я скачал Jython со следующего URL-адреса. http://search.maven.org/remotecontent ?filepath=org/python/jython-standalone/2.5.3/jython-standalone-2.5.3.jar

Если вы запустите jython CLI в одной оболочке, а затем посмотрите на состояния сокетов в другой, вы увидите, что они навсегда остаются в CLOSE_WAIT .

Для воспроизведения:

  $ java -cp jython-standalone-2.5.3.jar org.python.util.jython
 >>> import urllib2
 >>> urllib2.urlopen('http://www.google.com/notfound')
 >>> urllib2.urlopen('http://www.google.com/notfound')
 >>> urllib2.urlopen('http://www.google.com/notfound')
 >>> urllib2.urlopen('http://www.google.com/notfound')
 >>> urllib2.urlopen('http://www.google.com/notfound')
 

Для проверки сокетов:

  $ netstat -ant|grep CLOSE
 

Был бы признателен, если кто-нибудь сможет помочь мне найти решение этой проблемы.

Я не спрашиваю, что означает CLOSE_WAIT, но как решить проблему.

Как я могу получить дескриптор сокета, чтобы я мог его закрыть.

Такая же проблема с jython версии 2.7b2.

  $ java -cp jython-standalone-2.7-b1.jar org.python.util.jython
 >>> import contextlib, urllib2
 >>> u = 'http://www.google.com/notfound'
 >>> with contextlib.closing(urllib2.urlopen(u)) as x:
 >>>      print x.read()
 

Ответ №1:

Это означает, что удаленная сторона отправила fin в TCP-соединение, но приложение еще не ответило на него, закрыв сокет.

Ответ №2:

Отвечая на мой собственный вопрос. Проблема решена командой разработчиков jython.

http://bugs.jython.org/issue2170

Ответ №3:

Чтобы сокет вышел из close_wait, вам необходимо закрыть сокет fd.

Вы правы в том, что последовательности, подобные приведенным ниже, не накапливают fd в c-python, но накапливают открытые fd в jython. Я думаю, это как-то связано с тем, как работает сборщик мусора jython. В документе jython difference есть примечание, что такие действия, как open().read(), вызовут проблемы — я подозреваю, что это та же основная проблема.

 >>> urllib2.urlopen('http://www.google.com/').close()
>>> urllib2.urlopen('http://www.google.com/').close()
>>> urllib2.urlopen('http://www.google.com/').close()
>>> urllib2.urlopen('http://www.google.com/').close()
>>> urllib2.urlopen('http://www.google.com/').close()
>>> urllib2.urlopen('http://www.google.com/').close()
 

Решение состоит в том, чтобы правильно обработать условие ошибки следующим образом (синтаксис 2.5):;

 try: 
  urllib2.urlopen('http://www.google.com/not-found')
except urllib2.HTTPError, e:
  e.fp.close()
 

Комментарии:

1. Не могли бы вы привести пример, который работает с jython?

2. исправлено, чтобы включить пример

3. Если сервер отвечает «404 не найден», то ваш пример все еще пропускает CLOSE_WAIT. Попробуйте ‘www.google.com/notfound «.