Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以更改Python';的连接池大小吗;s";“请求”;模块?_Python_Multithreading_Request_Python Requests - Fatal编程技术网

我可以更改Python';的连接池大小吗;s";“请求”;模块?

我可以更改Python';的连接池大小吗;s";“请求”;模块?,python,multithreading,request,python-requests,Python,Multithreading,Request,Python Requests,(编辑:这个错误的意思可能是我错了。这是表示我客户端的连接池已满?还是服务器上的连接池已满,而这就是给我客户端的错误?) 我正在尝试使用python线程化和请求模块同时发出大量http请求。我在日志中看到此错误: WARNING:requests.packages.urllib3.connectionpool:HttpConnectionPool is full, discarding connection: 如何增加请求连接池的大小?这应该起到以下作用: import requests se

(编辑:这个错误的意思可能是我错了。这是表示我客户端的连接池已满?还是服务器上的连接池已满,而这就是给我客户端的错误?)

我正在尝试使用python
线程化
请求
模块同时发出大量
http
请求。我在日志中看到此错误:

WARNING:requests.packages.urllib3.connectionpool:HttpConnectionPool is full, discarding connection:

如何增加请求连接池的大小?

这应该起到以下作用:

import requests
sess = requests.Session()
adapter = requests.adapters.HTTPAdapter(pool_connections=100, pool_maxsize=100)
sess.mount('http://', adapter)
resp = sess.get("/mypage")

注意:只有在无法控制连接池的构造时才使用此解决方案(如@Jahaja的回答中所述)

问题是,
urllib3
会根据需要创建池。它不带参数地调用
urllib3.connectionpool.HTTPConnectionPool
类的构造函数。这些类在
urlib3.poolmanager.pool\u classes\u by\u scheme
中注册。诀窍是用具有不同默认参数的类替换这些类:

def patch_http_connection_pool(**constructor_kwargs):
    """
    This allows to override the default parameters of the 
    HTTPConnectionPool constructor.
    For example, to increase the poolsize to fix problems 
    with "HttpConnectionPool is full, discarding connection"
    call this function with maxsize=16 (or whatever size 
    you want to give to the connection pool)
    """
    from urllib3 import connectionpool, poolmanager

    class MyHTTPConnectionPool(connectionpool.HTTPConnectionPool):
        def __init__(self, *args,**kwargs):
            kwargs.update(constructor_kwargs)
            super(MyHTTPConnectionPool, self).__init__(*args,**kwargs)
    poolmanager.pool_classes_by_scheme['http'] = MyHTTPConnectionPool
然后可以调用设置新的默认参数。确保在建立任何连接之前已调用此命令

patch_http_connection_pool(maxsize=16)
如果使用https连接,则可以创建类似的功能:

def patch_https_connection_pool(**constructor_kwargs):
    """
    This allows to override the default parameters of the
    HTTPConnectionPool constructor.
    For example, to increase the poolsize to fix problems
    with "HttpSConnectionPool is full, discarding connection"
    call this function with maxsize=16 (or whatever size
    you want to give to the connection pool)
    """
    from urllib3 import connectionpool, poolmanager

    class MyHTTPSConnectionPool(connectionpool.HTTPSConnectionPool):
        def __init__(self, *args,**kwargs):
            kwargs.update(constructor_kwargs)
            super(MyHTTPSConnectionPool, self).__init__(*args,**kwargs)
    poolmanager.pool_classes_by_scheme['https'] = MyHTTPSConnectionPool
已经为您的问题提供了答案,但它没有回答正在发生的事情,或者,正如您所问的,这个错误意味着什么

关于这方面的一些非常详细的信息在中,包
requests
在引擎盖下使用来实际执行其请求。以下是您的问题的相关部分,添加了我自己的一些注释,并介绍了一些代码示例,因为
请求
具有不同的API:

PoolManager
类根据需要自动为每个主机创建
ConnectionPool
实例。默认情况下,它将保留最多10个ConnectionPool实例[注意:这是
requests.adapters.HTTPAdapter()
中的
pool\u connections
,并且它具有相同的默认值10]
。如果您向许多不同的主机发出请求,那么增加此数量可能会提高性能

但是,请记住,这确实会增加内存和套接字消耗

类似地,ConnectionPool类保留了一个单独的
HTTPConnection
实例池。这些连接在单个请求期间使用,并在请求完成时返回池。默认情况下,只保存一个连接以供重复使用[注意:这是
HTTPAdapter()
中的
pool\u maxsize
,并请求将默认值从1更改为10]
。如果同时向同一主机发出多个请求,则增加此数量可能会提高性能

ConnectionPool的池行为与PoolManager不同。默认情况下,如果发出新请求,并且池中没有空闲连接,则将创建新连接。但是,如果存在超过
maxsize
个连接,则不会保存此连接。这意味着maxsize不确定可以打开到特定主机的最大连接数,而只确定池中要保留的最大连接数。但是,如果指定
block=True
[注意:在
HTTPAdapter()
]中作为
pool\u block
提供][/strong>,则最多可以打开到特定主机的maxsize连接

鉴于此,以下是您的案例:

  • 提到的所有池都是客户端池。您(或
    请求
    )无法控制任何服务器连接池
  • 该警告是关于
    HttpConnectionPool
    ,即同时连接到同一主机的数量,因此可以增加
    pool\u maxsize
    ,以匹配用于消除警告的工作线程/线程的数量
  • 请注意,
    请求
    已经打开了您所请求的任意多个同时连接,而不管
    池大小
    。如果您有100个线程,它将打开100个连接。但是使用默认值时,池中将只保留其中的10个供以后重用,完成请求后将丢弃90个
  • 因此,更大的
    池\u maxsize
    通过重用连接而不是通过增加并发性来提高单个主机的性能
  • 如果您处理的是多台主机,那么您可能会更改
    pool\u连接
    。默认值已经是10,因此如果所有请求都指向同一个目标主机,则增加该值不会对性能产生任何影响(但会增加所使用的资源,如上述文档所述)

这对我很有用。应将其标记为正确答案。在将
http
替换为
https
后,该选项起作用。另外,我认为
pool\u connections
是不必要的。每个会话都有自己的连接池还是多个会话共享一个连接池?@lfk可能可以通过向多个会话添加一个适配器实例来共享它。但这可能不是一个好主意。在增加当前池之前,我如何检查它的大小?Requests有一个内置的API来提供ConnectionPool构造函数参数,不需要修补构造函数。(见@Jahaja的答案)这取决于上下文。如果您可以控制创建HTTPAdapter,那么使用构造函数是正确的解决方案。但在某些情况下,连接池是在某个框架或库的某个深处初始化的。在这些情况下,您可以像我上面所描述的那样修补库或修补连接池构造函数。我在解决方案中添加了一个说明。是的,这可能是另一个问题的答案,但这是我在搜索类似以下内容时发现的问题:
HttpConnectionPool已满,放弃连接python
。但是解决办法呢