1

我在这里做的事情完全超出了我的舒适区,所以希望我只是在做一些愚蠢的事情。

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

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

我的理论是,每次请求进行 REST 调用时,它都会激活 Python 和 Tomcat 之间的一对端口,但完成后它永远不会关闭端口。所以 python 一直在尝试获取越来越多的端口,最终要么以某种方式抢走并锁定 SSH 端口(让我关闭),要么它只使用所有端口,导致网络系统以某种方式崩溃(正如我所说,我我已经超出了我的深度。)

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

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

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

编辑:

解决...做:

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

在发出请求以强制请求完成后释放连接之前。

4

2 回答 2

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/请求/包/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)

我建议将处理程序连接到该记录器,并侦听与该记录器匹配的行。这会让你看到有多少连接被创建。

于 2012-08-07T21:58:13.653 回答
0

想通了...请求对连接有一个默认的“保持活动”策略,您必须通过执行显式覆盖该策略

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

在您提出请求之前。

从文档:

""" Keep-Alive 好消息——多亏了 urllib3,在会话中保持活动是 100% 自动的!您在会话中发出的任何请求都将自动重用适当的连接!

请注意,只有在读取所有主体数据后,连接才会释放回池中以供重用;请务必将 prefetch 设置为 True 或读取 Response 对象的 content 属性。

如果您想禁用 keep-alive,只需将 keep_alive 配置设置为 False:

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

此处的请求中可能存在一个细微的错误,因为我正在读取 .text 和 .content 属性,但它仍然没有释放连接。但是明确地将“保持活力”传递为 false 解决了这个问题。

于 2012-08-08T07:30:25.390 回答