优化 OpenResty 的性能
上代码,本站和众多站长用的都是类似的优化,大家可以根据自己的需求稍微改一改。
一、基础架构与配置优化
1. 进程模型与I/O优化
worker_processes auto; # 自动匹配CPU核心数
worker_cpu_affinity auto; # CPU亲和性,减少上下文切换
worker_rlimit_nofile 65535; # 提升单进程文件描述符限制
events {
worker_connections 16384; # 高并发连接数
use epoll; # Linux下高性能I/O模型
multi_accept on; # 一次性接受所有连接
}2. HTTP协议与传输优化
http {
sendfile on; # 零拷贝文件传输
tcp_nopush on; # 优化数据包发送(需配合sendfile)
tcp_nodelay on; # 禁用Nagle算法,降低延迟
keepalive_timeout 65s; # 长连接超时
keepalive_requests 1000; # 单个连接最大请求数
client_body_buffer_size 128k; # 请求体缓冲区
client_max_body_size 100m; # 最大请求体大小
server_tokens off; # 隐藏Nginx版本信息
}3. 内核参数调优
修改/etc/sysctl.conf后执行sysctl -p生效:
fs.file-max = 1000000 # 系统级文件描述符限制
net.ipv4.tcp_tw_reuse = 1 # 复用TIME_WAIT连接
net.ipv4.tcp_keepalive_time = 600 # TCP保活时间
net.ipv4.tcp_fin_timeout = 30 # FIN_WAIT_2状态超时二、Lua脚本与性能敏感操作
1. 内存与变量管理
-- 避免全局变量,使用局部变量
local re_find = ngx.re.find -- 预编译正则表达式
local ok, err = re_find("pattern", "text", "jo") -- 'j'标志启用缓存
-- 高效字符串拼接
local parts = {"a", "b", "c"}
local result = table.concat(parts) -- 优于"a".."b".."c"2. 模块化与响应时间监控
封装响应时间计算模块(timer.lua):
local timer = {}
function timer.get_execution_time(start_time, end_time)
return string.format("%.2f", (end_time - start_time) * 1000) -- 毫秒级
end
return timer使用示例:
local timer = require "timer"
local start_time = ngx.now()
-- 业务逻辑
local end_time = ngx.now()
ngx.header["X-Execution-Time"] = timer.get_execution_time(start_time, end_time) .. "ms"三、多级缓存与数据层优化
1. 共享内存缓存
http {
lua_shared_dict cache 100m; # 100MB共享内存
}Lua 操作示例:
local cache = ngx.shared.cache
local value = cache:get("key")
if not value then
value = generate_data() -- 动态生成数据
cache:set("key", value, 60) -- 缓存60秒
end2. Redis连接池与异步操作
local redis = require "resty.redis"
local red = redis:new()
red:set_timeouts(1000, 2000, 3000) -- 连接/发送/读取超时(毫秒)
local ok, err = red:connect("127.0.0.1", 6379)
if ok then
red:set_keepalive(10000, 100) -- 连接池复用
end3. MySQL查询优化
结合lua-resty-mysql实现非阻塞查询:
local mysql = require "resty.mysql"
local db = mysql:new()
db:set_timeout(2000) -- 2秒超时
local res, err = db:query("SELECT * FROM banners WHERE status=1") -- 轮播图查询示例四、异步编程与动态控制
1. 动态黑名单(共享内存+Redis)
http {
lua_shared_dict blacklist 10m; # 10MB共享内存
init_worker_by_lua_block {
local delay = 5 -- 5秒同步一次Redis黑名单
local function update_blacklist()
local red = redis:new()
red:connect("127.0.0.1", 6379)
local keys = red:smembers("blacklist_keys")
ngx.shared.blacklist:flush_all()
for _, key in ipairs(keys) do
ngx.shared.blacklist:set(key, true)
end
end
local ok, err = ngx.timer.every(delay, update_blacklist)
end
}访问控制:
if ngx.shared.blacklist:get(ngx.var.remote_addr) then
ngx.exit(ngx.HTTP_FORBIDDEN) -- 拦截黑名单IP
end2. Cosocket非阻塞调用
local sock = ngx.socket.tcp()
sock:settimeouts(1000, 2000, 3000) -- 连接/发送/读取超时
local ok, err = sock:connect("backend.com", 80)
if ok then
sock:send("GET /api HTTP/1.1\r\nHost: backend.com\r\n\r\n")
local data, err = sock:receive("*a")
sock:close()
end五、完整配置模板(nginx.conf)
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;
events {
worker_connections 16384;
use epoll;
multi_accept on;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65s;
keepalive_requests 1000;
client_body_buffer_size 128k;
client_max_body_size 100m;
server_tokens off;
# 共享内存
lua_shared_dict cache 100m;
lua_shared_dict blacklist 10m;
# Lua模块路径
lua_package_path "/usr/local/openresty/lualib/?.lua;;";
lua_package_cpath "/usr/local/openresty/lualib/?.so;;";
# 初始化脚本
init_worker_by_lua_file /path/to/init_blacklist.lua;
server {
listen 80;
location /api {
access_by_lua_block {
-- 黑名单检查
if ngx.shared.blacklist:get(ngx.var.remote_addr) then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
}
content_by_lua_file /path/to/api_handler.lua;
}
}
}六、性能监控与调优建议
指标监控
通过
X-Execution-Time响应头跟踪 API 耗时使用 Prometheus 插件(如 APISIX)监控 QPS 和延迟
压测工具
wrk或ab模拟高并发请求,调整参数至最优
持续调优
根据业务场景动态调整超时时间(如 Redis 查询从 1 秒放宽至 2 秒)
定期分析
error_log和access_log优化异常请求
实际部署时需结合业务需求微调参数。
下面是我自己的服务器的配置参数:
server {
listen 443 ssl http2 ;
listen 443 quic ;
listen [::]:443 ssl http2 ;
listen [::]:443 quic ;
server_name uniomo.com www.uniomo.com;
index index.php index.html index.htm default.php default.htm default.html;
access_log /www/sites/uniomo/log/access.log main;
error_log /www/sites/uniomo/log/error.log;
# 安全防护:隐藏版本号
server_tokens off ;
location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md) {
return 404;
}
location ^~ /.well-known/acme-challenge {
allow all;
root /usr/share/nginx/html;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 65s;
client_max_body_size 50M;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:8090;
}
http2 on;
if ($scheme = http) {
return 301 https://$host$request_uri;
}
ssl_certificate /www/sites/uniomo/ssl/fullchain.pem;
ssl_certificate_key /www/sites/uniomo/ssl/privkey.pem;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-SM2-SM4-GCM-SM3:ECDHE-ECDSA-AES256-GCM-SHA384:X25519MLKEM768:SecP256r1MLKEM768:ML-DSA-65:SLH-DSA-SHAKE-256;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_stapling on; # 启用OCSP装订加速证书验证
ssl_stapling_verify on;
error_page 497 https://$host$request_uri;
proxy_set_header X-Forwarded-Proto https;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
limit_conn perserver 30000;
limit_conn perip 300;
limit_rate 51200k;
add_header Alt-Svc 'h3=":443"; ma=2592000';
real_ip_recursive on;
set_real_ip_from 0.0.0.0/0;
set_real_ip_from ::/0;
real_ip_header X-Forwarded-For;
# HTTP/3与Alt-Svc通告优化
add_header Alt-Svc 'h3=":443"; h3-29=":443"; ma=2592000'; # 明确支持HTTP/3草案版本
# 连接限制与速率控制(调整参数)
location ~ .*\.(js|css|png|jpg|jpeg|gif|webp|webm|avif|ico|bmp|swf|eot|svg|ttf|woff|woff2)$ {
expires 30d;
access_log off;
log_not_found off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8090;
}
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS,PUT,DELETE always;
if ( $request_method = 'OPTIONS' ) {
return 204;
}
}优化 OpenResty 的性能
https://uniomo.com/archives/openresty-de-ji-zhi-you-hua-fang-an