nginx内置js模块实现访问量统计
				
									
					
					
						|  | 
							admin 2025年8月23日 22:53
								本文热度 697 | 
					
				 
				一、统计实现
js 统计访问量,utils.js:
/**
 * 查询访问总量
 */
function getNum(key) {
   let num = ngx.shared.num.get(key);
   return num ?? 0;
}
/**
 * 记录访问量
 */
function record(r, data, flags) {
 // 在最后一个数据块时增加一次请求数量
 if (flags && flags.last) {
    let key = "request_num";
    let num = getNum(key);
    num++;
    // 保存到共享内存中
    ngx.shared.num.set(key, num);
  }
  r.sendBuffer(data, flags);
}
function query(r) {
  return getNum("request_num");
}
export default { record, query };
nginx 配置:
http {
    # 设置一块共享内存区域,用于保存请求数量
    js_shared_dict_zone zone=num:512K type=number state=/var/nginx/num.json;
    # js文件路径
    js_path "/usr/local/nginx/njs";
    # 导入js统计模块
    js_import utils.js;
    server {
        listen 89;
        server_name localhost;
        location / {
            # 记录请求数,其它需要统计访问量的location相同配置,js_body_filter指令不能配置中http中
            js_body_filter utils.record;
            root html;
            index index.html index.htm;
        }
        location /stat {
            default_type text/plain;
            charset utf-8;
            # 统计接口/stat的访问没有计算到访问总量中
            # js_body_filter utils.record;
            # 获取请求数总量
            js_set $request_num utils.query;
            return 200 "总请求量:$request_num";
        }
    }
}
二、测试
- 安装压测工具, - sudo yum install httpd-tools
 
- 发送 200 个请求, - ab -n 200 -c 5 http://localhost:89/
 
- 接口查看访问量, - curl http://localhost:89/stat, 返回- 总请求量:200
 
- 查看 state 文件中的访问量,- cat /var/nginx/num.json,返回- {"request_num":{"value":200.000000,"expire":2819531276}}
 
- 重启 nginx 验证,共享数据是否仍然存在,reload 后数据不会丢失,stop 再启动数据丢失。 
三、按客户端地址统计访问量
js 方法中记录统计量的 key 改为远程地址:
/**
 * 查询访问总量
 */
function getNum(key) {
  let num = ngx.shared.num.get(key);
  return num ?? 0;
}
/**
 * 记录访问量
 */
function record(r, data, flags) {
 // 在最后一个数据块时增加一次请求数量
 if (flags && flags.last) {
    let key = r.variables.remote_addr;
    let num = getNum(key);
    num++;
    // 保存到共享内存中
    ngx.shared.num.set(key, num);
  }
  r.sendBuffer(data, flags);
}
export default { record };
获取统计量,直接返回 state 对应的 json 文件:
http {
    js_shared_dict_zone zone=num:512K type=number state=/var/nginx/stat.json;
    js_path "/usr/local/nginx/njs";
    js_import utils.js;
    server {
        listen 89;
        server_name localhost;
        location / {
            # 记录请求数
            js_body_filter utils.record;
            root html;
            index index.html index.htm;
        }
        location /stat {
            default_type application/json;
            charset utf-8;
            alias /var/nginx/;
            try_files stat.json '';
        }
    }
}
四、相关知识
阅读原文:原文链接
该文章在 2025/8/25 13:31:23 编辑过