我在这里做的事情完全超出了我的舒适区,所以希望我只是做了一些愚蠢的事情。
我有一个 Amazon EC2 实例,用于运行专用数据库,该数据库通过 Tomcat 内部提供 REST API 的 Web 应用程序进行控制。在同一台服务器上,我正在运行一个 Python 脚本,该脚本使用 Requests 库对数据库进行数十万个简单查询(我认为不可能合并这些查询,尽管我接下来会尝试这样做。 )
问题:运行脚本一段时间后,我的 SSH 终端突然出现管道损坏错误。当我尝试使用 SSH 重新登录时,我不断收到“操作超时”错误。因此,我什至无法重新登录来终止 Python 进程,而必须重新启动 EC2 实例(这是一个巨大的痛苦,特别是因为我使用的是临时存储)
我的理论是,每次 requests 进行 REST 调用时,它都会激活 Python 和 Tomcat 之间的一对端口,但完成后它永远不会关闭这些端口。因此,python 不断尝试获取越来越多的端口,最终要么以某种方式获取并锁定 SSH 端口(将我引导关闭),要么它只是使用所有端口,从而导致网络系统以某种方式崩溃(正如我所说,我我无法理解。)
我也尝试使用httplib2
,并且遇到了类似的问题。
有什么想法吗?如果我的端口理论是正确的,有没有办法在完成后强制请求交出端口?或者至少有一种方法可以告诉 Ubuntu 禁止 SSH 端口,这样我至少可以重新登录并终止进程?
或者是否有某种使用 Python 进行大量非常简单的 REST 调用的最佳实践?
编辑:
已解决...执行:
s = requests.session()
s.config['keep_alive'] = False
在发出请求之前,强制请求在完成后释放连接。
最佳答案
我的猜测:
https://github.com/kennethreitz/requests/blob/develop/requests/models.py#L539将 conn 设置为 connectionpool.connection_from_url(url)
这导致 https://github.com/kennethreitz/requests/blob/develop/requests/packages/urllib3/connectionpool.py#L562 ,这导致 https://github.com/kennethreitz/requests/blob/develop/requests/packages/urllib3/connectionpool.py#L167 .
def _new_conn(self):
"""
Return a fresh :class:`httplib.HTTPConnection`.
"""
self.num_connections += 1
log.info("Starting new HTTP connection (%d): %s" %
(self.num_connections, self.host))
return HTTPConnection(host=self.host, port=self.port)
我建议将一个处理程序连接到该记录器,并监听与该记录器匹配的行。这会让您看到正在创建多少个连接。
关于Python请求不清理连接导致端口溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11853418/