在线热更新 Upstream全面掌握 ngx_http_upstream_conf_module
1、模块定位与工作流
能力 | 说明 |
---|---|
热增删 / 修改后端节点 | 通过 HTTP GET 查询串即可,不需要 reload、restart。 |
支持 HTTP 与 Stream | 仅要求 upstream 使用 zone 共享内存。 |
一次只改一个上游 | 操作粒度=server 块(通过自动分配的 id )。 |
声明式状态持久化 | 若在 upstream 中指定 state /path/file; (商),reload 后依旧保持修改。 |
权限完全由 Nginx 控制 | 可配 Basic Auth、IP 白名单、mTLS。 |
注意:
upstream_conf
并不会修改 nginx.conf 文件,而是把变动写入共享内存 (& 可选 state 文件)。配置文件下一次 reload 会丢失修改,除非使用state
。
2、最小可用示例
resolver 10.0.0.10 valid=30s ipv6=off; # 若需 “server ... resolve”upstream backend {zone upstream_backend 64k; # 必须有 zoneserver 10.0.0.11 weight=5;
}server {listen 127.0.0.1:8080;location /upstream_conf {upstream_conf;allow 127.0.0.1; # 强制加 ACL!deny all;# auth_basic "protected";# auth_basic_user_file conf/.htpasswd;}
}
3、接口格式速查
GET /upstream_conf?{selector}{action¶ms}
片段 | 作用 | 必/选 |
---|---|---|
stream= | 若操作 stream upstream,填任意值 | 选 |
upstream=backend | 指定组名 | 必 |
id=42 | 指定 server 序号 | 视动作 |
add= | 添加节点 | 动作之一 |
remove= | 删除节点 | 动作之一 |
其余 weight/max_conns/... | 设置/更新 server 参数 | 选 |
4、常用场景示例(curl)
4.1 查询整个组
curl 'http://127.0.0.1:8080/upstream_conf?upstream=backend'
4.2 添加主节点
curl 'http://127.0.0.1:8080/upstream_conf?add=&upstream=backend&server=10.0.0.12:8080&weight=3'
返回示例:
added id=3 server=10.0.0.12:8080
4.3 标记节点为 down
curl 'http://127.0.0.1:8080/upstream_conf?upstream=backend&id=3&down='
4.4 切换为 drain(灰度下线,商版 1.13.6+)
curl 'http://127.0.0.1:8080/upstream_conf?upstream=backend&id=3&drain='
4.5 删除节点
curl 'http://127.0.0.1:8080/upstream_conf?remove=&upstream=backend&id=3'
4.6 Stream 组操作
curl 'http://127.0.0.1:8080/upstream_conf?stream=&upstream=tcp_backend&id=1&max_fails=2'
5、重要参数对照
名称 | 含义 | 典型用途 |
---|---|---|
server= | 地址或域名(可配合 resolve 动态解析) | 动态插入新实例 |
backup= | 设为备份节点 | 容灾 only |
weight= | RR/IP_HASH 等算法权重 | 流量灰度 |
max_conns= | 单节点连接上限 | 上游限流 |
slow_start= | 健康恢复的缓升时间 (商) | 避免突刺 |
drain= | 仅处理已绑定请求 (商) | 平滑下线 |
route= | Sticky route 名 (商) | 会话保持 |
6、安全最佳实践
-
专用内网 Listener
listen 127.0.0.1:8080;
-
双重认证
- IP ACL (
allow/deny
) - Basic Auth 或 mTLS
- IP ACL (
-
日志审计
access_log /var/log/nginx/upstream_conf.log;
-
只允许 GET + 参数白名单
WAF / Nginxif ($arg_upstream !~ ^backend|api$) { return 403; }
-
最小共享内存:
zone 64k
适合 <64 台节点,避免滥耗内存。
7、与 ngx_http_api_module 对比 & 迁移策略
能力 | upstream_conf | api (≥1.13.3) |
---|---|---|
协议 | 查询串 key=value | RESTful /api/6/http/upstreams/... |
JSON 输出 | ❌ (纯文本) | ✅ |
批量 PATCH | ❌ | ✅ |
Stream & HTTP | ✅ | ✅ |
状态读写 | 写 + 简单列表 | 读写 + 统计指标 |
Access 控制 | 由用户自加 | 同上 |
迁移
- 并行开启
/api/
; - 改造脚本为 REST PUT/PATCH;
- 完成后
location /upstream_conf
可删。
8、常见坑 & 排障
症状 | 原因 | 解决 |
---|---|---|
“403 Forbidden” | 未在 ACL 里 / 使用 POST | 用 GET 且白名单 IP |
修改成功但 reload 后丢失 | 未用 state 文件 | 在 upstream 加 state /var/lib/nginx/upstream.state; |
多 worker 但修改看不到 | 忘记 zone | 必须 zone name size; |
添加域名解析但不生效 | 缺 resolver | resolver 8.8.8.8; 并配 resolve |
drain 无效 | 版本 < 1.13.6 或非商版 | 升级商业版 / 用 down+慢启动替代 |
9、在 CI/CD 中使用
-
阶段流量拨号
# 灰度 5% curl "...&weight=1&id=online" curl "...&weight=19&id=gray"
-
蓝绿切换脚本
for id in $(blue_ids); do curl "...&id=$id&drain="; done sleep 120 && remove drained
-
自动扩容
Auto-Scaler → Nginx /upstream_conf add server=newIP:port weight=10
结语
ngx_http_upstream_conf_module
让 不想(或无法)reload 的场景依旧拥有秒级变更 Upstream 的能力。
- 日常运维:手动排障、临时摘除故障节点;
- 自动化:CI/CD 灰度发布、弹性伸缩、A/B 拨流;
- 平滑下线:结合
drain
/slow_start
让流量无感迁移。
若你计划使用新版本 Nginx,请把脚本升级到功能更全面的 ngx_http_api_module,接口更一致、输出 JSON 化,也能同时拉取实时指标。
如有更细节的落地问题,随时再问!