我正在与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