2013-08-27 14 views
32

(edytuj: Być może się mylę w tym, co ten błąd oznacza.) Czy to oznacza, że ​​pula połączeń u mojego KLIENTA jest pełna? Lub pula połączeń w SERVER jest pełna i jest to błąd mojego klienta jest podawany?)Czy mogę zmienić rozmiar puli połączeń dla modułu "żądania" Pythona?

Próbuję wykonać jednocześnie dużą liczbę żądań http przy użyciu modułu python threading i requests. Ten błąd występuje w dziennikach:

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

Co mogę zrobić, aby zwiększyć wielkość puli połączeń dla wniosków?

Odpowiedz

70

To powinno załatwić sprawę:

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

Działa to dla mnie. Powinien być oznaczony jako poprawna odpowiedź. – reish

9

Uwaga: korzystać z tego rozwiązania tylko wtedy, gdy nie można kontrolować budowę puli połączeń (jak opisano w odpowiedzi Jahaja za @).

Problem polega na tym, że urllib3 tworzy pule na żądanie. Wywołuje konstruktora klasy urllib3.connectionpool.HTTPConnectionPool bez parametrów. Zajęcia są rejestrowane w urllib3 .poolmanager.pool_classes_by_scheme. Sztuką jest zastąpienie klas klasami o różnych domyślnych parametrach:

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 

Następnie możesz zadzwonić, aby ustawić nowe domyślne parametry. Upewnij się, że jest to wywoływane przed wykonaniem jakiegokolwiek połączenia.

patch_http_connection_pool(maxsize=16) 

Jeśli używasz połączenia https można utworzyć podobną funkcję:

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

Żądania mają wbudowany interfejs API do dostarczania parametrów konstruktora ConnectionPool, poprawianie konstruktora jest niepotrzebne. (Patrz odpowiedź @ Jahaja.) – shazow

+1

To zależy od kontekstu. Jeśli masz kontrolę nad tworzeniem obiektu HTTPAdapter, użycie konstruktora jest poprawnym rozwiązaniem. Ale są przypadki, w których pula połączeń jest inicjowana gdzieś głęboko w jakimś szkielecie lub bibliotece. W takich przypadkach można załatać bibliotekę lub załączyć konstruktor puli połączeń, tak jak to opisano powyżej. –

+0

Dodałem wyjaśnienie do mojego rozwiązania. –

Powiązane problemy