应使用 $server_protocol 变量记录实际应用层协议:HTTP/1.1 请求记为 HTTP/1.1,启用 http2 的 HTTPS 请求记为 HTTP/2.0,启用 QUIC 的 HTTP/3 请求记为 HTTP/3.0;配合自定义日志格式与 awk 统计即可准确分析各协议使用率。

要在 Nginx 访问日志中准确记录请求协议版本并分析 HTTP/2 与 HTTP/3 的使用率,关键不是记录“响应协议”,而是捕获客户端与 Nginx 协商达成的**实际应用层协议**。Nginx 提供了原生、可靠的变量来实现这一点,无需额外模块或复杂判断。
用 $server_protocol 记录真实协商协议
该变量自 Nginx 1.11.6 起原生支持,直接反映请求到达时解析出的协议字符串:
- HTTP/1.1 请求 → 值为 HTTP/1.1
- 启用
listen 443 ssl http2的 HTTPS 请求 → 值为 HTTP/2.0 - 启用 QUIC(如
listen 443 quic)的 HTTP/3 请求 → 值为 HTTP/3.0(需 Nginx ≥ 1.25.0 + 正确编译 QUIC 支持)
它不依赖 SSL 终止位置,也不受反向代理影响,在每个请求中稳定可用。不要用 $scheme(只分 http/https)或 $http2(仅布尔标识,不区分 HTTP/2 与 HTTP/3)替代。
配置日志格式并启用记录
在 http{} 块中定义含协议字段的日志格式:
log_format proto_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$server_protocol $request_time';然后在具体 server{} 块中启用(注意:必须放在 server 内,不能只写在 http 全局块):
server {
listen 443 ssl http2;
listen 443 quic; # 若启用 HTTP/3
server_name example.com;
ssl_certificate ...;
ssl_certificate_key ...;
<pre class="brush:php;toolbar:false;"><code>access_log /var/log/nginx/protocol.log proto_log;}
统计 HTTP/2 与 HTTP/3 使用率
日志写入后,用标准命令快速计算占比(假设协议字段为第11列):
- 查 HTTP/2 使用率:
awk '$11=="HTTP/2.0"{h++} {t++} END{printf "%.2f%%\n", h/t*100}' /var/log/nginx/protocol.log - 查 HTTP/3 使用率:
awk '$11=="HTTP/3.0"{h++} {t++} END{printf "%.2f%%\n", h/t*100}' /var/log/nginx/protocol.log - 合并统计各版本分布:
awk '{print $11}' /var/log/nginx/protocol.log | sort | uniq -c | sort -nr
若需小时级趋势,可配合 $time_local 提取时间戳做分组聚合,导入 Grafana 或 Excel 绘图观察变化规律。
验证与注意事项
重启 Nginx 后,用工具发起不同协议请求验证日志输出是否正确:
-
curl -v http://example.com→ 日志末尾应为 HTTP/1.1 -
curl -v --http2 https://example.com→ 应为 HTTP/2.0 -
curl -v --http3 https://example.com(需 curl ≥ 8.0 + 支持 HTTP/3)→ 应为 HTTP/3.0
注意:HTTP/3 需确保 Nginx 已启用 QUIC 模块(如基于 nginx-quic 补丁或官方 1.25+ with BoringSSL),且监听配置含 quic 关键字;否则 $server_protocol 不会输出 HTTP/3.0。


















