小易说IT 小易说IT

Nginx upstream 对应各策略的配置示例

说明:全部是开源 Nginx 官方原生支持的 upstream 配置,least_time 在开源版 1.31.0+ 才支持,低版本开源 nginx 没有,是 Nginx Plus 早期专属;hash ... consistent 原生支持(ketama 一致性哈希)。

公共参数说明:

  • weight=N:权重

  • max_fails=3 fail_timeout=30s:被动健康检查,3 次失败、30s 内标记不可用,30s 不分配流量(开源自带)

  • backup:备用节点,所有主节点挂了才启用

1. 默认轮询 Round Robin(不需要额外指令)

依次轮流分发,默认策略

http {
    upstream backend_rr {
        server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
        server 127.0.0.1:8082 max_fails=3 fail_timeout=30s;
        server 127.0.0.1:8083 max_fails=3 fail_timeout=30s;
    }

    server {
        listen 80;
        location / {
            proxy_pass http://backend_rr;
            proxy_set_header Host $host;
        }
    }
}

2. 加权轮询 Weighted Round Robin

weight 越大分到请求越多,适合机器性能不一致

upstream backend_wrr {
    server 127.0.0.1:8081 weight=3 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8082 weight=2 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8083 weight=1 max_fails=3 fail_timeout=30s;
}

流量比例 3:2:1

3. 最小连接 least_conn

优先选当前活跃连接最少的节点;自带权重支持,适合请求耗时差异很大的场景

upstream backend_least_conn {
    least_conn; # 核心指令
    server 127.0.0.1:8081 weight=3 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8082 weight=2 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8083 max_fails=3 fail_timeout=30s;
}

4. IP 哈希 ip_hash

同一个客户端 IP 固定打到同一个后端,会话粘滞;后端宕机会自动漂移到其他节点

upstream backend_ip_hash {
    ip_hash; # 核心指令
    server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8082 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8083 max_fails=3 fail_timeout=30s;
}

注意:ipv4 只取前 3 段做 hash;代理、NAT 出口 IP 集中时容易热点

5. 通用 Hash + 一致性 Hash consistent(重点,缓存常用)

hash $key consistent; ketama 环,增删节点只少量 key 迁移,适合 memcached、redis 代理、静态缓存

# 按URI做一致性hash(相同url固定到同一节点)
upstream backend_consistent_uri {
    hash $request_uri consistent;
    server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8082 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8083 max_fails=3 fail_timeout=30s;
}
# 按用户id参数做一致性hash:比如 /?uid=10001
upstream backend_consistent_uid {
    hash $arg_uid consistent;
    server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8082 max_fails=3 fail_timeout=30s;
}

去掉 consistent 就是普通 hash,扩缩容会大规模 rehash。

6. least_time(最小响应时间,nginx 1.31.0+ / Nginx Plus)

综合:平均响应延迟 + 活跃连接数

  • header:收到响应 header 的时间(首包)

  • last_byte:完整响应返回时间

  • last_byte inflight:同时计入正在处理中的未完成请求

upstream backend_least_time {
    least_time header;
    server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8082 max_fails=3 fail_timeout=30s;
}

7. 补充:random(Nginx Plus 才有,开源无)

# Nginx Plus only,二选一随机优化 random two choices
upstream backend_random {
    random two_least_conn;
    server 127.0.0.1:8081;
    server 127.0.0.1:8082;
}

配套 proxy 公共片段(所有 upstream 都可以复用)

location / {
    proxy_pass http://backend_xxx;
    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_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
    proxy_next_upstream_tries 2;
    proxy_connect_timeout 2s;
    proxy_read_timeout 10s;
}

容易踩坑小结

  1. 算法指令(least_conn; ip_hash; hash ...; least_time)必须写在 server 行前面

  2. 开源 Nginx没有 fair(fair 是第三方模块 upstream_fair,不是官方),很多老教程会提,不推荐生产编译第三方模块

  3. ip_hash 不推荐现代微服务,优先 Redis 存 session 而不是会话绑定实例

  4. consistent hash 适合缓存集群;普通 hash 适合不经常扩缩容的场景


本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。

原文链接 https://www.yijunzhao.cc/archives/nginx-upstream-configuration-examples-each-strategy

欢迎访问 https://www.yijunzhao.cc/

https://www.yijunzhao.cc/