cherrypy不关闭套接字

3 投票
1 回答
2908 浏览
提问于 2025-04-11 18:28

我正在使用cherrypy作为我的网页服务器。它的性能对我的应用来说很好,但有一个非常大的问题。cherrypy在运行几个小时后崩溃,提示无法创建一个socket,因为打开的文件太多了:

[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..

我试着弄清楚发生了什么。我的应用并没有打开任何文件或socket等。我的文件只打开了几个berkeley数据库。我进一步调查了这个问题。我查看了我的cherrypy进程(ID为4536)在/proc/4536/fd/中的文件描述符。

最开始有新的socket被创建并且正常关闭,但过了一个小时后,我发现大约有509个socket没有被关闭。所有的socket都处于CLOSE_WAIT状态。我是通过以下命令获得这些信息的:

netstat -ap | grep "4536" | grep CLOSE_WAIT | wc -l

CLOSE_WAIT状态意味着远程客户端已经关闭了连接。那么,为什么cherrypy不关闭这些socket并释放文件描述符呢?我该如何解决这个问题?

我尝试调整了以下设置:

cherrypy.config.update({'server.socketQueueSize': '10'})

我以为这会限制任何时候打开的socket数量为10,但实际上根本没有效果。这是我设置的唯一配置,其他的配置都是默认值。

有人能帮我解释一下吗?你觉得这是cherrypy的一个bug吗?我该如何解决这个问题?有没有办法让我自己关闭这些socket?

以下是我的系统信息:

CherryPy-3.1.0

python 2.3.4

Red Hat Enterprise Linux ES release 4 (Nahant Update 7)

提前谢谢大家!

1 个回答

4

我想你可能在内存中存储了一些数据,这些数据里有一个指向套接字的引用;如果你把请求对象存储在某个地方,比如说,那可能就是问题所在。

套接字最后被关闭的机会是在它们被垃圾回收的时候;如果你做了什么事情让垃圾回收无法处理它们,那就是你的问题。我建议你试着用CherryPy写一个Hello World程序来重现这个问题;如果在那里面无法重现,那就说明问题出在你的代码里——找找看有没有地方在保存信息,而这些信息可能(直接或间接)引用了套接字。

撰写回答