2013-08-27 26 views
32

(编辑:也许我在这个错误的意思是错误的。这是否表明我的客户端连接池已满?或服务器上的连接池已满,这是我的客户端出错?)我可以更改Python“请求”模块的连接池大小吗?

我试图使用python threadingrequests模块同时发出大量的http请求。我在日志中看到这个错误:

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

我该怎么做才能增加请求连接池的大小?

回答

70

这应该做的伎俩:

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

这对我的作品。它应该被标记为正确答案。 – reish

9

注:使用此解决方案只有当你不能控制连接池的建设(如@ Jahaja的答案描述)。

问题是,urllib3按需创建池。它调用不带参数的urllib3.connectionpool.HTTPConnectionPool类的构造函数。课程在urllib3 .poolmanager.pool_classes_by_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 
+1

请求具有用于提供ConnectionPool构造函数参数的内置API,修补构造函数是不必要的。 (请参阅@ Jahaja的答案。) – shazow

+1

这取决于上下文。如果您可以控制创建HTTPAdapter,那么使用构造函数是正确的解决方案。但是有些情况下,连接池被初始化到深藏在某个框架或库中的某个地方。在这些情况下,您可以修补库或修补连接池构造函数,如上所述。 –

+0

我在我的解决方案中添加了一个说明。 –