模块 ngx_http_upstream_module

示例配置
指令
     upstream
     server
     zone
     state
     hash
     ip_hash
     keepalive
     keepalive_requests
     keepalive_time
     keepalive_timeout
     ntlm
     least_conn
     least_time
     queue
     random
     resolver
     resolver_timeout
     sticky
     sticky_cookie_insert
嵌入式变量

ngx_http_upstream_module 模块用于定义服务器组,可由 proxy_passfastcgi_passuwsgi_passscgi_passmemcached_passgrpc_pass 指令引用。

示例配置

upstream backend {
    server backend1.example.com       weight=5;
    server backend2.example.com:8080;
    server unix:/tmp/backend3;

    server backup1.example.com:8080   backup;
    server backup2.example.com:8080   backup;
}

server {
    location / {
        proxy_pass http://backend;
    }
}

动态可配置组,带有周期性 健康检查,可作为我们的 商业订阅 的一部分提供

resolver 10.0.0.1;

upstream dynamic {
    zone upstream_dynamic 64k;

    server backend1.example.com      weight=5;
    server backend2.example.com:8080 fail_timeout=5s slow_start=30s;
    server 192.0.2.1                 max_fails=3;
    server backend3.example.com      resolve;
    server backend4.example.com      service=http resolve;

    server backup1.example.com:8080  backup;
    server backup2.example.com:8080  backup;
}

server {
    location / {
        proxy_pass http://dynamic;
        health_check;
    }
}

指令

语法 upstream name { ... }
默认值
上下文 http

定义服务器组。服务器可以在不同的端口上监听。此外,可以在 TCP 和 UNIX 域套接字上监听的服务器可以混合使用。

示例

upstream backend {
    server backend1.example.com weight=5;
    server 127.0.0.1:8080       max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend3;

    server backup1.example.com  backup;
}

默认情况下,请求使用加权循环负载均衡方法在服务器之间分配。在上面的示例中,每 7 个请求将按如下方式分配:5 个请求转到 backend1.example.com,每个第二个和第三个服务器一个请求。如果在与服务器通信期间发生错误,请求将传递到下一个服务器,依此类推,直到尝试所有正在运行的服务器。如果无法从任何服务器获得成功的响应,客户端将收到与最后一个服务器通信的结果。

语法 server address [parameters];
默认值
上下文 upstream

定义服务器的地址和其他参数。地址可以指定为域名或 IP 地址,并带有可选端口,或指定为“unix:”前缀后的 UNIX 域套接字路径。如果未指定端口,则使用端口 80。解析为多个 IP 地址的域名同时定义多个服务器。

可以定义以下参数

weight=number
设置服务器的权重,默认为 1。
max_conns=number
限制与代理服务器同时进行的最大number个活动连接(1.11.5)。默认值为零,表示没有限制。如果服务器组不在共享内存中,则限制适用于每个工作进程。
如果启用了空闲保持活动连接、多个工作进程共享内存,则与代理服务器的活动和空闲连接总数可能会超过max_conns值。
从 1.5.9 版本到 1.11.5 版本之前,此参数作为我们商业订阅的一部分提供。
max_fails=number
设置与服务器通信失败的次数,这些失败应在由fail_timeout参数设置的持续时间内发生,以将服务器视为不可用,持续时间也由fail_timeout参数设置。默认情况下,失败尝试次数设置为 1。零值禁用尝试计数。什么是失败尝试由proxy_next_upstreamfastcgi_next_upstreamuwsgi_next_upstreamscgi_next_upstreammemcached_next_upstreamgrpc_next_upstream指令定义。
fail_timeout=time
设置
  • 与服务器通信失败的指定次数应在该时间内发生,以将服务器视为不可用;
  • 以及服务器将被视为不可用的时间段。
默认情况下,该参数设置为 10 秒。
backup
将服务器标记为备份服务器。当主服务器不可用时,将向其传递请求。
该参数不能与哈希IP 哈希随机负载平衡方法一起使用。
down
将服务器标记为永久不可用。

此外,以下参数作为我们商业订阅的一部分提供

resolve
监视与服务器域名对应的 IP 地址的更改,并在无需重新启动 nginx(1.5.12)的情况下自动修改上游配置。服务器组必须驻留在共享内存中。

要使此参数生效,必须在 http 块或相应的 upstream 块中指定 resolver 指令。

route=string
设置服务器路由名称。
service=name
启用 DNS SRV 记录解析,并设置服务 name(1.9.13)。要使此参数生效,必须为服务器指定 resolve 参数,并指定不带端口号的主机名。

如果服务名称不包含点(“.”),则会构造符合 RFC 的名称,并将 TCP 协议添加到服务前缀。例如,要查找 _http._tcp.backend.example.com SRV 记录,必须指定指令

server backend.example.com service=http resolve;

如果服务名称包含一个或多个点,则通过连接服务前缀和服务器名称来构造名称。例如,要查找 _http._tcp.backend.example.comserver1.backend.example.com SRV 记录,必须指定指令

server backend.example.com service=_http._tcp resolve;
server example.com service=server1.backend resolve;

优先级最高的 SRV 记录(具有相同最低数字优先级值的记录)解析为主要服务器,其余 SRV 记录解析为备用服务器。如果为服务器指定了 backup 参数,则高优先级 SRV 记录解析为备用服务器,其余 SRV 记录将被忽略。

slow_start=time
设置 time,在此期间,当不健康的服务器变为 健康 时,或者当服务器在一段时间内被认为 不可用 后变为可用时,服务器将从零恢复其权重到标称值。默认值为零,即禁用慢启动。
该参数不能与哈希IP 哈希随机负载平衡方法一起使用。
drain
将服务器置于“排空”模式(1.13.6)。在此模式下,只有 绑定 到服务器的请求才会被代理到服务器。
在 1.13.6 版本之前,只能使用 API 模块更改此参数。

如果组中只有一个服务器,则会忽略 max_failsfail_timeoutslow_start 参数,并且此类服务器永远不会被视为不可用。

语法 zone name [size];
默认值
上下文 upstream

此指令出现在 1.9.0 版本中。

定义共享内存区域的 namesize,该区域保存组的配置和运行时状态,这些状态在工作进程之间共享。多个组可以共享同一个区域。在这种情况下,只需指定一次 size 即可。

此外,作为我们的商业订阅的一部分,此类组允许更改组成员身份或修改特定服务器的设置,而无需重新启动 nginx。可以通过API模块(1.13.3)访问配置。

在 1.13.3 版本之前,只能通过upstream_conf处理的特殊位置访问配置。

语法 state file;
默认值
上下文 upstream

此指令出现在 1.9.7 版本中。

指定一个file,用于保存动态可配置组的状态。

示例

state /var/lib/nginx/state/servers.conf; # path for Linux
state /var/db/nginx/state/servers.conf;  # path for FreeBSD

状态当前仅限于具有其参数的服务器列表。在解析配置时读取文件,并且每次上游配置更改时都会更新文件。应避免直接更改文件内容。此指令不能与server指令一起使用。

重新加载配置二进制升级期间进行的更改可能会丢失。

此指令作为我们商业订阅的一部分提供。

语法 hash key [consistent];
默认值
上下文 upstream

此指令出现在 1.7.2 版本中。

为服务器组指定负载均衡方法,其中客户端-服务器映射基于哈希的key值。key可以包含文本、变量及其组合。请注意,从组中添加或删除服务器可能会导致将大多数键重新映射到不同的服务器。该方法与Cache::MemcachedPerl 库兼容。

如果指定了consistent参数,则将使用ketama一致性哈希方法。该方法确保在将服务器添加到组或从组中删除服务器时,只有少数键会重新映射到不同的服务器。这有助于为缓存服务器实现更高的缓存命中率。该方法与Cache::Memcached::FastPerl 库兼容,其中ketama_points参数设置为 160。

语法 ip_hash;
默认值
上下文 upstream

指定组应使用负载均衡方法,其中请求根据客户端 IP 地址在服务器之间分配。客户端 IPv4 地址的前三个八位字节或整个 IPv6 地址用作哈希键。该方法确保来自同一客户端的请求始终传递到同一服务器,除非此服务器不可用。在后一种情况下,客户端请求将传递到另一台服务器。很可能,它也总是同一台服务器。

从 1.3.2 和 1.2.2 版本开始支持 IPv6 地址。

如果需要暂时删除其中一台服务器,则应使用down参数对其进行标记,以保留客户端 IP 地址的当前哈希。

示例

upstream backend {
    ip_hash;

    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com down;
    server backend4.example.com;
}

在 1.3.1 和 1.2.2 版本之前,无法使用ip_hash负载均衡方法为服务器指定权重。

语法 keepalive connections;
默认值
上下文 upstream

此指令出现在 1.1.4 版本中。

激活与上游服务器的连接缓存。

connections 参数设置每个工作进程缓存中保留的上游服务器空闲 keepalive 连接的最大数量。当超过此数量时,将关闭最近最少使用的连接。

特别需要注意的是,keepalive 指令不会限制 nginx 工作进程可以打开的上游服务器连接的总数。connections 参数应设置为足够小的数字,以允许上游服务器处理新的传入连接。

在使用除默认轮循方法之外的负载均衡方法时,有必要在 keepalive 指令之前激活它们。

带有 keepalive 连接的 memcached 上游的示例配置

upstream memcached_backend {
    server 127.0.0.1:11211;
    server 10.0.0.2:11211;

    keepalive 32;
}

server {
    ...

    location /memcached/ {
        set $memcached_key $uri;
        memcached_pass memcached_backend;
    }

}

对于 HTTP,proxy_http_version 指令应设置为 “1.1”,并且应清除 “Connection” 头字段

upstream http_backend {
    server 127.0.0.1:8080;

    keepalive 16;
}

server {
    ...

    location /http/ {
        proxy_pass http://http_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        ...
    }
}

或者,可以通过将 “Connection: Keep-Alive” 头字段传递给上游服务器来使用 HTTP/1.0 持久连接,尽管不建议使用此方法。

对于 FastCGI 服务器,需要设置 fastcgi_keep_conn 才能使 keepalive 连接正常工作

upstream fastcgi_backend {
    server 127.0.0.1:9000;

    keepalive 8;
}

server {
    ...

    location /fastcgi/ {
        fastcgi_pass fastcgi_backend;
        fastcgi_keep_conn on;
        ...
    }
}

SCGI 和 uwsgi 协议没有 keepalive 连接的概念。

语法 keepalive_requests number;
默认值
keepalive_requests 1000;
上下文 upstream

此指令出现在 1.15.3 版本中。

设置可以通过一个 keepalive 连接提供的请求的最大数量。在发出最大数量的请求后,将关闭连接。

定期关闭连接对于释放每个连接的内存分配是必要的。因此,使用过高的最大请求数可能会导致过度的内存使用,不建议这样做。

在 1.19.10 版本之前,默认值为 100。

语法 keepalive_time time;
默认值
keepalive_time 1h;
上下文 upstream

此指令出现在 1.19.10 版本中。

限制可以通过一个 keepalive 连接处理请求的最长时间。达到此时间后,将在后续请求处理后关闭连接。

语法 keepalive_timeout timeout;
默认值
keepalive_timeout 60s;
上下文 upstream

此指令出现在 1.15.3 版本中。

设置一个超时时间,在此期间,与上游服务器的空闲 keepalive 连接将保持打开状态。

语法 ntlm;
默认值
上下文 upstream

此指令出现在 1.9.2 版本中。

允许代理带有 NTLM 身份验证 的请求。一旦客户端发送带有以“Negotiate”或“NTLM”开头的“Authorization”标头字段值的请求,上游连接就会绑定到客户端连接。后续客户端请求将通过相同的上游连接进行代理,保持身份验证上下文。

为了让 NTLM 身份验证正常工作,有必要启用到上游服务器的保持活动连接。proxy_http_version 指令应设置为“1.1”,并且应清除“Connection”标头字段

upstream http_backend {
    server 127.0.0.1:8080;

    ntlm;
}

server {
    ...

    location /http/ {
        proxy_pass http://http_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        ...
    }
}

在使用除默认循环方法之外的其他负载平衡器方法时,有必要在 ntlm 指令之前激活它们。

此指令作为我们商业订阅的一部分提供。

语法 least_conn;
默认值
上下文 upstream

此指令出现在 1.3.1 和 1.2.2 版本中。

指定一个组应使用负载平衡方法,其中请求将传递给活动连接数最少的服务器,同时考虑服务器的权重。如果存在多个这样的服务器,则会使用加权循环平衡方法依次尝试它们。

语法 least_time header | last_byte [inflight];
默认值
上下文 upstream

此指令出现在 1.7.10 版本中。

指定一个组应使用负载平衡方法,其中请求将传递给平均响应时间最短且活动连接数最少的服务器,同时考虑服务器的权重。如果存在多个这样的服务器,则会使用加权循环平衡方法依次尝试它们。

如果指定了 header 参数,则使用接收 响应标头 的时间。如果指定了 last_byte 参数,则使用接收 完整响应 的时间。如果指定了 inflight 参数 (1.11.6),则也会考虑不完整的请求。

在 1.11.6 版本之前,默认情况下会考虑不完整的请求。

此指令作为我们商业订阅的一部分提供。

语法 queue number [timeout=time];
默认值
上下文 upstream

此指令出现在 1.5.12 版本中。

如果在处理请求时无法立即选择上游服务器,则请求将被放入队列。该指令指定队列中可以同时存在的请求的最大 number。如果队列已满,或者在 timeout 参数中指定的时间段内无法选择要将请求传递到的服务器,则会向客户端返回 502(错误网关)错误。

timeout 参数的默认值为 60 秒。

在使用除默认循环方法之外的其他负载平衡器方法时,有必要在 queue 指令之前激活它们。

此指令作为我们商业订阅的一部分提供。

语法 random [two [方法]];
默认值
上下文 upstream

此指令出现在 1.15.1 版本中。

指定组应使用负载平衡方法,其中请求将传递给随机选择的服务器,同时考虑服务器的权重。

可选的 two 参数指示 nginx 随机选择 两个 服务器,然后使用指定的 方法 选择服务器。默认方法是 least_conn,它将请求传递给活动连接数最少的服务器。

least_time 方法将请求传递给平均响应时间最短且活动连接数最少的服务器。如果指定了 least_time=header,则使用接收 响应头 的时间。如果指定了 least_time=last_byte,则使用接收 完整响应 的时间。

least_time 方法作为我们 商业订阅 的一部分提供。

语法 resolver 地址 ... [valid=时间] [ipv4=on|off] [ipv6=on|off] [status_zone=区域];
默认值
上下文 upstream

此指令出现在 1.17.5 版本中。

配置用于将上游服务器的名称解析为地址的名称服务器,例如

resolver 127.0.0.1 [::1]:5353;

地址可以指定为域名或 IP 地址,并带有可选端口。如果未指定端口,则使用端口 53。名称服务器以循环方式进行查询。

默认情况下,nginx 在解析时将查找 IPv4 和 IPv6 地址。如果不需要查找 IPv4 或 IPv6 地址,则可以指定 ipv4=off (1.23.1) 或 ipv6=off 参数。

默认情况下,nginx 使用响应的 TTL 值缓存答案。可选的 valid 参数允许覆盖它

resolver 127.0.0.1 [::1]:5353 valid=30s;

为了防止 DNS 欺骗,建议在适当保护的可信本地网络中配置 DNS 服务器。

可选的 status_zone 参数启用 收集 指定 区域 中请求和响应的 DNS 服务器统计信息。

此指令作为我们商业订阅的一部分提供。

语法 resolver_timeout 时间;
默认值
resolver_timeout 30s;
上下文 upstream

此指令出现在 1.17.5 版本中。

设置名称解析超时,例如

resolver_timeout 5s;

此指令作为我们商业订阅的一部分提供。

语法 sticky cookie 名称 [expires=时间] [domain=] [httponly] [samesite=strict|lax|none|$变量] [secure] [path=路径];
sticky route $变量 ...;
sticky learn create=$variable lookup=$variable zone=name:size [timeout=time] [header] [sync];
默认值
上下文 upstream

此指令出现在版本 1.5.7 中。

启用会话亲和性,这会导致来自同一客户端的请求被传递到服务器组中的同一服务器。有三种方法可用

当使用 cookie 方法时,有关指定服务器的信息将通过 nginx 生成的 HTTP cookie 传递

upstream backend {
    server backend1.example.com;
    server backend2.example.com;

    sticky cookie srv_id expires=1h domain=.example.com path=/;
}

来自尚未绑定到特定服务器的客户端的请求将传递给由配置的平衡方法选择的服务器。带有此 cookie 的进一步请求将传递到指定的服务器。如果指定的服务器无法处理请求,则选择新服务器,就像客户端尚未绑定一样。

由于负载平衡方法始终尝试在考虑已绑定的请求的情况下均匀分布负载,因此具有更多活动绑定请求的服务器获得新未绑定请求的可能性较小。

第一个参数设置要设置或检查的 cookie 的名称。cookie 值是 IP 地址和端口或 UNIX 域套接字路径的 MD5 哈希的十六进制表示。但是,如果指定了 server 指令的“route”参数,则 cookie 值将是“route”参数的值

upstream backend {
    server backend1.example.com route=a;
    server backend2.example.com route=b;

    sticky cookie srv_id expires=1h domain=.example.com path=/;
}

在这种情况下,“srv_id”cookie 的值将是 ab

其他参数可能如下

expires=time
设置浏览器应保留 cookie 的time。特殊值 max 将导致 cookie 在“31 Dec 2037 23:55:55 GMT”过期。如果未指定该参数,它将导致 cookie 在浏览器会话结束时过期。
domain=domain
定义设置 cookie 的domain。参数值可以包含变量 (1.11.5)。
httponly
HttpOnly 属性添加到 cookie (1.7.11)。
samesite=strict | lax | none | $variable
使用以下值之一将 SameSite (1.19.4) 属性添加到 cookie:StrictLaxNone 或使用变量 (1.23.3)。在后一种情况下,如果变量值为空,则不会将 SameSite 属性添加到 cookie,如果值解析为 StrictLaxNone,则将分配相应的值,否则将分配 Strict 值。
secure
Secure 属性添加到 cookie(1.7.11)。
path=path
定义设置 cookie 的 path

如果省略任何参数,则不会设置相应的 cookie 字段。

route

当使用 route 方法时,代理服务器在收到第一个请求时为客户端分配一个路由。来自此客户端的所有后续请求都将在 cookie 或 URI 中携带路由信息。此信息与 server 指令的“route”参数进行比较,以识别应将请求代理到的服务器。如果未指定“route”参数,则路由名称将是 IP 地址和端口或 UNIX 域套接字路径的 MD5 哈希的十六进制表示。如果指定的服务器无法处理请求,则将根据配置的平衡方法选择新服务器,就好像请求中没有路由信息一样。

route 方法的参数指定可能包含路由信息的变量。第一个非空变量用于查找匹配的服务器。

示例

map $cookie_jsessionid $route_cookie {
    ~.+\.(?P<route>\w+)$ $route;
}

map $request_uri $route_uri {
    ~jsessionid=.+\.(?P<route>\w+)$ $route;
}

upstream backend {
    server backend1.example.com route=a;
    server backend2.example.com route=b;

    sticky route $route_cookie $route_uri;
}

在此,如果请求中存在“JSESSIONID”cookie,则路由将从此 cookie 中获取。否则,将使用 URI 中的路由。

learn

当使用 learn 方法(1.7.1)时,nginx 会分析上游服务器响应并了解通常在 HTTP cookie 中传递的服务器发起的会话。

upstream backend {
   server backend1.example.com:8080;
   server backend2.example.com:8081;

   sticky learn
          create=$upstream_cookie_examplecookie
          lookup=$cookie_examplecookie
          zone=client_sessions:1m;
}

在示例中,上游服务器通过在响应中设置 cookie “EXAMPLECOOKIE”来创建会话。带有此 cookie 的进一步请求将传递到同一服务器。如果服务器无法处理请求,则将选择新服务器,就好像客户端尚未绑定一样。

参数 createlookup 指定变量,分别指示如何创建新会话和搜索现有会话。这两个参数可以指定多次,在这种情况下,将使用第一个非空变量。

会话存储在共享内存区域中,其 namesizezone 参数配置。在 64 位平台上,一个兆字节的区域可以存储大约 4000 个会话。在 timeout 参数指定的时间内未访问的会话将从区域中移除。默认情况下,timeout 设置为 10 分钟。

header 参数 (1.13.1) 允许在上游服务器收到响应头后立即创建会话。

sync 参数 (1.13.8) 启用共享内存区域的 同步

此指令作为我们商业订阅的一部分提供。

语法 sticky_cookie_insert name [expires=time] [domain=domain] [path=path];
默认值
上下文 upstream

此指令自 1.5.7 版本起已过时。应改用具有新语法的等效 sticky 指令

sticky cookie name [expires=time] [domain=domain] [path=path];

嵌入变量

ngx_http_upstream_module 模块支持以下嵌入变量

$upstream_addr
保留上游服务器的 IP 地址和端口,或 UNIX 域套接字的路径。如果在请求处理期间联系了多台服务器,则它们的地址用逗号分隔,例如“192.168.1.1:80, 192.168.1.2:80, unix:/tmp/sock”。如果由“X-Accel-Redirect”或 error_page 发起从一个服务器组到另一个服务器组的内部重定向,则来自不同组的服务器地址用冒号分隔,例如“192.168.1.1:80, 192.168.1.2:80, unix:/tmp/sock : 192.168.10.1:80, 192.168.10.2:80”。如果无法选择服务器,则该变量保留服务器组的名称。
$upstream_bytes_received
从上游服务器接收的字节数 (1.11.4)。多个连接的值用逗号和冒号分隔,就像 $upstream_addr 变量中的地址一样。
$upstream_bytes_sent
发送到上游服务器的字节数 (1.15.8)。多个连接的值用逗号和冒号分隔,就像 $upstream_addr 变量中的地址一样。
$upstream_cache_status
保留访问响应缓存的状态 (0.8.3)。状态可以是“MISS”、“BYPASS”、“EXPIRED”、“STALE”、“UPDATING”、“REVALIDATED”或“HIT”。
$upstream_connect_time
保留与上游服务器建立连接所花费的时间 (1.9.1);时间以秒为单位保留,精度为毫秒。在 SSL 的情况下,包括握手所花费的时间。多个连接的时间用逗号和冒号分隔,就像 $upstream_addr 变量中的地址一样。
上游服务器在“Set-Cookie”响应头字段中发送的具有指定 name 的 cookie (1.7.1)。仅保存最后一个服务器响应中的 cookie。
$upstream_header_time
保留从上游服务器接收响应头所花费的时间 (1.7.10);时间以秒为单位保留,精度为毫秒。多个响应的时间用逗号和冒号分隔,就像 $upstream_addr 变量中的地址一样。
$upstream_http_名称
保留服务器响应头字段。例如,可以通过 $upstream_http_server 变量获取“Server”响应头字段。将头字段名称转换为变量名称的规则与以“$http_”前缀开头的变量相同。仅保存来自最后一个服务器响应的头字段。
$upstream_last_server_name
保留最后选定的上游服务器的名称(1.25.3);允许通过 SNI 传递该名称
proxy_ssl_server_name on;
proxy_ssl_name        $upstream_last_server_name;

此变量作为我们 商业订阅 的一部分提供。

$upstream_queue_time
保留请求在上游 队列 中花费的时间(1.13.9);时间以秒为单位保留,精度为毫秒。多个响应的时间以逗号和冒号分隔,就像 $upstream_addr 变量中的地址一样。
$upstream_response_length
保留从上游服务器获取的响应的长度(0.7.27);长度以字节为单位保留。多个响应的长度以逗号和冒号分隔,就像 $upstream_addr 变量中的地址一样。
$upstream_response_time
保留从上游服务器接收响应所花费的时间;时间以秒为单位保留,精度为毫秒。多个响应的时间以逗号和冒号分隔,就像 $upstream_addr 变量中的地址一样。
$upstream_status
保留从上游服务器获取的响应的状态代码。多个响应的状态代码以逗号和冒号分隔,就像 $upstream_addr 变量中的地址一样。如果无法选择服务器,则变量保留 502(错误网关)状态代码。
$upstream_trailer_名称
保留从上游服务器获取的响应末尾的字段(1.13.10)。