$connection 不适合直接用于负载追踪,因其仅为单 worker 内单调递增的连接 id,不携带进程信息、不反映活跃状态、无法跨 worker 对齐;需结合 $pid、$connection_requests 及 stub_status 或 vts 模块实现真实负载观测。

在 Nginx 中,$connection 是一个内置变量,表示当前连接的唯一整数 ID(从 1 开始递增,进程重启后重置),但它**本身不能直接用于追踪 Worker 间并发连接的负载分布**。原因在于:$connection 是连接级标识,不携带 Worker 进程信息,也不反映连接活跃状态或持续时间;且它在不同 worker 进程中独立计数,无法跨进程对齐或聚合。
为什么 $connection 不适合直接做负载追踪
$connection 的设计初衷是日志调试和连接生命周期标记,不是负载指标。它的值只在单个 worker 内单调递增,比如 worker 0 的连接 ID 是 1,2,3…,worker 1 的也是 1,2,3…——你无法靠它区分“哪个 worker 承载了更多活跃连接”。同时,它不随连接关闭而回收,也不与请求、SSL 会话或 upstream 关联,单独记录意义有限。
真正可行的并发负载观测方案
要实际掌握各 worker 的并发连接负载,需结合 Nginx 内置状态 + 外部工具,而非仅依赖 log_format:
-
启用 stub_status 模块并按 worker 暴露指标:编译时确保含
--with-http_stub_status_module,为每个 worker 绑定独立监听端口(如用 systemd socket 激活或 stream 模块反向代理到不同端口),再通过/basic_status获取Active connections实时值 -
用 nginx-module-vts(Virtual Host Traffic Status):支持按 worker 分组统计,提供 JSON 接口返回每个 worker 的
connections.active、connections.idle等,可被 Prometheus 抓取 -
结合 $pid + $connection 记录连接归属:在 log_format 中加入
$pid,例如:log_format conn_log '$pid:$connection [$time_local] "$request" $status $body_bytes_sent';
这样每条日志带上了 worker 进程 PID 和该 worker 内的连接 ID,便于离线分析连接创建频次、平均存活时间等趋势(需配合日志采集系统做 group by pid) -
用共享内存 zone 统计实时并发:通过
limit_conn_zone $binary_remote_addr zone=addr:10m类机制虽不直接暴露 worker 维度,但配合limit_conn_status和自定义 error log,可间接识别连接拒绝发生在哪个 worker(需开启daemon off调试模式观察)
如果坚持写入 access_log,推荐这样增强可观测性
仅靠 $connection 不够,但可组合关键变量提升诊断价值:
- 记录连接建立时间:
$time_iso8601或$msec,用于计算连接生命周期 - 标记请求是否复用连接:
$connection_requests(该连接已处理请求数),值为 1 表示新连接,>1 表示 keepalive 复用 - 添加 worker 标识:
$pid(必须)+ 可选$worker_pid(Nginx 1.19.5+ 支持) - 示例 log_format:
log_format debug_conn '$pid:$connection:$connection_requests [$time_local] "$request" $status $connection_requests';
不复杂但容易忽略:$connection 的价值不在单点数值,而在它与 $pid、$connection_requests 的组合,能还原出每个 worker 内连接的“新鲜度”和复用效率——这才是负载不均的真实线索。










