Nginx无法直接按80%写死分流,需通过加权轮询(如从库weight=4、主库weight=1)在读请求专属upstream中实现约80%流量走从库,且必须配合健康检查与路径/头部路由确保读写请求准确分离。

要让 80% 的查询流量走只读从库节点,Nginx 本身不能直接按“80%”写死比例——它通过 加权轮询 实现相对份额分配。关键不是凑百分比,而是用权重比逼近目标分流效果,同时必须确保请求真能落到从库上(即:读写分离需由上游业务或代理层明确区分读/写路径)。
1. 权重配比要合理,避免极端值
想实现约 80% 流量到从库,可设从库权重为 4,主库权重为 1 → 比例为 4:1,理论占比 80% : 20%。这个组合简洁、收敛快、偏差小。
- ✅ 推荐:
server 192.168.1.20:3306 weight=4;(从库)server 192.168.1.10:3306 weight=1;(主库) - ❌ 避免:
weight=80和weight=20—— 数值过大易因连接复用、请求批次少导致实际分布抖动明显 - ⚠️ 注意:Nginx 的
stream模块才能代理 MySQL 端口(如 3306),http模块不适用;且直连 DB 风险高,生产环境建议前置 ProxySQL 或 DB 中间件做语义识别
2. 必须配合健康检查,防止故障节点拖累分流
若从库宕机却仍被轮询,80% 流量就会失败。所以每台 server 行都得带 max_fails 和 fail_timeout:
server 192.168.1.20:3306 weight=4 max_fails=2 fail_timeout=15s;server 192.168.1.10:3306 weight=1 max_fails=2 fail_timeout=15s;- 一旦从库连续失败 2 次,15 秒内自动标记为 down,剩余流量全切到主库(此时虽非预期,但保障可用性)
3. 真正决定“哪些请求走从库”的不是 weight,而是 upstream 的选择逻辑
weight 只在请求已进入某个 upstream 块后起作用。所以你得先让读请求命中专用于从库的 upstream:
- 方式一(推荐):按 URL 路径区分
例如所有/api/v1/read/xxx请求 proxy_pass 到upstream read_backend { ... },其中只配置从库 + 权重 - 方式二:按 HTTP Header 或参数路由(需
map指令预判)
比如识别X-Query-Type: read,再 set $backend "read_pool",最后proxy_pass http://$backend - ⚠️ 单纯在混合读写的 upstream 里配 weight=4:1,无法保证写请求不打到从库——这属于架构设计错误,不是权重能解决的
4. 验证是否真走了 80%,不能只看配置
reload 后必须用真实流量验证,方法很简单:
- 在从库和主库的访问日志中记录
$remote_addr - $time_local "$request" $upstream_addr - 发起 1000+ 次读请求(如用
wrk -t4 -c100 -d30s http://your-api/read/health) - 统计日志里
upstream_addr字段出现次数,看是否接近 4:1(允许 ±3%~5% 波动)


















