7.9.6 性能优化与故障排查
围绕 OpenResty 的性能优化与故障排查,应从请求链路、Lua 执行、网络与系统资源、模块配置四个维度建立方法论。目标是降低延迟、提升吞吐、控制资源占用并提高可观测性与可恢复性。
原理草图(请求链路与关键耗时点):
一、性能优化要点(含配置示例与命令)#
1. 连接与事件模型#
关键目标:提高并发能力,减少连接排队。
配置示例(/etc/nginx/nginx.conf):
worker_processes auto;
worker_rlimit_nofile 200000;
events {
worker_connections 65535;
use epoll;
multi_accept on;
accept_mutex off;
}
http {
keepalive_timeout 30s;
keepalive_requests 10000;
upstream backend {
server 10.0.0.11:8080 max_fails=2 fail_timeout=5s;
server 10.0.0.12:8080 max_fails=2 fail_timeout=5s;
keepalive 256;
}
}
命令解释与预期:
# 查看当前进程打开文件数限制
ulimit -n
# 预期:>= 100000(与 worker_rlimit_nofile 匹配)
# 查看实际 worker 进程数与连接数
ps -ef | grep nginx
ss -lntp | grep nginx
2. Lua 运行时优化#
关键目标:减少 Lua 内存分配与阻塞。
示例(/etc/nginx/conf.d/lua_opt.conf):
server {
listen 8080;
location /lua {
content_by_lua_block {
local ngx = ngx
local say = ngx.say
local t = ngx.now()
-- 避免频繁创建表,缓存函数引用
say("time=", t)
}
}
}
Lua 调试与基准测试:
# 使用 resty 验证脚本
resty -e 'local ngx=ngx; ngx.say("ok")'
# 预期:输出 ok
3. 共享字典与缓存#
关键目标:提升热点数据命中率,减少回源。
示例:
lua_shared_dict hot_cache 100m;
server {
listen 8080;
location /cache {
content_by_lua_block {
local dict = ngx.shared.hot_cache
local v = dict:get("key")
if not v then
v = "value_from_backend"
dict:set("key", v, 5) -- TTL 5s
end
ngx.say(v)
}
}
}
监控共享字典:
# 查看共享字典使用情况
grep "lua_shared_dict" -n /etc/nginx/nginx.conf
# 通过自定义日志或指标输出 used/evictions(见监控部分)
4. I/O 与阻塞控制#
关键目标:避免同步阻塞导致 worker 堵塞。
示例(超时配置):
lua_socket_connect_timeout 1000ms;
lua_socket_read_timeout 2000ms;
proxy_connect_timeout 1s;
proxy_read_timeout 2s;
5. 静态资源优化#
关键目标:减少系统调用与 TCP 交互。
location /static/ {
root /data/www;
sendfile on;
tcp_nopush on;
open_file_cache max=10000 inactive=30s;
open_file_cache_valid 60s;
}
二、故障排查路径(含命令与日志)#
1. 高延迟#
排查步骤:
1) 查看错误日志是否出现超时
tail -f /var/log/nginx/error.log
# 关注:upstream timed out, lua socket read timeout
2) 分析请求耗时字段
# 自定义日志格式包含 request_time/upstream_response_time
grep "request_time" /var/log/nginx/access.log | tail
3) 验证上游 RTT
ping -c 3 10.0.0.11
curl -w "%{time_total}\n" -o /dev/null -s http://10.0.0.11:8080/health
2. 502/504#
排查步骤:
# 查看上游健康状态
curl http://10.0.0.11:8080/health
# 检查 upstream 连接
ss -s
可能原因:
- 上游实例不可用
- DNS 解析失败
- 连接耗尽
3. QPS 下降#
排查步骤:
# 查看进程是否频繁 reload
grep "reload" /var/log/nginx/error.log
# 查看 CPU/内存
top -H -p $(pidof nginx | tr ' ' ,)
4. 内存增长#
排查步骤:
# 进程内存观察
pmap -x $(pidof nginx | awk '{print $1}')
# 检查 lua_shared_dict 变化(需要自定义埋点/监控)
5. 连接耗尽#
排查步骤:
ss -ant state time-wait | wc -l
ss -ant state syn-recv | wc -l
sysctl net.core.somaxconn
三、监控与可观测性(示例)#
1. stub_status#
location /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}
2. 自定义访问日志格式#
log_format main '$remote_addr $request '
'rt=$request_time urt=$upstream_response_time '
'status=$status';
access_log /var/log/nginx/access.log main;
四、常见排错工具安装与使用#
# CentOS/RHEL
yum install -y htop sysstat lsof strace
# Ubuntu/Debian
apt-get install -y htop sysstat lsof strace
工具说明:
- pidstat -p <pid> 1:查看 CPU/IO 使用
- strace -p <pid>:分析系统调用阻塞点
- lsof -p <pid>:查看文件/连接占用
五、回滚与恢复策略(操作示例)#
# 1) 检查配置
nginx -t
# 2) 备份配置
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.$(date +%F)
# 3) 平滑重载
nginx -s reload
# 4) 快速回滚
cp /etc/nginx/nginx.conf.bak.2024-01-01 /etc/nginx/nginx.conf
nginx -s reload
六、练习题#
1) 在 OpenResty 中配置 stub_status 并用 curl 获取连接状态,解释 Active/Reading/Writing/Waiting 含义。
2) 使用 log_format 增加 request_time 与 upstream_response_time,观察是否存在高延迟请求。
3) 配置 lua_shared_dict 并实现一个 5 秒 TTL 的缓存示例。
4) 模拟上游超时(将 proxy_read_timeout 调小),观察 error.log 中错误信息并解释原因。
5) 使用 ss -s 分析连接状态,判断是否存在连接耗尽风险。