python - Requests / Asyncio:使用 Python 请求会话使 pool_maxsize=1000 有缺点吗?
问题描述
我正在使用以下代码通过请求增加池 maxsize:
import requests
session = requests.Session()
session.mount("https://", requests.adapters.HTTPAdapter(pool_maxsize=50))
session.mount("http://", requests.adapters.HTTPAdapter(pool_maxsize=50))
设置有缺点pool_maxsize=1000
吗?
我有时需要 50 - 1000 个连接,但大多数时候我只需要 1 个连接。
或者,有没有办法允许动态调整池大小?
哪种解决方案最好:
- 放
pool_maxsize = 1000
- 创建 2 个会话,1 个使用
pool_maxsize = 1
,另一个使用pool_maxsize=1000
. - 当我需要不同数量的连接时动态改变 pool_maxsize 。(如果可能的话)
速度最重要!
编辑:大部分时间我都在做正常的请求:
session.get(....)
但有时我会使用 asyncio 来执行大量请求:
import asyncio
async def perform_async_calls(self, session, urls):
loop = asyncio.get_event_loop()
futures = []
for url in urls:
futures.append(loop.run_in_executor(None, session.get, url)
results = []
for future in futures:
result = await future
results.append(result.json())
return results
解决方案
在 HTTP 1.1 中,客户端可以通过设置 Keep-Alive 标头通过同一连接发送多个请求。否则,您必须为每个请求打开一个新连接。使用 Keep-Alive 设置,可以通过同一连接发送多个请求。
打开连接的时间成本很高,因为它需要额外的 TCP 握手往返,然后才能发出下一个请求,因此重用已经存在的连接会更快。
连接池的作用是,在您发出请求后,该连接会为您可能发出的后续请求保持打开状态,并保留在池中。Requests 设置 keep alive 标头并在后台管理池,因此您通常无需担心它。
如果您使用多线程,则池会同步对连接的访问,以便每个连接一次仅由一个线程使用。让多个线程同时发出请求需要池中的多个连接。
拥有比线程更多的连接根本不会提高性能,因为请求包在发出请求时会阻塞线程,因此线程不可能一次使用多个连接。要从附加连接中获得更多性能,需要增加线程数。
像这样添加连接只有在您不受网络速度瓶颈时才有帮助,打开更多连接并不会使互联网更快。因此,只需添加更多线程+连接,直到性能停止增加。
我不确定动态调整大小是什么意思。池在需要时打开新连接,并尽可能重用旧连接。一旦达到最大值,它就会停止打开连接。从某种意义上说,池大小是动态的,只要它低于最大大小。
推荐阅读
- elasticsearch - 如何在弹性搜索中按小时对文档进行分组?
- json - Gatling JSON Feeder 独特的 POST 正文
- html - 如何限制自动填充或自动适应列的总宽度?
- r - ggplot:创建相对堆叠直方图
- c# - 如何将 IList 转换为 ObservableCollection
- gradle - 在运行测试的同时获得 jacoco 代码覆盖率
- selenium - 找不到定位器时如何跳过特定的 WebElement 进程?
- node.js - enoent ENOENT:没有这样的文件或目录,
- sql-server - 在 SQL Server 中评估阶乘(n)?
- trace32 - TRACE32 分段错误和/或程序意外结束后的完整回溯