Nginx/OpenResty 反代配置最佳实践
我一开始用的是 Nginx 后来全换成了 OpenResty。原因很简单:OpenResty 就是 Nginx + Lua,灵活度不是一个量级的。
这篇讲讲我这一年多踩过的反代坑和最终稳定运行的配置。
为什么选 OpenResty
最初装 Nginx 是因为"大家都在用",后来发现几个痛点:
1. 动态 upstream 管理 — Nginx 改完配置要 nginx -s reload,高峰期 reload 会短暂影响服务。OpenResty 可以用 Lua 动态添加/删除 upstream,不 reload
2. 限流、防爬、认证 — 这些功能 Nginx 要装模块,OpenResty 内置 Lua + Redis / Memcached,随手写几行代码就能搞定
3. WAF 能力 — 简单的 CC 攻击拦截、SQL 注入检测,Lua 脚本几分钟写一个
我现在的反代层全跑在 OpenResty 上,后端 22 个容器基本都靠它转发。
基础反代配置
upstream halo_backend {
server halo:8090;
keepalive 32;
}
server {
listen 80;
server_name soulwrite.xyz;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name soulwrite.xyz;
ssl_certificate /etc/nginx/ssl/soulwrite.xyz.pem;
ssl_certificate_key /etc/nginx/ssl/soulwrite.xyz.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
location / {
proxy_pass http://halo_backend;
proxy_http_version 1.1;
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_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection "";
# 解决 WebSocket 问题
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
静态资源缓存
博客主要流量是 CSS/JS/图片,反代缓存能显著降低后端压力:
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff2?|ttf|eot)$ {
proxy_pass http://halo_backend;
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}
动态 Upstream(OpenResty+Lua)
有时候后端服务要重启或者迁移 IP,静态写死的 upstream 就不方便。我用 Lua 动态读取:
resolver 8.8.8.8 ipv6=off;
set_by_lua $backend '
local hosts = {
["halo"] = "halo:8090",
["alist"] = "alist:5244",
["ollama"] = "ollama:11434"
}
return hosts[ng.var.host] or "127.0.0.1:80"
';
这样改后端 IP 只需要改 Lua 代码,不用动 Nginx 配置。
踩坑记录
坑 1:WebSocket 断开
Halo 和有些服务用 WebSocket,最初没加 Upgrade 头,连接几秒就断。后来加上:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
问题解决。
坑 2:SSL 握手超时
某次加完 SSL 后部分客户端报 SSL_do_handshake() failed。查了一通发现是 TLS 版本和 Cipher 配置问题。改成上面配置里的写法,兼容性最好。
坑 3:Proxy Buffer 太小
博客文章里有大量内容时,后端响应被 OpenResty buffer 住导致超时。调大:
proxy_buffering on;
proxy_buffer_size 128k;
proxy_buffers 8 256k;
proxy_busy_buffers_size 256k;
完整配置目录结构
/opt/services/reverse-proxy/
├── docker-compose.yml
├── conf.d/
│ ├── halo.conf
│ ├── alist.conf
│ ├── ollama.conf
│ └── tools.conf
├── ssl/
│ ├── soulwrite.xyz.pem
│ └── soulwrite.xyz.key
└── nginx.conf (主配置)
总结
OpenResty 比 Nginx 灵活在哪:
- reload 零感知 — Lua 动态刷新
- 限流防爬 — 几行代码搞定
- WebSocket 原生支持
我现在 22 个服务全靠这一层反代,一个容器搞定所有转发,维护成本极低。
Nginx/OpenResty 反代配置最佳实践
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法