【问题标题】:Python Requests URLLib3 Connection Pool SizePython 请求 URLLib3 连接池大小
【发布时间】:2014-09-28 09:28:16
【问题描述】:

在我的应用程序中,我在线程中发送了几个request.post() 请求。根据我必须发布的数据量,创建的线程数可能有数百个。

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

我的问题是,当并行发送大量数据时,日志被以下消息淹没,最终没有更多的输入发送到日志:

Connection pool is full. Discarding connection.

我的问题是,使用requests-oauthlib,有没有办法指定,可能在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)

【问题讨论】:

    标签: python multithreading python-requests urllib


    【解决方案1】:

    阻止请求中只有 N 个尝试同时使用连接池的最简单方法是一次只创建 N 个。

    最简单的方法是使用 N 个线程池为 M 个请求的队列提供服务,而不是为每个请求使用一个单独的线程。如果您使用的是 Python 3.2+,则使用 concurrent.futures 库非常容易 — 实际上,它与第一个 ThreadPoolExecutor 示例几乎相同,只是您使用的是 requests 而不是 urllib。如果您不使用 3.2+,则有一个名为 futures 的 stdlib 模块的向后移植,它提供了相同的功能回到......我认为是 2.6,但不要引用我的话(PyPI 目前已关闭)。

    可能有一个更简单的解决方案:有一个名为 requests-futures 的第三方库,我猜从名称(再次,PyPI 下降......)以某种方式为您包装了它。

    您可能还想考虑使用grequests 之类的东西在一个带有gevent greenlets 的线程中完成所有操作,但就您的代码而言,这与使用线程池没有显着不同.

    【讨论】:

    • 感谢您的回答。我已经使用 ThreadPoolExecutor (我在 Python 2.7 上)实现了你所说的,并将它添加到我原来的问题中。你能确认这是你的想法吗?我不再收到超出连接池的警告,并且对发送请求的控制方式感到非常满意。感谢您的帮助!
    猜你喜欢
    • 2016-02-14
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2014-06-24
    • 1970-01-01
    • 2011-08-13
    • 2015-12-19
    • 2018-02-18
    相关资源
    最近更新 更多