HTTP/2 与 ALPN 检查
每次都重新握一次手,看这个站当下协商出来的到底是什么协议,以及它在 HTTP/2 里给自己定的参数。
需服务端处理这个工具由服务器代为访问网络
你要检查的域名或网址会发送到本站服务器,由服务器发起查询,结果只返回给这个页面。
服务器不保存查询内容,也不记录你查了什么,只按来源 IP 限制频率(每分钟 30 次)防止被当跳板刷。站上其它工具仍然全部在浏览器本机完成。
例子:
必须走 HTTPS:HTTP/2 是靠 TLS 的 ALPN 扩展协商的,明文端口上协商不出 h2。
ALPN 在 TLS 握手里干了什么
ALPN(应用层协议协商)是 TLS 握手阶段的一小段扩展:客户端在 ClientHello 里按自己的偏好顺序声明「我支持这些应用层协议」,服务端从中挑一个放进 ServerHello。整个过程发生在握手内部,所以不需要多发一次请求,也不会产生一次额外的往返——这也是它取代早年那套「先按 HTTP/1.1 请求、看服务端是否 101 升级」做法的原因。
理解这一点能解释一个常见现象:ALPN 的结果取决于双方的偏好,不是服务端能力的绝对声明。这个工具按 h2、http/1.1 的顺序声明,服务端选了 http/1.1,通常说明它没启用 h2;但如果服务端配置里刻意把 h1 排在前面,结果也会是这样。要区分这两种情况,得去看服务端自己的配置,工具只能给你一个外部观测到的结果。
另外要注意 ALPN 和 TLS 版本是两层的事,别混着看。TLS 1.2 上照样能跑 HTTP/2,TLS 1.3 也不代表就一定会用 h2。前者管「连接怎么加密」,后者管「在这条加密连接上怎么组织请求」。
SETTINGS 里哪几个参数值得看
连接建立之后,服务端会发来一份 SETTINGS,声明它接受什么、限制什么。这份参数是 HTTP/2 性能调优里最直接的抓手,但日常几乎没人看,因为它在浏览器开发者工具里藏得很深。
maxConcurrentStreams 决定这一条连接上能同时跑多少个请求。HTTP/1.1 时代浏览器用「同一个域名开六条连接」来绕开队头阻塞,HTTP/2 则是一条连接加多路复用,所以这个数字就是流量的闸门。100 到 250 是常见区间;如果只有个位数,多路复用基本白开,页面加载会退化成排队。
initialWindowSize 是流控窗口的初始值,决定单条流在收到对端确认之前能连续发多少数据。协议默认 65535 字节,在带宽延迟积大的链路上(比如跨国)这个值太小,一次往返只能推进 64 KB,大文件下载会被拖慢。把它提到 1 MB 以上是常见优化,也是这个页面上最容易看出「对方有没有认真调过」的地方。
maxHeaderListSize 是请求头体积的上限。这个值如果是「未声明」,意味着服务端接受任意大的头部,攻击者可以据此发一个超大头部,让服务端在解码 HPACK 时消耗大量内存——这就是 HPACK 炸弹。显式声明成 16 到 64 KB 就能挡住它。顺便一提,某些 CDN 会声明一个接近 4 GB 的值,那其实等于没限制,页面上会把这种情况单独标出来。
剩下的 maxFrameSize 和 headerTableSize 属于细枝末节,调不调差别很小;服务端推送(enablePush)则已经是历史遗留——Chrome 从 106 起就移除了对它的支持,保留它既没有收益也不会造成问题。
什么时候 HTTP/2 反而不如 HTTP/1.1
这一点很少被提起:HTTP/2 是一条连接承载所有请求,所以它把「多个连接的并行」换成了「一条连接上的多路复用」。这在请求数量多的时候是巨大的改进,但代价是 TCP 层的队头阻塞变成了整条连接的问题——一个丢包会让所有流一起等待,而 HTTP/1.1 的六条连接里只有一条受影响。所以 HTTP/2 真正的完整形态是 HTTP/3 的 QUIC,它把这条连接移到了 UDP 上。
实际结论是:服务端把流控窗口调得太小、或者并发流限得过低时,HTTP/2 可能比原来的 HTTP/1.1 更慢。所以「开了 h2 就更快」不该当成结论,而是要看这份 SETTINGS 有没有把参数配对。检查完这里,可以再用响应头与重定向检查看看这个站的缓存和传输策略,两者合起来才是完整的传输层体检。
常见问题
为什么开发者工具里显示 h2,这里却显示 http/1.1?
两边测的不是同一件事。开发者工具那一列显示的是这条连接协商出来的结果,而浏览器有连接池——你看到的那条连接可能是几分钟前建的,站点中途改过配置也照样显示旧结果。这个工具每次都重新握手,所以拿到的是当下这一刻的答案。反过来说,如果你刚改完配置,用这个工具能看到变化,页面刷新则不一定。
协商结果是 http/1.1,说明服务器不支持 HTTP/2 吗?
不能这么下结论。ALPN 的规则是服务端从客户端给出的列表里挑一个它支持的,所以结果取决于双方的偏好顺序。这里按 h2、http/1.1 的顺序声明(也就是把 h2 排在前面),服务端仍然选了 http/1.1,通常意味着它确实没启用 h2;但也可能是配置里明确把 h1 排在前面。想彻底确认,可以看响应头里有没有升级相关的字段,或者直接查服务端的配置。
HTTP/2 开了是不是就变快了?
不一定,甚至可能相反。HTTP/2 真正解决的是「同一个域名下要开很多条连接」这个问题——浏览器对每个域名只允许六条左右的并发连接,请求一多就排队,而 HTTP/2 用一条连接承载多路复用。所以它的收益取决于你的页面结构:请求数量多、并发高的时候收益明显;只有一两个请求的页面几乎没差别。反过来,如果服务端把流控窗口设得太小,单条大文件下载可能比 HTTP/1.1 还慢,这正是要看 SETTINGS 的原因。
SETTINGS 里的 maxConcurrentStreams 是什么?
服务端告诉客户端「这一条连接上,你最多可以同时开多少个请求」。HTTP/1.1 时代浏览器只能用六条连接来绕开队头阻塞,HTTP/2 则是靠这个数字来限流。常见值在 100 到 250 之间;如果只有 1 或者个位数,多路复用基本失效,页面加载会退化成排队。
服务端没声明 maxHeaderListSize 有影响吗?
有。这个字段是服务端声明「请求头我最多接受多大」,不声明意味着它接受任意大小。攻击者可以借此发一个超大头部,让服务端在解码 HPACK 时消耗大量内存,这就是 HPACK 炸弹。主流服务器默认值通常是 16 到 64 KB,显式声明出来更稳妥。
为什么这个检查不校验证书?
因为证书是否有效和「支持什么协议」是两件独立的事,而证书有问题时你往往更需要知道自己的协议配置到底生效没有。证书的细节交给站上的 SSL 证书在线检查,那个工具会给出链、有效期和浏览器看到的结果。
相关:SSL 证书在线检查