Cherpy не закрывает сокеты

Я использую 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)

Заранее спасибо!


person NeoAnderson    schedule 21.10.2008    source источник
comment
Если бы вы могли создать и опубликовать минимальный репродуктор, это было бы полезно; если мы не можем воспроизвести в нашей собственной среде, любые предположения являются догадками.   -  person Charles Duffy    schedule 23.10.2008


Ответы (1)


Я предполагаю, что вы храните (в памяти) некоторый фрагмент данных, который имеет ссылку на сокет; например, если вы храните объекты запроса где-нибудь, это, скорее всего, сделает это.

Последний шанс для сокетов быть закрытым — это когда они удаляются сборщиком мусора; если вы делаете что-то, что помешает сборке мусора добраться до них, это ваша проблема. Я предлагаю вам попробовать воспроизвести программу Hello World, написанную на CherryPy; если вы не можете воспроизвести там, вы знаете, что это в вашем коде - ищите места, где вы сохраняете информацию, которая может (прямо или иначе) ссылаться на сокет.

person Charles Duffy    schedule 21.10.2008
comment
Нет, я не сохраняю никакой информации. На самом деле мой сервер доступен только для чтения. Никаких записей не происходит, кроме сокета. Розетки изначально собраны достаточно хорошо. Эта проблема приходит с течением времени. - person NeoAnderson; 21.10.2008
comment
Опять же, можете ли вы воспроизвести это с помощью Hello World? - person Charles Duffy; 22.10.2008
comment
Кстати, когда я говорю о сохранении любой информации, я имею в виду в памяти, а не на диске или в хранилище базы данных. - person Charles Duffy; 22.10.2008
comment
Опять же, можете ли вы воспроизвести это с помощью Hello World? (Есть веб-сайт стартапа, в котором я владею некоторыми акциями, созданного несколько лет назад с использованием CherryPy; он выдает много обращений только из-за скриптовых процессов, и, насколько мне известно, они никогда не сталкивались с этой проблемой) . - person Charles Duffy; 23.10.2008