gme*_*mon 19 python keep-alive
我正在使用python的HTTP通信请求模块,我想知道如何重用已经建立的TCP连接?请求模块是无状态的,如果我反复调用get获取相同的URL,那么每次都会创建一个新的连接吗?
谢谢!!
Dmy*_*huk 53
全局函数喜欢requests.get或在每次调用时requests.post创建requests.Session实例.使用这些功能建立的连接无法重复使用,因为您无法访问自动创建的会话并将其连接池用于后续请求.如果你只需要做几个请求就可以使用这些功能.否则你会想要自己管理会话.
以下是requests使用全局get函数和会话时的行为快速显示.
准备工作,与问题无关:
>>> import logging, requests, timeit
>>> logging.basicConfig(level=logging.DEBUG, format="%(message)s")
Run Code Online (Sandbox Code Playgroud)
请参阅每次调用时建立的新连接get:
>>> _ = 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
Run Code Online (Sandbox Code Playgroud)
但是,如果您为后续调用使用相同的会话,则会重用连接:
>>> 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")
Run Code Online (Sandbox Code Playgroud)
性能:
>>> 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
Run Code Online (Sandbox Code Playgroud)
重用会话(以及会话的连接池)时,工作速度会快得多.
请求模块是无状态的,如果我反复调用get获取相同的URL,那么每次都会创建一个新的连接吗?
该requests模块不是无国籍的; 如果您选择这样做,它只会让您忽略状态并有效地使用全局单例状态.*
它(或者更确切地说,是一个底层库urllib3)维护一个由(主机名,端口)对键控的连接池,因此如果可以的话,它通常会神奇地重用连接.
正如文件所说:
好消息 - 感谢urllib3,keep-alive在会话中100%自动!您在会话中发出的任何请求都将自动重用相应的连接!
请注意,只有在读取了所有正文数据后,才会将连接释放回池中以供重用; 一定要设置或者
stream到False或读取content的财产Response对象.
那么,"如果可以"是什么意思呢?正如上面的文档所暗示的那样,如果你保持流式响应对象存活,它们的连接显然不能被重用.
此外,连接池确实是一个有限的缓存,而不是无限的,所以如果您的垃圾邮件了一吨的连接,其中两个是在同一台服务器,你不会总是重复使用的连接,只需经常.但通常,这就是你真正想要的.
*此处相关的特定状态是传输适配器.每个会话都有一个传输适配器.您可以手动指定适配器,也可以指定全局默认值,或者只使用默认的全局默认值,它基本上只包含urllib3.PoolManager用于管理其HTTP连接的默认值.有关更多信息,请阅读文档.