站点有三千多条跳转规则,压测显示每个请求在 Nginx 阶段多花四十毫秒,QPS 到八百就上不去,CPU 却只用了三成。碰到这种情况,我一般先确认改动有没有真的生效。

原因不复杂,rewrite 规则是逐条顺序匹配的,请求要走到最后一条才发现不匹配。规则里还混着大量正则和 if,每条都要编译执行一遍。

碰到「rewrite 性能」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。改完顺手把文档补一句,省得下次自己重新推一遍。

nginx -T | grep -c 'rewrite '
ab -n 2000 -c 50 https://example.com/guide/hello/
# 对比精简规则前后的 Time per request

监控和日志的时间要对上,时区不一致会多绕很大一圈。临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。

具体做法是,把高频规则提到最前面,冷门规则按前缀合并成一条;能用 map 做的判断别用一堆 if,map 只在加载时算一次;把整段规则按域名或目录拆到不同 server 块,减少单次匹配条数;改完用 ab 或 wrk 对比同一路径的耗时。

最后用这个标准收尾,同一路径的请求耗时回到十毫秒级,QPS 到两千时 CPU 才过半。

作者 9823189