Nginx不支持运行时动态修改upstream权重,但可通过脚本生成配置+定时重载实现时段自动切换:一、抽离upstream为独立文件并include;二、编写按小时切换权重的shell脚本;三、用cron每小时触发执行并重载。

Nginx 本身不支持运行时动态修改 upstream 中各服务器的 weight 值(权重是静态编译进配置的),但可以通过外部控制 + 配置热重载的方式,实现在不同业务时段自动切换权重的效果。核心思路是:用脚本按时间规则生成带新权重的配置片段,再触发 Nginx 重载。
以下为可落地的三步实现方案:
一、准备可替换的 upstream 配置模板
把 upstream 块单独抽离成独立文件(如 /etc/nginx/conf.d/upstream.conf),内容如下:
upstream backend_servers {
server 192.168.0.2:8000 weight=3 max_fails=3 fail_timeout=20s;
server 192.168.0.3:8000 weight=7 max_fails=3 fail_timeout=20s;
}注意:不要在主 nginx.conf 中直接写死 upstream,而是用 include 引入:
http {
include /etc/nginx/conf.d/upstream.conf;
# 其他配置...
}二、编写时段权重切换脚本
新建脚本 /usr/local/bin/switch-weight.sh,根据当前小时判断业务时段并写入对应权重:
#!/bin/bash
HOUR=$(date +%H)
UPSTREAM_FILE="/etc/nginx/conf.d/upstream.conf"
case $HOUR in
09|10|11|12|13|14|15|16|17)
# 工作日高峰:8:00–18:00(示例),给高性能服务器更高权重
cat > "$UPSTREAM_FILE" << 'EOF'
upstream backend_servers {
server 192.168.0.2:8000 weight=2;
server 192.168.0.3:8000 weight=8;
}
EOF
;;
18|19|20|21|22|23|00|01|02|03|04|05|06|07|08)
# 低峰期:均衡或倾向低负载服务器
cat > "$UPSTREAM_FILE" << 'EOF'
upstream backend_servers {
server 192.168.0.2:8000 weight=5;
server 192.168.0.3:8000 weight=5;
}
EOF
;;
esac
# 检查语法并重载
nginx -t && nginx -s reload赋予执行权限:
chmod +x /usr/local/bin/switch-weight.sh
三、用 cron 定时触发切换
每小时检查一次时段并更新(避免分钟级频繁重载):
# 编辑 root 的 crontab sudo crontab -e
添加一行:
0 * * * * /usr/local/bin/switch-weight.sh >/dev/null 2>&1
这样每天整点自动适配权重,无需人工干预。
补充说明
- 若需更细粒度(如按分钟、节假日、流量阈值),可扩展脚本逻辑,接入 Prometheus 指标或调用 API 判断状态;
- 所有
weight修改都依赖nginx -s reload,它会平滑重启 worker 进程,不中断已有连接; - 确保
max_fails/fail_timeout等健康检查参数已配置,让异常节点自动剔除,与权重策略协同工作; - 生产环境建议加锁机制(如
flock),防止多个 cron 实例并发写配置导致冲突。
不复杂但容易忽略的是配置文件权限和语法校验——每次写入后务必 nginx -t,失败时不重载,避免服务中断。


















