Nginx 中访问日志如何记录服务启动以来的累计请求总数

作者:袖梨 2026-08-23

Nginx无内置全局累计请求数,但可通过stub_status模块获取实时总数、日志聚合工具长期统计、或OpenResty共享字典计数器实现;$request_number仅表单连接内序号,非全局值。

Nginx 本身不直接提供“自启动以来累计请求总数”的内置计数器,也无法在 access_log 中自动写入一个递增的全局请求数。但可以通过几种实用方式间接实现该目标,核心思路是:将请求计数从日志生成环节转移到外部统计或运行时变量环节。

使用 $request_number 变量(单次连接内序号,非全局)

$request_number 是 Nginx 1.11.0+ 提供的变量,表示当前 TCP 连接中第几个请求(HTTP/1.1 keepalive 或 HTTP/2 多路复用下会递增),但它不是服务级累计值,重启后归零,且每个连接独立计数。例如:

log_format count_log '$request_number - $remote_addr - $time_local - "$request"';

这只能用于调试连接行为,不能替代全局累计请求统计。

借助 Nginx 的 stub_status 模块(实时只读,不记录到日志)

启用 ngx_http_stub_status_module 后,可通过 /nginx_status 端点获取实时指标,其中 “Requests” 行显示的就是自启动以来的总请求数

  1. 需编译时包含该模块(大多数预编译包已启用)
  2. 配置示例:
    location /nginx_status {

    stub_status on;

    allow 127.0.0.1;

    deny all;

    }

  3. 访问 curl http://localhost/nginx_status 输出类似:

    Active connections: 3

    server accepts handled request

    123456 123456 789012

    最后一列 789012 即为累计请求数

用 log_format + 日志聚合工具统计(推荐用于长期累计)

这是最可靠、生产常用的方式:让 Nginx 正常记录每条请求,再由外部工具(如 awk、logrotate 配合计数脚本、或 ELK/Prometheus)汇总解析日志文件,得出总量。

  1. 确保 access_log 未被轮转覆盖(或配合 logrotate 归档策略保留历史)
  2. 简单统计命令:wc -l /var/log/nginx/access.log*(注意:若日志含多行记录如 JSON 或带换行的 UA,需更精准解析)
  3. 更健壮做法:用定时任务每日追加计数到一个 total_requests.log,或用 Prometheus + nginx-vts-exporter 实现指标持久化与监控

通过 Lua 模块(openresty)维护共享字典计数器

如果使用 OpenResty 或编译了 ngx_http_lua_module,可在内存中维护一个跨 worker 的原子计数器:

  1. 定义 shared dict:lua_shared_dict req_counter 10m;
  2. 在 log_by_lua_block 中递增:
    log_by_lua_block {

    local dict = ngx.shared.req_counter

    dict.inc("total", 1)

    }

  3. 再通过 Lua API 或自定义 endpoint 暴露该值,或定期写入文件
  4. 优势:低延迟、进程间共享;缺点:重启丢失(除非额外落盘),需谨慎处理 worker 初始化

相关文章

精彩推荐