通过nginx custom_log统计websocket连接成功率与握手耗时,需配置log_format包含$status、$upstream_http_upgrade、$request_time等字段,并在location中启用proxy_http_version 1.1及upgrade/connection头透传;成功率=(status=101且upgrade=websocket的请求数)/总websocket请求($http_upgrade~*websocket),平均耗时=所有101响应的$request_time均值。

要通过 custom_log 统计 WebSocket 连接成功率与握手耗时,核心是让反向代理(如 Nginx)在 WebSocket 握手完成或失败时,记录关键字段:状态码、上游响应时间、协议升级结果。Nginx 本身不直接暴露“WebSocket 握手是否成功”,但可通过 $status、$upstream_http_upgrade、$request_time 等变量组合判断。
确认 Nginx 已启用 custom_log 并捕获必要变量
Nginx 的 log_format 需显式包含以下字段:
-
$status:HTTP 响应状态码(101 表示握手成功;4xx/5xx 表示失败) -
$upstream_http_upgrade:后端返回的Upgrade头内容(通常为websocket),可辅助验证是否真正完成协议升级 -
$request_time:从收到请求头到发送完响应头的总耗时(单位秒,精度毫秒),即握手阶段耗时的合理近似值 -
$http_upgrade和$http_connection:用于过滤真实 WebSocket 请求(需含Upgrade: websocket和Connection: Upgrade)
示例配置:
log_format ws_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'$request_time $upstream_http_upgrade '
'"$http_upgrade" "$http_connection"';定义 location 并启用 proxy_set_header 升级支持
确保 WebSocket 请求被正确转发且头部透传,否则 $upstream_http_upgrade 可能为空:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 必须设置
proxy_http_version 1.1和proxy_set_header Upgrade $http_upgrade - 必须设置
proxy_set_header Connection "upgrade"(注意加引号,避免被覆盖为close) - 建议加上
proxy_read_timeout 86400防止空闲断连干扰统计
示例:
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
access_log /var/log/nginx/ws_access.log ws_log;
}用日志解析区分成功/失败连接并计算耗时
握手成功的典型日志行特征:$status == 101 且 $upstream_http_upgrade == "websocket";失败则多为 400、401、502、504 等,且 $upstream_http_upgrade 为空或非 websocket。
- 成功率 = (status=101 且 upgrade=websocket 的请求数) ÷ 总 WebSocket 请求(满足
$http_upgrade ~* websocket) - 平均握手耗时 = 所有 status=101 日志的
$request_time平均值(单位秒) - 建议用 awk / grep / prometheus + nginxlog-exporter 等工具实时聚合,例如:
# 统计成功率(假设日志格式固定,字段按空格分隔)
awk '$6 == "101" && $8 == "websocket" {s++} $7 ~ /websocket/ {t++} END {printf "success rate: %.2f%\n", s/t*100}' ws_access.log注意边界情况与精度限制
$request_time 包含 Nginx 自身处理开销(如 DNS 解析、SSL 握手),并非纯后端握手耗时;若需更精确的后端处理时间,可用 $upstream_response_time 替代(但该变量在 101 响应中可能不生效,取决于 Nginx 版本和 upstream 行为)。
- Nginx 1.19.1+ 对 101 响应开始支持
$upstream_response_time,旧版本建议以$request_time为主并做基线校准 - 客户端未完成 Upgrade(如半路断开 TCP)可能产生 499 状态,也应计入失败
- 避免将 HTTP 长轮询或 SSE 请求误判为 WebSocket,严格依赖
$http_upgrade字段过滤










