bigywater.tech
Scrapy · 45

HTTP/2 下载处理器

Scrapy 能用 HTTP/2 吗?一条连接上多路复用是不是真的?并发流上限由谁决定?证书默认校验吗?这篇用 nginx 当 HTTPS + HTTP/2 服务器,看连接数、协议和耗时。

20 → 1
同样 41 个 https 请求,HTTP/1.1 与 H2 处理器用的连接数
3.12 s
nginx 最大并发流 4 时 40 个请求(各 0.3 s)的总耗时(流上限 128 时是 0.66 s)
False
DOWNLOAD_VERIFY_CERTIFICATES 的默认值

启用

实测 · 本机执行输出
  默认 HTTP11DownloadHandler:nginx 记录的连接数 20(其中一条连接上最多 3 个请求);协议 {'HTTP/1.1': 41};TLS {'TLSv1.3': 41};response.protocol=HTTP/1.1、ip_address=127.0.0.1、certificate 类型=Certificate;总耗时 0.06 s
  H2DownloadHandler:nginx 记录的连接数 1(其中一条连接上最多 40 个请求);协议 {'HTTP/2.0': 41};TLS {'TLSv1.3': 41};response.protocol=h2、ip_address=127.0.0.1、certificate 类型=Certificate;总耗时 0.04 s

把 https 映射到 H2DownloadHandler 并安装 h2 库;只支持 TLS 上的 HTTP/2。响应的 protocol 是 h2。

多路复用

实测 · 本机执行输出
  DOWNLOAD_VERIFY_CERTIFICATES 默认 = False
  默认(不校验):[{'who': 'callback', 'status': 200}]
  DOWNLOAD_VERIFY_CERTIFICATES=True:[{'who': 'errback', 'exc': 'DownloadFailedError', 'msg': "[<twisted.python.failure.Failure OpenSSL.SSL.Error: [('SSL routines', '', 'certificate verify failed"}]

同一主机的请求共用一条连接,以流的形式并发;并发流数受服务器上限(http2_max_concurrent_streams)约束,超出的排队。

证书

实测 · 本机执行输出
  H2 + 流上限 128:后端并发峰值 20;nginx 连接数 1;总耗时 0.66 s(40 个请求 × 0.3 s ÷ 并发)
  H2 + 流上限 4:后端并发峰值 4;nginx 连接数 1;总耗时 3.12 s(40 个请求 × 0.3 s ÷ 并发)
  HTTP11 + nginx 流上限 4(对 1.1 无影响):后端并发峰值 20;nginx 连接数 20;总耗时 0.67 s(40 个请求 × 0.3 s ÷ 并发)

DOWNLOAD_VERIFY_CERTIFICATES 默认关闭,不校验证书;打开后自签名证书会得到 DownloadFailedError。

限制

实测 · 本机执行输出
  H2 处理器 + meta proxy:[{'who': 'errback', 'exc': 'NotImplementedError', 'msg': "_ScrapyH2Agent doesn't support proxies."}]

不支持代理(抛 NotImplementedError)。

分步演示

HTTP/2
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.8 / Scrapy 2.19.0 / Twisted 26.4.0 / lxml 6.1.3 / parsel 1.12.1(临时虚拟环境);所有请求只发给本机自己起的测试服务器(127.0.0.1,端口 9960 以上,不访问任何真实网站);服务器可以按实验需要制造延迟、重定向、压缩、断连等行为,并记录收到的原始请求;每个实验在临时目录里新建 Scrapy 项目或单文件 spider,命令输出来自真实的 scrapy 进程;计时用 time.perf_counter,数字每次运行会有小幅抖动(另装 h2 4.4.1;nginx 来自 Homebrew,监听 127.0.0.1,HTTPS + HTTP/2,反向代理到本机的 Python 后端;证书是 openssl 生成的 EC P-256 自签名证书)。连接数来自 nginx 访问日志里的连接序号
    • 没有验证:服务器推送(Scrapy 不支持);HTTP/2 下的流量控制窗口和大响应;连接断开后的重连;h2c(明文 HTTP/2);TLS 会话复用的收益(只比较了连接数,没有拆分握手耗时);真实网络上 H2 与 HTTP/1.1 的吞吐对比(本机后端太快,0.06 s 对 0.04 s 没有统计意义)
    京ICP备2026067502号-1京公网安备11010502063487号