$server_protocol 是 Nginx 记录客户端请求协议版本的内置变量,值为 HTTP/1.0、HTTP/1.1 或 HTTP/2.0,是区分 HTTP 版本最可靠且低开销的依据,但 CDN 回源时可能不反映真实客户端协议。
$server_protocol 是 Nginx 内置变量,用于记录客户端发起请求时使用的协议版本(如 HTTP/1.1 或 HTTP/2.0),它在 access log 中可直接输出,是区分 HTTP/1.x 与 HTTP/2 请求最可靠、开销最小的依据。
Nginx 中该变量返回的是协议字符串,常见值包括:
HTTP/1.0HTTP/1.1HTTP/2.0(注意:即使客户端使用 HTTP/2,Nginx 也统一记为 HTTP/2.0,而非 h2)可通过临时添加日志字段验证:
log_format debug_log '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$server_protocol"';推荐将协议信息作为独立字段写入日志,便于后续解析与筛选。例如:
log_format http_version '$remote_addr [$time_local] "$request_method $uri $server_protocol" $status $body_bytes_sent $request_time "$http_user_agent" $server_protocol';这样每条日志末尾都明确标注协议,无需解析 request line,避免因 URI 中含空格或特殊字符导致误切分。
以常见工具为例:
protocol 字段(正则:"(?P<protocol>HTTP/[0-9].[0-9])"$),再用 KQL 或 LogQL 按 protocol : "HTTP/2.0" 过滤,并聚合 uri 或 path
$server_protocol 转为 label,再构建 nginx_http_requests_total{protocol="HTTP/2.0", path="/api/v1/users"} 类型指标HTTP/2 在 Nginx 中仅支持通过 HTTPS 启用(RFC 7540 要求),因此若看到 $server_protocol == "HTTP/2.0",必对应 TLS 连接;而 HTTP/1.1 可能来自 HTTP 或 HTTPS。这意味着:
$scheme(http/https)判断协议版本$ssl_protocol 与 $ssl_cipher,排查是否因 TLS 版本或 ALPN 协商失败导致降级到 HTTP/1.1HTTP/1.1,$server_protocol 不反映客户端真实协议,需结合 $http_upgrade 或 CDN 自定义 header 判断