Я использую Cherpy в качестве веб-сервера. Это дает хорошую производительность для моего приложения, но с ним есть очень большая проблема. Cherpy падает через пару часов, заявляя, что не может создать сокет, так как открыто слишком много файлов:
[21/Oct/2008:12:44:25] ENGINE HTTP Server
cherrypy._cpwsgi_server.CPWSGIServer(('0.0.0.0', 8080)) shut down
[21/Oct/2008:12:44:25] ENGINE Stopped thread '_TimeoutMonitor'.
[21/Oct/2008:12:44:25] ENGINE Stopped thread 'Autoreloader'.
[21/Oct/2008:12:44:25] ENGINE Bus STOPPED
[21/Oct/2008:12:44:25] ENGINE Bus EXITING
[21/Oct/2008:12:44:25] ENGINE Bus EXITED
Exception in thread HTTPServer Thread-3:
Traceback (most recent call last):
File "/usr/lib/python2.3/threading.py", line 436, in __bootstrap
self.run()
File "/usr/lib/python2.3/threading.py", line 416, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib/python2.3/site-packages/cherrypy/process/servers.py", line 73, in
_start_http_thread
self.httpserver.start()
File "/usr/lib/python2.3/site-packages/cherrypy/wsgiserver/__init__.py", line 1388, in start
self.tick()
File "/usr/lib/python2.3/site-packages/cherrypy/wsgiserver/__init__.py", line 1417, in tick
s, addr = self.socket.accept()
File "/usr/lib/python2.3/socket.py", line 167, in accept
sock, addr = self._sock.accept()
error: (24, 'Too many open files')
[21/Oct/2008:12:44:25] ENGINE Waiting for child threads to terminate..
Я пытался понять, что происходит. Мое приложение не открывает ни один файл, ни один сокет и т. д. Мой файл открывает только пару баз данных Беркли. Я исследовал этот вопрос дальше. Я видел файловые дескрипторы, используемые моим процессом cherrypy с идентификатором 4536 в /proc/4536/fd/. Первоначально были созданы и правильно очищены новые сокеты, но через час я обнаружил, что в нем было около 509 сокетов, которые не были очищены. Все сокеты находились в состоянии CLOSE_WAIT. Я получил эту информацию с помощью следующей команды:
netstat -ap | grep "4536" | grep CLOSE_WAIT | wc -l
Состояние CLOSE_WAIT означает, что удаленный клиент закрыл соединение. Почему Cherpy не закрывает сокет и не освобождает файловые дескрипторы? Что я могу сделать, чтобы решить проблему?
Я пытался играть со следующим:
cherrypy.config.update({'server.socketQueueSize': '10'})
Я думал, что это ограничит количество открытых сокетов до 10, но это совсем не эффективно. Это единственная конфигурация, которую я установил, поэтому остальные конфигурации сохраняют значения по умолчанию.
Может ли кто-нибудь пролить свет на это? Как вы думаете, это ошибка в Cherpy? Как я могу решить эту проблему? Есть ли способ закрыть эти сокеты самостоятельно?
Ниже приведена информация о моей системе:
CherryPy-3.1.0
питон 2.3.4
Red Hat Enterprise Linux ES, выпуск 4 (обновление Nahant 7)
Заранее спасибо!