HTTP/2的Server Push曾经被寄予厚望,很多团队在Nginx里配置了http2_push之后却发现效果时好时坏,其中一个容易被忽视的细节就是推送日记的匹配机制。Nginx通过一份日记表来记录已经推送过哪些资源,避免对同一个连接重复推送,而http2_push_diary_encrypt指令正是控制这份日记是以明文还是加密形式存储和匹配的关键开关。理解它不仅能解释一些奇怪的表现,还关系到传输过程中的信息暴露问题。

推送日记到底是什么,为什么需要加密
当服务端执行一次推送时,Nginx需要记住这个连接上已经推送过哪些资源路径,这份记录就是所谓的push diary,中文一般叫推送日记。它的作用很直接:如果浏览器在解析HTML后又主动请求了某个CSS文件,而这个文件已经被推送过,Nginx就不应该再推送一次,否则会造成带宽浪费。日记的匹配方式是计算请求路径的哈希值并和日记中已有的条目比对。
按照HTTP/2协议RFC 7540的描述,这个日记哈希在实现上建议做异或加密处理。原因在于,如果日记以明文哈希存在并且直接参与协商,中间观察者理论上可以通过穷举常见路径的方式推断出客户端曾经请求过哪些资源,这属于一种隐私泄露。http2_push_diary_encrypt就是Nginx提供的开关,打开后日记条目会以加密形式编码,匹配时同样在加密域内完成,不暴露原始哈希。
需要注意一点:日记是按连接维度维护的,HTTP/2连接复用时间越长,日记积累的条目越多,加密匹配带来的计算开销也就越明显。因此在高并发短连接场景下开启它,收益和成本都要权衡。
http2_push_diary_encrypt的语法与配置示例
这个指令非常简单,只有on和off两个取值,默认值是off。它可以配置在http、server两个层级,语法如下:
语法: http2_push_diary_encrypt on | off; 默认值: http2_push_diary_encrypt off; 上下文: http, server
下面给一个相对完整的配置片段,把推送相关的几个指令一起演示,方便对照理解:
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;
# 开启推送日记加密
http2_push_diary_encrypt on;
# 限制并发推送数量,防止瞬间打满带宽
http2_max_concurrent_pushes 10;
# 主动推送样式和脚本
location / {
root /var/www/site;
http2_push /css/main.css;
http2_push /js/app.js;
# 使用preload响应头方式推送,适合动态内容
add_header Link "</css/main.css>; as=style; rel=preload";
}
}配置完成后用nginx -t检查语法,再通过nginx -s reload平滑重载。验证是否生效可以用curl加--http2参数观察PUSH_PROMISE帧,或者用浏览器的开发者工具查看推送的资源。如果想确认日记加密是否真的开启,可以抓包对比日记条目的编码,开启后条目不再是裸哈希形态。
常见问题与排查思路
第一个高频问题是配置后reload报错,提示unknown directive。http2_push_diary_encrypt是在Nginx 1.15.9版本才引入的,如果你的Nginx版本低于这个数,指令根本不存在。先用nginx -V查看编译版本和参数,同时确认编译时带了--with-http_v2_module,否则整个HTTP/2功能都不可用。
第二个问题是推送没有生效。这往往不是日记加密的锅,而是链路上有代理剥离了HTTP/2,或者浏览器主动禁用了推送。Chrome从106版本起就已经禁用了HTTP/2和HTTP/3的服务端推送,所以现在测试Server Push更多是用curl或专门支持推送的客户端,例如:
# 用curl测试服务端推送,-k 忽略自签名证书 curl -k --http2 -I https://127.0.0.1/ -v 2>&1 | grep -i push
第三个问题是开启加密后性能略有下降。日记匹配从简单的整数比较变成了加密域内的比对,条目越多开销越大。如果你的站点推送资源数量不多(一般几十个以内),这点开销可以忽略;如果确实敏感,可以考虑关闭加密换取性能,但要清楚其中的隐私取舍。
总的来说,http2_push_diary_encrypt是一个小而专的指令,本身不复杂,但它背后涉及HTTP/2推送的匹配机制和隐私设计。配置时确认版本、确认模块、配合合理的并发推送限制,基本就能稳定运行。随着浏览器侧对Server Push支持度的下降,如果你在做新架构,也可以评估用103 Early Hints或标准的preload来替代推送,这已经是目前更主流的做法。
Nginxhttp2_push_diary_encryptHTTP/2 Push修改时间:2026-09-07 03:10:27