aiohttp 把并发限制放在 TCPConnector 里,但 limit 和 limit_per_host 到底各管什么、两个同时设怎么办、几个会话一起跑又怎样,文档里一两句话很难说清。这篇在本机用多台服务器和多个主机名把它们逐一量出来。
aiohttp.TCPConnector() 默认 limit=100,limit_per_host=0(0 表示不限)
默认 limit=100、limit_per_host=0。直接用默认值的爬虫,对目标站点最高会同时开 100 条连接;这个数字对某个站点是否合适,取决于那个站点,本文没有拿任何真实站点测它的承受能力。
默认(limit=100,limit_per_host=0):服务器同时在处理的峰值 100,累计连接数 100,总耗时 245 ms limit=0(不限):服务器同时在处理的峰值 200,累计连接数 200,总耗时 158 ms limit=20:服务器同时在处理的峰值 20,累计连接数 20,总耗时 1091 ms limit_per_host=5:服务器同时在处理的峰值 5,累计连接数 5,总耗时 4231 ms
只有一个目标主机时,limit 和 limit_per_host 效果一样:服务器看到的并发峰值就是设定值,总耗时接近 请求数 / 上限 × 单次耗时。limit=0 表示不限制,200 个请求会同时发出。
limit=30:三台服务器各自的并发峰值 [14, 24, 14],三台合起来同时在处理的峰值 30,总耗时 1080 ms limit=0,limit_per_host=5:三台服务器各自的并发峰值 [5, 5, 5],三台合起来同时在处理的峰值 15,总耗时 3163 ms limit=30,limit_per_host=5:三台服务器各自的并发峰值 [5, 5, 5],三台合起来同时在处理的峰值 15,总耗时 3183 ms
limit 限制所有主机合计的连接数,各主机之间分配不均(实测 [14, 24, 14]);limit_per_host 限制每个主机。两个同时设置时,更紧的那个起作用。
用同一个主机名(127.0.0.1)访问,limit_per_host=5:服务器同时处理的峰值 5,4270 ms 用 4 个不同主机名(都解析到同一台服务器)访问,limit_per_host=5:服务器同时处理的峰值 20,1523 ms
limit_per_host 按请求里的主机名和端口分组,不关心它们是不是同一台服务器。用 4 个域名访问同一台服务器,服务器实际看到的并发是 4 × 5 = 20。
1 个 ClientSession,每个 limit=10,各发 100 个请求:服务器同时处理的峰值 10,总耗时 1087 ms 3 个 ClientSession,每个 limit=10,各发 100 个请求:服务器同时处理的峰值 30,总耗时 1102 ms 同样 300 个请求但共用 1 个 ClientSession(limit=10):服务器同时处理的峰值 10,总耗时 3216 ms
上限属于 TCPConnector,每个 ClientSession 默认有自己的连接器,所以几个会话同时跑,总并发是它们的上限之和。想要全局的上限,会话要共用,或者在外面再套一层 Semaphore。