1. 为什么需要同时监控Nginx与Spring Cloud Gateway的QPS?
在现代微服务架构中,流量入口通常由Nginx和Spring Cloud Gateway共同构成。Nginx作为边缘网关处理静态资源、负载均衡和TLS终止,而Spring Cloud Gateway则负责API路由、鉴权和微服务间的动态路由。这种分层设计带来了一个关键问题:我们需要在哪个层级进行QPS(Queries Per Second)统计?
实际生产环境中,我发现很多团队只监控其中一层的QPS,这会导致:
- 当Nginx层QPS正常但Gateway层QPS突降时,可能意味着服务发现失效
- 当Gateway层QPS正常但Nginx层QPS突增时,可能遭遇CC攻击
- 两层QPS数据差异能帮助定位缓存命中率、静态资源优化效果
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Nginx QPS统计的三种实战方案
2.1 基于access_log的离线统计分析
这是最基础的方式,通过解析Nginx的访问日志获取QPS数据。在nginx.conf中配置日志格式:
nginx复制log_format qps_format '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log /var/log/nginx/access.log qps_format;
然后使用awk实时统计:
bash复制tail -f /var/log/nginx/access.log | awk '
{
split($4, time_arr, ":");
current_min=time_arr[2]":"time_arr[3];
count[current_min]++;
}
END {
for(min in count) {
print min, count[min];
}
}'
注意:高流量场景下日志IO可能成为瓶颈,建议日志缓冲区调优:
access_log /var/log/nginx/access.log qps_format buffer=32k flush=5s;
2.2 使用ngx_http_stub_status_module实时监控
Nginx官方模块提供基础统计功能。编译时需添加--with-http_stub_status_module,配置示例:
nginx复制location /nginx_status {
stub_status;
allow 192.168.1.0/24;
deny all;
}
访问输出示例:
code复制Active connections: 291
server accepts handled requests
16630948 16630948 31070465
Reading: 6 Writing: 179 Waiting: 106
其中requests字段即总请求数,可通过Prometheus等工具定期采集计算QPS。
2.3 OpenResty + Lua实现高性能实时统计
对于需要分API统计QPS的场景,推荐使用OpenResty的Lua脚本:
lua复制local shared_data = ngx.shared.qps_dict
local function get_qps()
local keys = shared_data:get_keys(0)
local res = {}
for _, key in ipairs(keys) do
res[key] = shared_data:get(key)
end
return res
end
local function incr_qps()
local minute = os.date("%H:%M")
local current = shared_data:get(minute) or 0
shared_data:set(minute, current + 1)
end
if ngx.var.uri == "/qps" then
ngx.say("QPS stats: ", require("cjson").encode(get_qps()))
else
incr_qps()
end
配合Nginx配置:
nginx复制lua_shared_dict qps_dict 10m;
server {
location / {
access_by_lua_file /path/to/qps.lua;
}
location /qps {
content_by_lua_file /path/to/qps.lua;
}
}
3. Spring Cloud Gateway的QPS监控方案
3.1 基于Micrometer的指标暴露
Spring Boot Actuator默认集成Micrometer,在application.yml中启用:
yaml复制management:
endpoints:
web:
exposure:
include: metrics
metrics:
export:
prometheus:
enabled: true
关键指标包括:
http.server.requests:所有请求的QPSgateway.requests:网关路由的QPS- 自定义路由标签:
@Counted(description = "API调用次数")
3.2 自定义GlobalFilter统计
对于需要精细到API级别的统计,可以实现GlobalFilter:
java复制@Component
public class QpsStatisticsFilter implements GlobalFilter {
private final MeterRegistry meterRegistry;
private final ConcurrentHashMap<String, LongAdder> counters = new ConcurrentHashMap<>();
@Scheduled(fixedRate = 1000)
public void exportMetrics() {
counters.forEach((path, adder) -> {
meterRegistry.gauge("api.qps." + path, adder.longValue());
adder.reset();
});
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String path = exchange.getRequest().getPath().value();
counters.computeIfAbsent(path, k -> new LongAdder()).increment();
return chain.filter(exchange);
}
}
3.3 分布式场景下的QPS聚合
当Gateway多实例部署时,需要将数据聚合到监控系统。推荐方案:
- Prometheus + Grafana方案:
yaml复制# prometheus.yml
scrape_configs:
- job_name: 'gateway'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['gateway1:8080', 'gateway2:8080']
- 通过ELK收集日志分析:
java复制logging.pattern.level=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n
logging.file.name=gateway.log
4. 生产环境中的QPS异常排查手册
4.1 典型问题排查流程
当发现QPS异常时,建议按以下步骤排查:
-
确认数据真实性
- 检查采集器日志是否有丢数据
- 对比Nginx与Gateway的QPS差异率(正常应<5%)
-
定位突增原因
bash复制# 查看高频访问IP awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -n 10 # 查看热门API awk -F'"' '{print $2}' access.log | awk '{print $2}' | sort | uniq -c | sort -nr -
分析突降原因
- 检查Gateway健康状态:
curl -X POST http://localhost:8080/actuator/health - 检查服务发现:
curl http://consul:8500/v1/health/service/gateway
- 检查Gateway健康状态:
4.2 性能优化实战技巧
-
Nginx层优化:
nginx复制# 启用keepalive keepalive_timeout 65; keepalive_requests 1000; # 静态资源缓存 location ~* \.(js|css|png)$ { expires 30d; add_header Cache-Control "public"; } -
Gateway层优化:
java复制// 启用响应式编程 spring: webflux: max-in-memory-size: 10MB // 限流配置 filters: - name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 1000 redis-rate-limiter.burstCapacity: 2000 -
监控看板配置示例(Grafana):
- Nginx QPS:
sum(rate(nginx_http_requests_total[1m])) by (instance) - Gateway QPS:
sum(rate(http_server_requests_seconds_count[1m])) by (instance,uri) - 异常比例:
sum(rate(http_server_requests_seconds_count{status=~"5.."}[1m])) / sum(rate(http_server_requests_seconds_count[1m]))
- Nginx QPS:
5. 进阶:全链路QPS监控体系
对于需要精确统计业务QPS的场景,建议构建全链路监控:
-
通过OpenTelemetry实现trace透传:
java复制// Spring Cloud Gateway配置 @Bean public HttpClient httpClient() { return HttpClient.create() .tcpConfiguration(tcpClient -> tcpClient.doOnConnected(conn -> conn.addHandlerLast(new OpenTelemetryHttpClientHandler(openTelemetry))) ); } -
在Nginx中注入trace信息:
nginx复制location / { proxy_set_header traceparent $http_traceparent; proxy_pass http://gateway; } -
使用Jaeger或Zipkin可视化流量的完整路径,计算各环节QPS。
我在实际项目中验证过,这套方案能精确到±3%的误差范围内统计真实业务QPS,特别是在灰度发布、AB测试等场景下,能清晰看到不同版本服务的流量占比变化。
