Я использую Cherrypy в качестве веб-сервера. Это дает хорошую производительность для моего приложения, но с ним очень большая проблема. Cherrypy аварийно завершает работу через пару часов, заявляя, что не может создать сокет, поскольку открыто слишком много файлов:
[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..
Я пытался понять, что происходит. Мое приложение не открывает никаких файлов или сокетов и т. д. Мой файл открывает только пару Беркли БД. Я исследовал эту проблему дальше. Я видел файловые дескрипторы, используемые моим вишневым процессом с идентификатором 4536 в / proc / 4536 / fd / Первоначально были созданы и правильно очищены новые сокеты, но через час я обнаружил, что около 509 сокетов не были очищены. Все сокеты были в состоянии CLOSE_WAIT. Я получил эту информацию с помощью следующей команды:
netstat -ap | grep "4536" | grep CLOSE_WAIT | wc -l
Состояние CLOSE_WAIT означает, что удаленный клиент закрыл соединение. Почему Cherrypy не закрывает сокет и не освобождает файловые дескрипторы? Что я могу сделать, чтобы решить проблему?
Я пробовал поиграть со следующим:
cherrypy.config.update({'server.socketQueueSize': '10'})
Я думал, что это ограничит количество открытых в любое время сокетов до 10, но это было неэффективно. Это единственная конфигурация, которую я установил, поэтому остальные конфигурации сохраняют свои значения по умолчанию.
Может ли кто-нибудь пролить свет на это? Как вы думаете, это ошибка в Cherrypy? Как я могу это решить? Могу ли я сам закрыть эти сокеты?
Ниже приводится информация о моей системе:
CherryPy-3.1.0
Python 2.3.4
Red Hat Enterprise Linux ES, выпуск 4 (обновление Nahant 7)
Заранее спасибо!






Я предполагаю, что вы храните (в памяти) некоторую часть данных, которая ссылается на сокет; например, если вы храните объекты запроса где угодно, это, скорее всего, сработает.
Последний шанс закрытия сокетов - это сборка мусора; Если вы делаете что-то, что может помешать им попасть в сборщик мусора, в этом ваша проблема. Я предлагаю вам попытаться воспроизвести с помощью программы Hello World, написанной на CherryPy; если вы не можете воспроизвести там, вы знаете, что это в вашем коде - ищите места, где вы сохраняете информацию, которая может (прямо или иначе) ссылаться на сокет.
Нет, я не настаиваю на какой-либо информации. Фактически мой сервер предназначен только для чтения. Никаких записей, кроме сокета, не происходит. Розетки изначально собраны достаточно хорошо. Эта проблема возникает со временем.
Опять же - вы можете воспроизвести это с помощью Hello World?
Кстати, когда я говорю «сохранение любой информации», я имею в виду в памяти, а не на диске или в хранилище базы данных.
Опять же - вы можете воспроизвести это с помощью Hello World? (Есть веб-сайт стартапа, на котором я держу несколько акций, созданный несколько лет назад с использованием CherryPy; он заполняет много обращений только от только скриптовых процессов, и AFAIK они никогда не сталкивались с этой проблемой).
Если бы вы могли построить и опубликовать минимальный репродуктор, это было бы полезно; если мы не можем воспроизвести в нашей собственной среде, любые предположения являются предположениями.