我正在與python的HTTP通信的請求模塊,我想知道如何重用已建立的TCP連接?請求模塊是無狀態的,如果我反覆調用get來獲取相同的URL,它會不會每次都創建一個新的連接?python請求模塊和連接重用
謝謝!
我正在與python的HTTP通信的請求模塊,我想知道如何重用已建立的TCP連接?請求模塊是無狀態的,如果我反覆調用get來獲取相同的URL,它會不會每次都創建一個新的連接?python請求模塊和連接重用
謝謝!
請求模塊是無狀態的,如果我反覆調用獲取相同的URL,它不會創建一個新的連接每次?
requests
模塊不是無狀態的;它只是讓你忽略狀態,並有效地使用全球單身狀態,如果你選擇這樣做。*
而它(或者,而是其中一個底層庫,urllib3
)維護一個連接池(主機名,端口)對,所以如果可能的話,它通常會神奇地重用連接。
極好的消息 - 由於urllib3,保活是在一個會話中100%自動 !您在任何會話中發出的任何請求都會自動重複使用相應的連接!
請注意,一旦所有的主體數據都被讀取,連接只會被釋放回池以供重用 ;請確保將
stream
設置爲False
或者讀取Response
對象的content
屬性。
那麼,「如果可以」意味着什麼?正如上面的文檔所暗示的,如果你保持流式響應對象的活着,它們的連接顯然不能被重用。
此外,連接池確實是一個有限的緩存,而不是無限的,所以如果您的垃圾郵件了一噸的連接,其中兩個是在同一臺服務器,你不會總是重用的連接,只需通常是。但通常情況下,這就是你真正想要的。
*與此有關的特定狀態是transport adapter。每個會話都有一個傳輸適配器。您可以手動指定適配器,或者您可以指定全局默認值,或者您可以使用默認的全局默認值,它基本上只包含用於管理其HTTP連接的urllib3.PoolManager
。有關更多信息,請閱讀文檔。
非常感謝您的詳細回覆;這真的很有幫助。我還有一個問題。上述文檔中的「會話」是什麼?我通讀了文檔,實際上有一個Session對象。我通讀了「請求」代碼,併爲每個請求創建了一個Session對象。所以,如果連接只在Session中重用,那麼我不確定在兩個「get」調用之間連接將被重用。 – gmemon
@gmemon:對不起,這是不好的措辭。我的意思是構成全局狀態的適配器的集合,在這種情況下,特別是'HTTPAdapter'(這是持有'urllib3.PoolManager'的東西)。我不知道這是對的,但「會議」顯然是一個不錯的選擇。我會編輯答案。感謝您指出了這一點。 – abarnert
全局函數如requests.get
或requests.post
在每次調用時創建requests.Session
實例。用這個函數進行的連接不能被重用,因爲你不能訪問自動創建的會話並將它的連接池用於後續請求。如果你只需要做幾個請求,就可以使用這個函數。否則,你會想自己管理會話。
以下是使用全局函數和會話時requests
行爲的快速顯示。
準備,沒有真正的問題有關:
>>> _ = requests.get("https://www.wikipedia.org")
Starting new HTTPS connection (1): www.wikipedia.org
>>> _ = requests.get("https://www.wikipedia.org")
Starting new HTTPS connection (1): www.wikipedia.org
但是如果你使用同一個會話的後續調用,新:
>>> import logging, requests, timeit
>>> logging.basicConfig(level=logging.INFO, format="%(message)s")
見,新的連接在每次調用get
時間確定不會爲每個請求創建連接:
>>> session = requests.Session()
>>> _ = session.get("https://www.wikipedia.org")
Starting new HTTPS connection (1): www.wikipedia.org
>>> _ = session.get("https://www.wikipedia.org")
>>> _ = session.get("https://www.wikipedia.org")
>>> _ = session.get("https://www.wikipedia.org")
性能:
>>> timeit.timeit('_ = requests.get("https://www.wikipedia.org")', 'import requests', number=100)
Starting new HTTPS connection (1): www.wikipedia.org
Starting new HTTPS connection (1): www.wikipedia.org
Starting new HTTPS connection (1): www.wikipedia.org
...
Starting new HTTPS connection (1): www.wikipedia.org
Starting new HTTPS connection (1): www.wikipedia.org
Starting new HTTPS connection (1): www.wikipedia.org
52.74904417991638
>>> timeit.timeit('_ = session.get("https://www.wikipedia.org")', 'import requests; session = requests.Session()', number=100)
Starting new HTTPS connection (1): www.wikipedia.org
15.770191192626953
當你重用會話(從而會話的連接池)
工程快得多。
http://docs.python-requests.org/en/latest/user/advanced/#keep-alive – dm03514