#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.
Ответ №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 «.