主题
外部 Nginx 反向代理配置
当在 IPAM 容器前端再部署一层外部 Nginx 反向代理(用于 HTTPS 卸载、域名转发等场景)时,必须对 SSE(Server-Sent Events)路径做特殊配置,否则监控页面会出现连接超时、数据延迟等问题。
背景说明
IPAM 的实时监控功能(主机监控、网络监控等)通过 SSE 向浏览器推送数据:
浏览器 ──HTTPS──▶ 外部 Nginx 代理 ──▶ 容器 Nginx (12380) ──▶ Go 后端 (12389)- 容器内部 Nginx 已内置 SSE 支持(
proxy_buffering off),无需额外配置 - 外部 Nginx 代理 默认启用响应缓冲,会缓存 SSE 流式数据,导致浏览器无法实时接收
⚠️ 关键点:问题出现在外层代理,而非容器内部 Nginx。即使容器配置正确,外层代理仍会阻断 SSE 实时推送。
问题现象
| 现象 | 说明 |
|---|---|
| SSE 连接建立耗时数十秒 | 浏览器 Network 面板显示 /api/monitor/* 请求长时间 pending |
| 监控数据不更新或严重延迟 | 首帧数据延迟到达,曲线停滞 |
| 刷新监控页面白屏 | SPA 路由未回退到 index.html,前端资源 404 |
解决方案
1. SSE 路径关闭缓冲
对外部 Nginx 代理的 /api/ 路径关闭 proxy_buffering 与 proxy_cache,并提升 HTTP 版本与读超时:
nginx
location /api/ {
proxy_pass http://127.0.0.1:12380;
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;
# SSE 必须:关闭缓冲与缓存,确保流式数据实时到达浏览器
proxy_buffering off;
proxy_cache off;
# HTTP/1.1 长连接,避免每次请求重新握手
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# SSE 长连接读超时(秒),需大于监控会话最长时长
proxy_read_timeout 86400;
}如仅需对监控接口生效,可将 location 改为
location /api/monitor/,其余/api/路径保留默认缓冲以提升普通 API 性能。
2. SPA 路由回退
非 API 路径需回退到 index.html,否则直接访问 /monitor/host 等前端路由会返回 404:
nginx
location / {
proxy_pass http://127.0.0.1:12380;
# 或直接代理到容器,由容器 Nginx 处理 try_files
}容器内部 Nginx 已配置
try_files $uri $uri/ /index.html;,外层代理只需将非 API 请求转发到容器即可。
3. 完整配置示例
nginx
server {
listen 443 ssl http2;
server_name ipam.example.com;
ssl_certificate /etc/nginx/ssl/ipam.crt;
ssl_certificate_key /etc/nginx/ssl/ipam.key;
# API 请求(含 SSE):关闭缓冲,确保实时推送
location /api/ {
proxy_pass http://127.0.0.1:12380;
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_buffering off;
proxy_cache off;
proxy_http_version 1.1;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
# 其余请求(前端静态资源、SPA 路由)
location / {
proxy_pass http://127.0.0.1:12380;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}验证方法
检查响应头:SSE 响应应包含
Content-Type: text/event-streambashcurl -I -H "Accept: text/event-stream" https://ipam.example.com/api/monitor/host浏览器 Network 面板:访问监控页面,观察
/api/monitor/*请求- ✅ 正常:请求状态
pending(保持长连接),但首帧数据在秒级到达 - ❌ 异常:请求 pending 数十秒无数据,或 TTFB 超过 5 秒
- ✅ 正常:请求状态
对比内外层延迟:
bash# 直连容器(应秒级响应) curl -N http://127.0.0.1:12380/api/monitor/host -H "Authorization: Bearer <token>" # 经外层代理(同样应秒级响应) curl -N https://ipam.example.com/api/monitor/host -H "Authorization: Bearer <token>"若直连秒级、代理数十秒,则外层 Nginx 缓冲未关闭。
故障排查
| 现象 | 排查方向 |
|---|---|
| SSE 仍延迟 | 确认外层 Nginx 已 nginx -t && nginx -s reload;检查是否有 CDN/WAF 在前再缓存 |
| 监控页刷新白屏 | 检查外层 location / 是否正确转发到容器 12380;确认容器 Nginx 有 try_files |
| 502/504 错误 | 确认容器正常运行:docker ps | grep ipam-frontend;检查 proxy_read_timeout 是否过短 |
| 首帧快但后续断连 | 检查 proxy_read_timeout 是否小于监控会话时长;确认中间无防火墙切断长连接 |