【问题标题】:Python & HTTPX: How does httpx client's connection pooling work?Python & HTTPX:httpx 客户端的连接池是如何工作的?
【发布时间】:2021-12-23 06:04:46
【问题描述】:

考虑这个向 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 文档的this 部分建议在向同一个 URL 发出多个请求时使用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 对象也应该被销毁,对吧? 这样做有什么好处还是有更好的方法?

【问题讨论】:

    标签: python http session tcp httpx


    【解决方案1】:

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

    不,以您展示的方式使用httpx.Client 没有任何优势。事实上 httpx.<method> API,例如httpx.getexactly the same thing

    “池”是Client 持有的传输管理器的一个特性,默认为HTTPTransport。传输在Client 初始化时间和stored as the instance property self._transport 创建。

    创建一个新的Client 实例意味着一个新的HTTPTransport 实例,并且传输实例有自己的TCP 连接池。通过每次创建一个新的 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-04
      • 2015-01-03
      • 1970-01-01
      • 2015-06-17
      • 1970-01-01
      • 2020-04-10
      • 2012-05-22
      • 2017-12-24
      相关资源
      最近更新 更多