2014-09-28 114 views
1

在我的申请,我送过在线程数request.post()请求。根据我必须发布的数据量,创建的线程数可以达到数百个。Python的请求URLLib3连接池大小

request对象的实际创建是使用requests-oauthlib进行的,该对象在使用时将验证数据插入到request对象中。

我的问题是,当有大量数据并行发送,该日志上充斥着以下消息,且最终没有更多的输入发送到日志:

Connection pool is full. Discarding connection.

我的问题是,随着使用的requests-oauthlib,是有办法specity,也许内post方法本身,连接池的大小,或是否应该阻止这样其他请求可以创造更多前完成?我问这个,因为在使用的requests-oauthlib,这将是非常棘手,构建一个自定义request对象,并要求requests-oauthlib使用它。

一两件事,我曾尝试如下,但它没有任何效果 - 我继续得到警告:

import requests 
s = requests.Session() 
a = requests.adapters.HTTPAdapter(pool_block=True) 
s.mount('http://', a) 
s.mount('https://', a) 

更新 - 线程现在正在以可控的方式产生。

with futures.ThreadPoolExecutor(max_workers=10) as executor: 
    executor.submit(function, args) 

回答

1

阻断请求,以便只有其中N个最简单的方法是尝试使用连接池一次是一次只创建n个。

做到这一点的最简单的方法是用N个线程服务中号的请求队列的池,而不是为每个请求单独的线程。如果您使用的是Python 3.2+,则使用concurrent.futures库很容易 - 事实上,它与第一个ThreadPoolExecutor示例几乎相同,只是您使用requests而不是urllib。如果你不使用3.2+,那么stdlib模块的backport命名为futures,它提供了相同的功能......我认为2.6,但不要在此引用我(PyPI目前处于关闭状态)。

可能还有一个更简单的解决方案:有一个名为requests-futures的第三方库,我从名字中猜测(再次,PyPI下来...),以某种方式将它包装起来。

您可能还想考虑使用诸如grequests之类的东西在一个线程中使用gevent greenlet执行所有操作,但就代码而言,使用线程池并不会有太大的不同。

+0

谢谢您的回答。我已经实现了你所说的使用ThreadPoolExecutor(我在Python 2.7中)并将其添加到我原来的问题中。你能否确认这是你的想法?我不再获得超过连接池的警告,我非常高兴与如何控制的请求被被红牌罚下。谢谢你的帮助! – Cristian 2014-09-28 13:20:24

+1

@克里斯蒂安:确切地说;很高兴它对你有效。 – abarnert 2014-09-28 21:00:38