Nginx从1.13.9版本开始支持HTTP/2服务端推送相关配置,其中http2_push_diary_max_age是一个容易被忽略但非常关键的指令。它用来设定服务器推送日记(push diary)里每条记录的最大存活秒数,直接影响了客户端在多长时间内不会被重复推送同一批资源。

要弄明白这个指令,得先知道什么是推送日记。当Nginx通过HTTP/2向浏览器主动推送某个资源(比如样式表或脚本)时,它会把这次推送记录写进一张表,也就是推送日记。之后同一个客户端再次建立连接,Nginx会先查日记,如果发现某资源近期已经推过且没过期,就不会再推。http2_push_diary_max_age就是给这些记录设了一个“最大年龄”,时间一到,记录作废,下次连接就可能重新推送。
举个实际例子,假如站点首页依赖main.css和app.js,你在Nginx里配置了http2_push,并设http2_push_diary_max_age为300秒。那么用户五分钟内反复刷新或重新连接,这两个文件不会被重复推;超过五分钟后,日记清空,再次访问就会重新推送一次。这种机制避免了无意义的带宽消耗,但也带来缓存与新版不同步的权衡。
指令基础用法与默认值
在Nginx配置中,http2_push_diary_max_age属于http、server或location层级均可使用的指令。它的语法非常简单,后面跟一个以秒为单位的数字,例如:http2_push_diary_max_age 300;。如果不显式配置,Nginx使用的是默认值,官方设定为300秒,也就是五分钟。
这个默认值对更新不频繁的静态站比较友好,因为五分钟内重复访问不重复推,省了开销。但很多动态内容站或天天发版的团队,五分钟可能刚好跨过一次上线,导致部分用户拿到旧推送记录而错过新资源。因此理解默认值只是起点,真正要用好,得结合自己业务的发布节奏来改。
设置过大或过小的影响
如果把http2_push_diary_max_age设得非常小,比如10秒,那几乎每次短间隔重连都会重新推送。表面上看用户总能拿到“最新”资源,但服务端带宽和客户端接收开销直线上升,HTTP/2推送节省往返延迟的优势也被抵消。对于流量大的站点,这种配置反而会拖慢整体性能。
反过来,若设得极大,例如86400秒(一天),用户一天内无论怎么来都不再推送。这在资源极度稳定时没问题,可一旦你改了CSS配色或修了JSbug并立刻上线,老用户因为日记未过期,浏览器仍认为无需重新收推送,只能等第二天自然失效后才更新。这种“最大年龄”过长造成的滞后,在敏捷迭代业务里是不可接受的。
对比参考表
| 配置秒数 | 重复推送频率 | 更新生效速度 | 适用场景 |
|---|---|---|---|
| 10 | 极高 | 最快 | 测试环境或极低频访问内部系统 |
| 300(默认) | 中等 | 五分钟内可能滞后 | 常规静态展示站 |
| 3600 | 较低 | 最长一小时滞后 | 每日定时发版的后台系统 |
| 86400 | 极低 | 一天滞后 | 几乎不变的文档库 |
结合业务频率给出配置建议
经验上,先统计自己站点前端资源的实际变更频率。如果每周只改一次,那么设成一天也无妨;如果每天高峰前发一次版,可以设成7200秒左右,保证两次发版之间用户不被无效推送,又能在当天第二次发布后逐步覆盖。若是持续集成、随时上线的业务,建议缩到600到1800秒,用稍多一点的带宽换时效性。
另外要注意,http2_push_diary_max_age只管“日记过期”,并不控制资源本身在浏览器里的缓存。真正让用户拿到新文件,还需配合正确的Cache-Control与文件哈希命名。只有推送日记时效和资源缓存策略一起设计,才能既不浪费推送,也不让用户卡在旧版本上。
常见误区与排查方法
一个典型误区是以为调大这个指令能“强制”用户更新。其实完全相反,它只是让服务器少推,浏览器端若已有旧推送资源且缓存未过,仍不会主动来要新的。遇到用户说“上线了但没变”,先查是不是日记年龄太长,再查资源URL是否带版本号。
排查时可在Nginx开启debug日志,观察push diary相关记录,看某连接是否因为diary命中而跳过推送。若发现命中率过高且更新总延迟,就调小max_age;若发现反复推送导致带宽异常,就适当调大。用真实访问数据反推,比盲目抄默认值更稳妥。
总结来说,http2_push_diary_max_age最大年龄不是越大越好也不是越小越灵,它是推送日记的生命周期开关。把它当成业务更新节奏的映射,才能发挥HTTP/2推送的真正价值。
Nginxhttp2_push_diary_max_ageHTTP2_server_push修改时间:2026-08-10 10:51:27