HTTP/2 Push是Nginx在1.13.9版本之后正式引入的能力。它的核心逻辑是服务器在响应某个主请求时,主动将预先声明的关联资源推送到客户端缓存中,浏览器后续需要这些资源时可以直接从缓存读取,省去重新发起请求的往返时间。这个机制听起来很有吸引力,但实际部署时问题并不少:推送的资源如果浏览器已经缓存了,就会白白消耗带宽;推送的资源如果过大或者优先级安排不合理,反而会拖慢首屏渲染。要衡量这些取舍是否合理,必须有日志数据支撑。SolarWinds的日志分析组件可以把Nginx的访问日志与错误日志统一收集起来,再通过字段解析和告警规则帮助运维人员看清HTTP/2 Push的真实表现。

开启Nginx HTTP/2 Push并梳理日志来源
要在Nginx中启用HTTP/2 Push,先要确认编译时包含ngx_http_v2_module。使用nginx -V命令可以查看编译参数,如果输出中包含--with-http_v2_module就说明模块已就绪。配置层面,http2_push指令属于location级别的指令,它指定在响应当前location的请求时,服务器应该主动推送哪些资源。一个典型的配置如下:
server {
listen 443 ssl http2;
server_name www.ipipp.com;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
root /var/www/html;
index index.html;
location / {
http2_push /css/style.css;
http2_push /js/app.js;
http2_push /images/logo.png;
}
location = /css/style.css {
add_header Content-Type text/css;
}
location = /js/app.js {
add_header Content-Type application/javascript;
}
}
这个配置在访问根路径时,会推送style.css、app.js和logo.png三个资源。需要注意的是,http2_push指令的路径必须与资源在服务器上的实际URI一致,浏览器收到推送后会根据URI与真实请求做匹配。如果推送的URI与实际请求不一致,浏览器会直接忽略推送,导致推送失效但日志里却看不到明显的报错。
Nginx的HTTP/2 Push日志来源主要有两个。第一个是access_log,它记录了每个请求的基本信息,但默认格式中并不区分普通请求和被推送的请求。第二个是error_log的debug级别日志,当error_log配置为debug时,Nginx会输出大量与HTTP/2帧处理相关的内部信息,包括推送流的创建、发送和关闭过程。debug日志虽然信息量最丰富,但体量也最大,生产环境长期开启会对性能产生可见影响。因此在日志策略上,通常建议在access_log中通过自定义格式提取关键字段,同时只在排查问题时短暂开启debug日志。
定制Nginx日志格式提取推送指标
要让SolarWinds能够分析推送行为,核心工作是在Nginx的日志格式中嵌入有区分度的字段。Nginx提供了一些与协议相关的内置变量,其中$http2这个变量在连接使用HTTP/2协议时值为h2,在HTTP/1.x连接下为空。日志中加入这个变量,就能区分出哪些请求走的是HTTP/2连接。
log_format push_diag '$remote_addr - $remote_user [$time_local] '
'$request_method $uri $server_protocol '
'status=$status bytes=$body_bytes_sent '
'http2=$http2 referer=$http_referer '
'push_flag=$http2_push_flag';
上面这个格式里,$http2_push_flag并不是Nginx的内置变量。Nginx官方模块目前没有提供直接标记推送请求的变量,这是很多人在做推送日志分析时遇到的第一个障碍。要解决这个问题,有两条路径可以走。第一条路径是基于access_log中的请求头特征来推断。当浏览器通过HTTP/2 Push接收到资源时,该资源不会产生独立的请求记录,因为浏览器不会发起新的请求。所以实际上access_log里根本不会出现被推送资源的独立条目,被推送的资源只有推送发送阶段的内部日志。这意味着要精确追踪推送行为,光靠access_log是不够的。
第二条路径是使用Nginx的debug日志。将error_log设置为debug级别后,Nginx会输出类似http2 push frame的日志行。这些日志包含流ID、推送资源路径、发送字节数等细节。不过debug日志的格式不适合直接采集分析,需要配合日志预处理脚本。还有一种做法是使用OpenResty或者nginx-plus提供的额外变量,nginx-plus的http2_push指令支持更多上下文,并且可以通过NGINX Plus API获取推送相关的统计计数。如果使用开源Nginx,则建议在Nginx前面加一层日志处理器,比如用Filebeat的multiline配置把debug日志中与push相关的行聚合起来,再送入SolarWinds。
一个折中的方案是在Nginx配置中同时维护access_log和error_log,并在error_log中使用自定义格式记录push事件。例如在http2_push指令执行时,Nginx会向error_log输出notice级别的日志。把error_log级别设置为notice格式可以控制日志体量,同时保留推送相关的关键事件。日志采集端再通过过滤规则只提取包含push关键词的行,就能在不引入debug日志开销的情况下获得推送事件流。
SolarWinds接入Nginx日志与告警策略
SolarWinds的日志分析能力主要来自Log Analyzer和配套的Agent。部署方式上,可以在Nginx所在的服务器安装SolarWinds Agent,也可以使用Syslog协议把日志转发到SolarWinds的日志接收端。对于Nginx日志,推荐使用Agent模式,因为Agent支持文件尾部追踪,可以实时读取access_log和error_log的新增内容,并且内置了Nginx日志解析规则,能自动识别常见的日志字段。
[log_collector]
enabled = true
log_paths = /var/log/nginx/access.log
log_paths = /var/log/nginx/error.log
multiline_match = ^\d{4}/\d{2}/\d{2}
tags = nginx,http2_push
上面的配置片段展示了Agent侧的基础设置。log_paths指定了需要追踪的日志文件路径,multiline_match用于处理跨行的日志条目,tags则为日志打上自定义标识,方便在SolarWinds控制台中按标签检索。当日志进入SolarWinds之后,可以创建自定义的日志查询规则,例如搜索包含push关键词的error_log条目,或者统计某个时间段内$http2变量值为h2的请求占比。
告警策略的设计需要贴合运维场景。对于HTTP/2 Push来说,值得关注的指标包括:推送资源的传输失败次数是否异常升高、单位时间内推送数据的字节数是否超过了带宽预算、以及访问日志中HTTP/2连接的占比是否突然下降。SolarWinds允许基于日志查询结果触发告警,例如设置规则为每5分钟内匹配到包含http2 push failed的日志条数超过10条时发送通知。这种基于日志内容而非固定阈值的告警方式,比单纯监控CPU或内存更能直接反映推送策略的问题。
推送效果评估与常见问题排查
推送策略是否有效,不能只看推送资源的数量,还要看推送是否真正被浏览器使用。浏览器在收到服务器推送后,会在缓存中查找是否已经存在同名资源。如果资源已经被浏览器缓存过,或者推送的URI与页面实际引用的URL不一致,浏览器会发送RST_STREAM帧取消这次推送。这种取消行为在Nginx的debug日志中会以stream reset或者push cancelled的形式出现。
排查推送取消问题时,最直接的方法是比较Nginx配置中的http2_push路径与HTML页面中实际引用的资源路径。例如页面里引用的是/css/style.css?v=20240101这种带版本参数的URL,而http2_push指令只写了/css/style.css,两者无法匹配,推送就会被浏览器丢弃。这种情况下,页面加载时浏览器仍然会重新请求带版本参数的URL,推送等于完全失效。
另一个常见的坑是推送资源的数量过多。每个HTTP/2 Push都会占用独立的流,在连接建立初期发送大量推送帧会与主响应的关键资源争抢带宽。浏览器端也有并发流的限制,超过限制的推送会被排队或者被拒绝。实际经验中,首页推送的资源数量控制在3到5个是相对安全的范围,推送的资源总体积也不宜超过主文档体积的3倍。如果日志数据显示推送的字节数远大于实际被使用的字节数,说明推送策略偏激进,需要收缩推送列表。
要从日志中获得被推送资源的实际使用情况,可以结合浏览器端的Performance API数据。浏览器通过performance.getEntriesByType方法可以获取资源加载的详细信息,其中transferSize为0的条目说明该资源来自缓存,也就是推送命中的情况。将这些前端数据与Nginx日志中的推送事件做时间维度的关联分析,可以得到推送命中率的估算值。这个指标比单纯的推送次数更能反映HTTP/2 Push策略的优劣。
从监控数据反推配置优化
当SolarWinds中积累了足够多的日志数据后,就可以进行趋势分析。提取一段时间内HTTP/2连接的占比变化,能够反映用户侧的协议升级情况。如果HTTP/2连接占比长期在低位徘徊,说明大量用户还在使用HTTP/1.x协议,推送能力对这些用户完全不起作用,此时应该优先推动协议升级而不是继续调整推送策略。
日志中还可以分析出推送资源的大小分布。将推送资源的字节数与页面总加载字节数进行比较,可以估算推送带来的带宽增量。如果推送资源的传输错误率明显高于普通请求,需要检查推送的资源是否存在缓存过期设置不当、ETag变化频繁等问题。Nginx的http2_push指令本身不会检查资源的缓存头,如果资源设置了很短的缓存过期时间,浏览器在推送到达时可能仍然会重新验证,导致推送的实际收益被削弱。
对于SolarWinds用户来说,把这些指标做成仪表盘可以大幅降低日常巡检的工作量。仪表盘上展示推送请求占比、推送取消率、HTTP/2连接趋势和日志错误率四个关键面板,配合按小时或者按天聚合的粒度,运维人员可以快速定位推送策略的变化是否带来了正面效果。推送行为监控的价值并不在于看到每一次推送的细节,而在于通过趋势和异常告警让Nginx的HTTP/2 Push配置始终处于可控状态。
Nginx HTTP/2 PushSolarWinds日志监控推送性能分析修改时间:2026-09-24 15:22:17