Python请求没有清理连接和导致端口溢出?

时间:2012-08-07 20:15:18

标签: python rest networking ssh python-requests

我在这里做了一些相当于我舒适区的事情,所以希望我只是在做一些愚蠢的事情。

我有一个Amazon EC2实例,我用它来运行一个专门的数据库,该数据库是通过提供REST API的Tomcat内部的webapp来控制的。在同一台服务器上,我正在运行一个Python脚本,该脚本使用Requests库对数据库进行数十万次简单查询(我不认为可以合并查询,但我会尝试下一步。 )

问题:运行脚本一段时间后,我的SSH终端上突然出现损坏管道错误。当我尝试使用SSH重新登录时,我不断收到“操作超时”错误。所以我甚至无法重新登录以终止Python进程,而是必须重新启动EC2实例(这是一个巨大的痛苦,特别是因为我正在使用临时存储)

我的理论是,每次请求进行REST调用时,它都会激活Python和Tomcat之间的一对端口,但是当它完成时它永远不会关闭端口。所以python一直试图抓住越来越多的端口,并最终以某种方式抓住并锁定SSH端口(启动我),或者它只是使用所有端口,这导致网络系统以某种方式废弃(正如我所说,我超出我的深度。)

我也尝试使用httplib2,并遇到了类似的问题。

有什么想法吗?如果我的港口理论是正确的,有没有办法强制要求在港口完成后放弃港口?或者至少有一种方法告诉Ubuntu保持SSH端口不受限制,这样我至少可以重新登录并终止进程?

或者是否有一些使用Python进行大量非常简单的REST调用的最佳实践?

编辑:

...解决做:

s = requests.session()
s.config['keep_alive'] = False

在发出请求之前强制请求释放连接之前。

2 个答案:

答案 0 :(得分:2)

我的推测:

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

这最终导致https://github.com/kennethreitz/requests/blob/develop/requests/packages/urllib3/connectionpool.py#L185

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)

我建议将处理程序挂钩到该记录器,然后侦听与该记录器匹配的行。这可以让你看到正在创建多少个连接。

答案 1 :(得分:0)

想出来......请求在连接上有一个默认的“保持活动”策略,你必须通过

明确覆盖它们
s = requests.session()
s.config['keep_alive'] = False
在提出请求之前

来自doc:

“”” 活着 好消息 - 感谢urllib3,keep-alive在会话中100%自动!您在会话中发出的任何请求都将自动重用相应的连接!

请注意,只有在读取了所有正文数据后,才会将连接释放回池中以便重复使用;一定要将prefetch设置为True或读取Response对象的content属性。

如果你想禁用keep-alive,你可以简单地将keep_alive配置设置为False:

s = requests.session() s.config ['keep_alive'] = False “”“

此处的请求中可能存在一个微妙的错误,因为我正在读取.text和.content属性,但它仍然没有释放连接。但明确地将“保持活着”作为错误修正了问题。