文档说 CONCURRENT_REQUESTS_PER_DOMAIN 限制单个域名的并发。这篇在服务器端数同时在处理的请求,发现默认的 asyncio reactor 下它根本拦不住一次性涌入的请求;全局限制和 DOWNLOAD_DELAY 才是靠得住的。本文的结论都是 2.19.0 本机实测。
每域名并发 asyncio reactor(默认) SelectReactor 无 reactor 理想耗时 48×0.3/N
1 峰值 48(0.35) 峰值 1(14.69) 峰值 1(14.65) 14.4
2 峰值 48(0.37) 峰值 2(7.35) 峰值 2(7.35) 7.2
4 峰值 48(0.38) 峰值 4(3.70) 峰值 4(3.68) 3.6
8 峰值 48(0.36) 峰值 8(1.88) 峰值 8(1.85) 1.8
16 峰值 48(0.37) 峰值 16(0.96) 峰值 16(0.95) 0.9文档上,每个域名(下载槽)同时下载的请求数不超过 CONCURRENT_REQUESTS_PER_DOMAIN。实测 2.19.0 在 SelectReactor 和无 reactor 模式下确实如此,但默认的 asyncio reactor 下单域名的并发等于已经排在槽里的请求数,与设置无关。
asyncio reactor(默认):槽的 concurrency = 4;共 17 次开始下载;各次开始时槽里 transferring(含自己)依次是 [1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];服务器峰值 16 SelectReactor:槽的 concurrency = 4;共 17 次开始下载;各次开始时槽里 transferring(含自己)依次是 [1, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4];服务器峰值 4
槽按 concurrency − len(transferring) 放行,而 asyncio 下下载是以任务的方式排队的,transferring 要等任务运行才增加,放行循环看不到,于是一次放光。
全局并发 服务器总峰值 各主机峰值 总耗时 s
4 4 127.0.0.1=2 localhost=2 2.46
6 6 127.0.0.1=3 localhost=3 1.87
16 16 127.0.0.1=8 localhost=8 0.65全局 CONCURRENT_REQUESTS(引擎按在途请求数判断)和 DOWNLOAD_DELAY(每次只放出一个)在 asyncio reactor 下有效。
DOWNLOAD_DELAY 服务器峰值 总耗时 s 相邻请求到达间隔的中位数 ms
0 24 0.34 0
0.1 4 2.73 101
0.2 2 5.13 201有 DOWNLOAD_DELAY 时相邻请求间隔等于延迟,同时在途的请求数约等于请求耗时除以延迟。
PER_IP=3(ScrapyPriorityQueue) asyncio reactor:峰值 48 SelectReactor:峰值 3 无 reactor:峰值 48
DOWNLOAD_SLOTS={"127.0.0.1": {"concurrency": 3}} asyncio reactor:峰值 48 SelectReactor:峰值 3 无 reactor:峰值 48它们设置的也是槽的 concurrency,所以有同样的现象;无 reactor 模式下它们也不起作用。
55
56 def __init__(self, crawler: Crawler):
57 super().__init__(crawler)
58 self._ssl_context: ssl.SSLContext = _make_ssl_context(crawler.settings)
59 connector = aiohttp.TCPConnector(
60 local_addr=self._bind_address,
61 # hard limit on simultaneous connections
62 limit=self._pool_size_total,
63 # hard limit on simultaneous connections per host
64 limit_per_host=self._pool_size_per_host,
65 )
66 self._session: aiohttp.ClientSession = aiohttp.ClientSession(aiohttp 下载处理器自己的连接器带 limit 和 limit_per_host,所以每域名限制由它保证。