考虑一下向API端点发出简单GET请求的函数:
import httpx
def check_status_without_session(url : str) -> int:
response = httpx.get(url)
return response.status_code运行此函数将在每次调用函数check_status_without_session时打开一个新的TCP连接。现在,HTTPX文档的这部分建议在对同一个Client发出多个请求时使用Client API。以下职能是这样做的:
import httpx
def check_status_with_session(url: str) -> int:
with httpx.Client() as client:
response = client.get(url)
return response.status_code根据文档,使用Client将确保:
..。客户端实例使用HTTP连接池。这意味着当您向同一台主机发出多个请求时,客户端将重用底层TCP连接,而不是对每个请求重新创建一个。
我的问题是,在第二个例子中,我已经将Client上下文管理器封装在一个函数中。如果我用同一个URL多次调用check_status_with_session,那么每次调用该函数时,不是只创建一个新的连接池吗?这意味着它实际上并不是在重用连接。当函数堆栈在函数执行后被销毁时,Client对象也应该被销毁,对吗?这样做有什么好处吗?还是有更好的方法?
发布于 2022-02-08 16:27:25
这样做有什么好处吗?还是有更好的办法?
不,以您所展示的方式使用httpx.Client没有好处。事实上,httpx.<method> API,例如httpx.get,做完全一样的东西!
“池”是Client持有的传输管理器的一个特性,默认情况下是HTTPTransport。传输是在Client初始化时和self._transport创建的。
创建一个新的Client实例意味着一个新的HTTPTransport实例,而传输实例有自己的HTTPTransport连接池。通过每次创建一个新的Client实例,并且只使用它一次,直接使用httpx.get是没有好处的。
那可能没问题!连接池是通过为每个请求创建新的TCP连接而进行的优化。您的应用程序可能不需要这样的优化,它可能已经满足了您的需要。
如果您在一个紧循环中向同一个端点提出了许多请求,那么在循环上下文中迭代可能会为您带来一些吞吐量增益。
with httpx.Client(base_url="https://example.com") as client:
results = [client.get(f"/api/resource/{idx}") for idx in range(100)]对于这种I/O繁重的工作负载,通过并行执行结果(例如使用httpx.AsyncClient ),您可能会做得更好。
https://stackoverflow.com/questions/69916682
复制相似问题