繁体   English   中英

Python & HTTPX:httpx 客户端的连接池是如何工作的?

[英]Python & HTTPX: How does httpx client's connection pooling work?

考虑这个 function 向 API 端点发出简单的 GET 请求:

import httpx 

def check_status_without_session(url : str) -> int:
    response = httpx.get(url)
    return response.status_code

每次调用 function check_status_without_session时,运行此 function 将打开一个新的 TCP 连接。 现在,HTTPX 文档的这一部分建议使用Client API,同时向同一个 URL 发出多个请求。以下 function 会执行此操作:

import httpx

def check_status_with_session(url: str) -> int:
    with httpx.Client() as client:
        response = client.get(url)
        return response.status_code

根据文档,使用Client将确保:

... Client 实例使用 HTTP 连接池。 这意味着当您向同一主机发出多个请求时,客户端将重用底层 TCP 连接,而不是为每个请求重新创建一个连接。

我的问题是,在第二种情况下,我已将Client上下文管理器包装在 function 中。如果我使用相同的 URL 多次调用check_status_with_session ,难道不会在每次调用 function 时创建一个新的连接池吗? 这意味着它实际上并没有重用连接。 由于 function 堆栈在 function 执行后被销毁, Client object 也应该被销毁,对吧? 这样做有什么好处还是有更好的方法?

这样做有什么好处还是有更好的方法?

不,以您展示的方式使用httpx.Client没有任何优势。 事实上httpx.<method> API,例如httpx.get ,做的是完全一样的事情

“池”是Client持有的传输管理器的一个特性,默认情况下是HTTPTransport 传输在Client初始化时创建并存储为实例属性self._transport

创建一个新的Client实例意味着一个新的HTTPTransport实例,传输实例有自己的 TCP 连接池。 每次都创建一个新的Client实例并且只使用它一次,与直接使用httpx.get ,您没有任何好处。

那可能没问题。 连接池是对为每个请求创建新的 TCP 连接的优化,您的应用程序可能不需要该优化。 它可能已经足够满足您的需求了。

如果您在紧密循环中向同一个端点发出许多请求,则在循环上下文中进行迭代可能会.net 您会获得一些吞吐量增益,例如

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM