HTTP/2 协议带来的多路复用、头部压缩等特性已经大幅改善了页面加载体验,但很多团队忽略了它另一个有意思的能力:服务端推送(Server Push)。Nginx 从 1.13.9 版本开始支持 HTTP/2 Push,可以让服务器在浏览器还没发起请求时,就把关键资源推送到客户端。不过 Push 并非银弹,用不好反而浪费带宽,所以配合 Dynatrace 这类可观测性平台做量化监控,才能真正判断它有没有带来收益。

HTTP/2 Push 的工作原理与适用场景
传统的资源加载流程是这样的:浏览器下载 HTML 文件,解析后才发现需要某个 CSS 文件,然后再发起一次请求。即便 HTTP/2 支持多路复用,这个「发现依赖再请求」的往返过程依然存在。HTTP/2 Push 的思路是打破这个顺序:服务器在发送 HTML 响应的同时,主动把预测浏览器会需要的资源一并发送过去,浏览器收到后放进本地缓存,等真正解析到对应标签时直接命中缓存,省去了一次网络往返。
听起来很美好,但 Push 有一个天然的缺陷:服务器是在「猜」浏览器需要什么。如果猜错了,推过去的数据就是纯粹的带宽浪费,甚至可能与浏览器缓存里已有的内容重复。因此 Push 比较适合的场景是:高确定性、高优先级、体积不大的关键资源,比如首屏必需的 CSS 文件、关键的字体文件、内联入口 JS 等。而图片、视频这类大体积低优先级资源,一般不适合推送。
另外一个值得了解的概念是 Cache Digest(也叫 push diary 的思路来源)。客户端在握手阶段告诉服务器自己已经缓存了哪些资源,服务器据此决定要不要推送,避免重复推送。这个机制需要浏览器和服务器同时支持,目前落地程度有限,但理解它有助于你明白 Nginx 社区设计推送策略时的考量。
Nginx 中配置 HTTP/2 Push 的完整方法
Nginx 的 HTTP/2 Push 由 ngx_http_v2_module 模块提供,该模块默认构建在 Nginx 二进制中,无需额外编译。首先确保监听端口开启了 http2 参数,然后使用 http2_push 指令指定要推送的资源路径。基础配置如下:
server {
listen 443 ssl http2;
server_name example.ipipp.com;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
root /var/www/html;
location = /index.html {
# 直接指定推送资源
http2_push /css/main.css;
http2_push /js/app.js;
}
}除了硬编码路径,Nginx 还支持一种更优雅的方式:http2_push_preload。开启后,Nginx 会解析响应头中的 Link 字段,凡是带有 preload 参数的资源都会被自动推送。这种方式的好处是可以由后端应用动态决定推送什么,Nginx 只负责执行,配置更灵活:
location / {
http2_push_preload on;
proxy_pass http://127.0.0.1:8080;
}后端应用只需要在响应中添加这样的头,Nginx 就会自动推送对应文件:
Link: </css/critical.css>; rel=preload; as=style Link: </fonts/main.woff2>; rel=preload; as=font
这里有几个常见的坑需要注意。第一,推送的资源路径必须是同源的相对路径,不能跨域。第二,推送会占用带宽,建议只推两三个关键文件,不要贪多。第三,如果客户端实际上已经有缓存,Push 反而会拖慢速度,这也是后面要借助日志和监控来验证的原因。你可以在 Nginx 日志中引入 $http2_pushed 相关变量(部分版本支持 $http2 变量判断协议),来区分哪些请求来自 Push:
log_format push_log '$remote_addr - $request '
'protocol=$http2 '
'status=$status '
'bytes=$body_bytes_sent';
access_log /var/log/nginx/access_push.log push_log;为什么说 Push 要配合监控才能用好
Push 的效果高度依赖用户状态:首次访问的用户可能受益明显,而老用户可能因为缓存已存在而白白接收了重复数据。Chrome 开发者工具的 Network 面板可以查看 Initiator 为 Push 的请求,但这只能覆盖你手动测试的场景。要在真实流量中量化 Push 的收益,就需要接入专业的监控平台,Dynatrace 是其中一个很好的选择。
Dynatrace 的 OneAgent 可以自动发现 Nginx 进程,采集请求级别的指标,包括响应时间、吞吐量、HTTP 状态码分布等。针对 HTTP/2 流量,你可以结合 Nginx 的访问日志(通过 Logstash 或 Dynatrace 的日志采集功能导入)与 Dynatrace 的 Real User Monitoring 数据做交叉分析:RUM 负责记录真实用户的页面加载瀑布图、首屏时间、LCP 等关键指标,服务端日志则告诉你 Push 请求的实际命中情况。
具体的接入步骤大致如下:先在 Nginx 服务器上安装 OneAgent,Dynatrace 会自动识别 Nginx 并开始采集基础指标;然后在 Dynatrace 界面中为 Nginx 创建监控实体,配置日志来源指向你定义的 push 日志文件;最后在 RUM 中对启用了 Push 的页面建立对比基线。一个实用的做法是灰度发布:一部分流量走开启 Push 的配置,一部分走关闭的配置,通过 Dynatrace 的多维度分析对比两组用户的 LCP 和带宽消耗,用数据说话。
如果监控数据显示 Push 收益有限甚至为负,也不必执着。实践社区目前更主流的做法是退回到 HTTP Preload(即只发 Link 头不推送,让浏览器自己提前请求),或者干脆优化资源的内联与拆分。Push 作为一项技术尝试,其价值在于理解服务端与浏览器在资源加载上的协作机制,而 Dynatrace 这类工具的意义,则是让每一次性能优化决策都有真实数据支撑,而不是凭感觉。
NginxHTTP/2 PushDynatrace修改时间:2026-09-05 13:40:30