ALPN(Application-Layer Protocol Negotiation,应用层协议协商,读作”al-p-n”)是 TLS 扩展规范 RFC 7301 中定义的一项机制,用于在客户端与服务器进行 TLS 加密握手的过程中,同步协商出双方都支持的应用层协议,例如 HTTP/1.1、HTTP/2 或 HTTP/3。这篇指南帮助你理解 ALPN 如何减少一次额外的网络往返,从而显著加快建站场景下的连接建立速度,并学会在服务器上正确配置与排查。
# 查看服务器支持的 ALPN 协议 (示例输出) # openssl s_client 会打印握手后选中的 next protocol echo | openssl s_client -alpn h2,http/1.1 -connect example.com:443 2>/dev/null | grep "ALPN" # 典型输出: ALPN protocol: h2
ALPN 的定义
ALPN 是 TLS 的一个扩展字段,它允许客户端在发送 ClientHello(客户端问候)消息时,附带一份按优先级排序的应用层协议列表;服务器收到后,从这份列表中选择自己同样支持且优先级最高的一项,并通过 ServerHello(服务器问候)回复给客户端。整个过程发生在 TLS 加密协商阶段,因此不需要额外的明文通信通道,也不需要双方在 80 端口预先探测一次”明文升级”流程。
在 ALPN 出现之前,客户端与服务器通常依靠 HTTP/1.1 的 Upgrade: h2c 机制来做协议升级:先以明文 HTTP/1.1 建立连接,再发送 Upgrade 请求头申请切换到 HTTP/2。这种方式会额外增加至少一次网络往返(RTT,Round-Trip Time,一次请求-响应往返耗时),在延迟较高的线路(例如跨境访问)上会成倍放大连接建立时间。ALPN 把这一协商动作内嵌进 TLS 握手,让协议选择不再消耗额外的 RTT。
ALPN 的工作原理
ALPN 完全依托 TLS 1.2 与 TLS 1.3 的扩展机制工作。以一次典型的 HTTPS 请求为例,其协商流程可以拆解为四个步骤:
- 客户端在 ClientHello 中携带 ALPN 扩展,例如依次声明 h2、http/1.1。
- 服务器查看自身已启用的协议栈,从客户端列表中挑选交集里优先级最高的协议。
- 服务器在 ServerHello 中回写选中的协议标识(一个长度不超过 255 字节的字节串)。
- 握手完成后,双方后续数据全部按该协议解析,无需再次协商。
ALPN 协议标识(protocol name)采用 one-byte-length-prefixed 的编码格式,常用取值包括 h2(对应 HTTP/2 over TLS)、http/1.1 以及 h3(对应 HTTP/3 over QUIC,见下方说明)。下面这张图归纳了 ALPN 在整个连接建立阶段的位置与作用。

ALPN 与 HTTP/2、HTTP/3 的关系
现代浏览器(如 Chrome、Firefox、Edge)在与 HTTPS 站点建连时,都会在 ClientHello 里同时声明 h2 与 http/1.1。站点只有正确启用 ALPN,浏览器才会使用 HTTP/2;否则连接会自动降级回 HTTP/1.1。也就是说,ALPN 是 HTTP/2 得以在加密连接上实际生效的前提条件之一。
与 HTTP/2 相比,HTTP/3 改为基于 UDP 的 QUIC 协议承载,其传输层协商由 QUIC 的传输参数完成,但仍会复用 ALPN 的标识体系来区分应用层版本。部署 HTTP/3 时通常需要在协议列表里同时保留 h3 与 h2,作为不支持 UDP 场景下的回退路径。关于底层网络与加速机制的说明,可以进一步阅读 BGP 路由与跨区访问 与 负载均衡健康检查 词条。
如何配置 ALPN
多数主流 Web 服务器默认会自动启用 ALPN,并将 h2 排在列表靠前位置。以下是几种常见场景的配置方法,示例中的参数为示意用法,具体取值以你的部署环境为准。
Nginx 的 ALPN 配置
Nginx 从 1.9.5 起,在 listen 443 ssl 基础上通过 http2 与 ssl_protocols 指令联动 ALPN。示例配置节选如下(示例配置,需结合你的站点上下文):
listen 443 ssl http2; # 启用 TLS 1.2 与 1.3,ALPN 自动声明 h2 ssl_protocols TLSv1.2 TLSv1.3; # 指定加密套件顺序,h2 优先 ssl_prefer_server_ciphers on;
CDN 与云加速场景
接入 CDN 或负载均衡器后,ALPN 协商由边缘节点完成,源站通常无须改动。若发现回源为明文 HTTP/2,需要检查 CDN 面板中”协议版本”或”回源协议”选项,确认边缘与源站均启用了对应的 ALPN 标识。
ALPN 带来的提速效果
ALPN 的提速本质是把”明文协议探测”环节从连接建立中移除。对于典型的 HTTPS 连接,完整的 TLS 1.3 握手约需 1 次 RTT;在缺少 ALPN 的前提下,若还要额外交互一次 HTTP Upgrade,则整体耗时会被放大到约 2 次 RTT。在一张跨区访问测试矩阵中,示例场景(延迟 150 毫秒示例典型区间)下,启用 ALPN 后页面首字节时间约缩短数十毫秒级。下表归纳了不同场景的相对收益:
- 高延迟跨境线路:ALPN 节省的 RTT 占比最高,提速感知最明显。
- HTTP/2 多路复用站点:协议协商减少后,并发资源加载的整体等待时间随之下降。
- 移动网络:弱网环境下每个 RTT 代价高昂,ALPN 的省往返价值进一步放大。

常见误区与排查方法
在实际运维中,ALPN 相关故障往往表现为”站点只走 HTTP/1.1″或”HTTP/2 始终无法启用”。
| 症状 | 可能原因 | 排查动作 |
|---|---|---|
| curl 始终回退 HTTP/1.1 | 服务器未启用 http2 模块或 ALPN 未声明 | 核对 Nginx 编译参数,确认包含 http_v2_module |
| 浏览器开发者工具显示 protocol 为空 | 中间设备(防火墙/代理)剥离了 ALPN 扩展 | 更换网络或用 openssl s_client 逐跳核对 |
| TLS 握手直接失败 | 双方 ALPN 列表无交集 | 用 -alpn 参数显式指定并调整服务器协议列表 |
| HTTP/3 无法启用 | UDP 端口被阻断或缺少 h3 标识 | 放行 443/UDP 并确认 ALPN 列表含 h3 |
需要特别警惕的是,某些安全设备会在”审计”名义下剥除 ALPN 扩展,这会造成客户端与服务器各自持有不同的协议认知。这类故障与 DNS 缓存解析异常类似,都是”两侧状态不一致”的典型问题,可参考 DNS 负缓存 与 CNAME 打平 的排查思路。
总结
ALPN 通过将应用层协议协商内嵌进 TLS 握手,为 HTTPS 连接省下一次额外的网络往返,是 HTTP/2 与 HTTP/3 得以在加密连接上高效工作的重要基础。站长在部署或迁移站点时,只要确认服务器、CDN 与客户端三方的 ALPN 协议列表存在交集,通常即可获得正确的协商结果。理解其原理后,即使遇到协议意外降级,也能对照握手过程快速定位根因。

微信扫一扫打赏
支付宝扫一扫打赏