CherryPy未关闭套接字

3

我正在使用cherrypy作为Web服务器。它为我的应用程序提供了良好的性能,但是它有一个非常大的问题。几个小时后,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..

我试图找出发生了什么。我的应用程序不打开任何文件或套接字等。我的文件只打开几个伯克利数据库。我进一步调查了这个问题。我在/proc/4536/fd/中看到了由我的cherrypy进程使用的文件描述符,其id为4536。 最初创建了新的套接字并正确清除了它们,但是一个小时后,我发现它有大约509个未被清理的套接字。所有套接字都处于CLOSE_WAIT状态。我使用以下命令获取了这些信息:

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

CLOSE_WAIT状态表示远程客户端已关闭连接。为什么Cherrypy没有关闭套接字并释放文件描述符呢?我该怎么解决这个问题?
我尝试了以下方法:
cherrypy.config.update({'server.socketQueueSize': '10'})

我认为这将限制同时打开的套接字数量为10,但它根本没有起作用。这是我唯一设置的配置,因此其余配置保持默认值。

有人可以解释一下吗?你认为这是CherryPy中的bug吗?我该如何解决?是否有办法自己关闭这些套接字?

以下是我的系统信息:

CherryPy-3.1.0

python 2.3.4

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

谢谢!


1
如果您能够构建并发布一个最小的复现程序,那将非常有用;除非我们能够在自己的环境中重现,否则任何建议都只是猜测。 - Charles Duffy
1个回答

4
我想您正在存储(在内存中)一些与套接字有关的数据; 如果您在任何地方存储请求对象,那么可能会这样做。套接字最后一次关闭的机会是在它们被垃圾回收时; 如果您正在执行任何防止垃圾回收到达它们的操作,则存在问题。我建议您尝试使用CherryPy编写的Hello World程序进行再现; 如果您无法在那里重现,那么您知道问题出在您的代码上--查找可能(直接或间接地)引用套接字的信息的位置。

不,我没有持久化任何信息。事实上,我的服务器是只读服务器。除了套接字之外,没有任何写操作发生。最初套接字已经收集得足够好了。这个问题随着时间的推移而出现。 - NeoAnderson
你能用Hello World再次重现它吗? - Charles Duffy
顺便说一下,当我说“持久化任何信息”时,我的意思是在内存中,而不是在磁盘或数据库存储中。 - Charles Duffy
你能用“Hello World”再重现一遍吗?(我持有某个初创公司的股份,他们几年前使用CherryPy构建了一个网站;仅来自脚本过程的访问量就非常高,据我所知他们从未遇到过这个问题)。 - Charles Duffy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接