ngx_http_upstream_module 模块
ngx_http_upstream_module
模块用于定义服务器组,这些服务器组可以通过 proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass 和 grpc_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 |
---|---|
默认值 | — |
上下文 |
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 |
---|---|
默认值 | — |
上下文 |
upstream |
定义服务器的 address
和其他 parameters
。地址可以指定为域名或 IP 地址(带可选端口),也可以指定为带有“unix:
”前缀的 UNIX 域套接字路径。如果未指定端口,则使用端口 80。解析为多个 IP 地址的域名会同时定义多个服务器。
可以定义以下参数
-
weight
=number
- 设置服务器的权重,默认值为 1。
-
max_conns
=number
- 限制到代理服务器的最大并发活动连接数(1.11.5)。默认值为零,表示没有限制。如果服务器组不住在共享内存中,则限制作用于每个 worker 进程。
如果启用了空闲 keepalive 连接、多个worker 进程和共享内存,则到代理服务器的活动连接和空闲连接的总数可能超过
max_conns
值。自版本 1.5.9 至版本 1.11.5,此参数作为我们的商业订阅的一部分提供。
-
max_fails
=number
- 设置在
fail_timeout
参数设置的持续时间内与服务器通信的失败尝试次数,达到该次数后服务器将被视为在fail_timeout
参数设置的持续时间内不可用。默认情况下,失败尝试次数设置为 1。零值禁用尝试计数。什么被视为失败尝试由 proxy_next_upstream, fastcgi_next_upstream, uwsgi_next_upstream, scgi_next_upstream, memcached_next_upstream 和 grpc_next_upstream 指令定义。 -
fail_timeout
=time
- 设置
- 指定次数的失败尝试在多长时间内发生后,服务器将被视为不可用;
- 以及服务器将被视为不可用的持续时间。
-
backup
- 将服务器标记为备份服务器。当主服务器不可用时,请求将被传递给它。
此参数不能与 hash, ip_hash 和 random 负载均衡方法一起使用。
-
down
- 将服务器标记为永久不可用。
-
resolve
- 监视与服务器域名对应的 IP 地址变化,并自动修改 upstream 配置,无需重启 nginx (1.5.12)。服务器组必须位于共享内存中。
为了使此参数生效,必须在 http 块或相应的 upstream 块中指定
resolver
指令。在版本 1.27.3 之前,此参数仅作为我们的商业订阅的一部分提供。
-
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.com
和server1.backend.example.com
SRV 记录,需要指定指令server backend.example.com service=_http._tcp resolve; server example.com service=server1.backend resolve;
优先级最高的 SRV 记录(具有相同最低优先级值的记录)被解析为主服务器,其余 SRV 记录被解析为备份服务器。如果为服务器指定了 backup 参数,则高优先级 SRV 记录被解析为备份服务器,其余 SRV 记录被忽略。
在版本 1.27.3 之前,此参数仅作为我们的商业订阅的一部分提供。
此外,以下参数作为我们的商业订阅的一部分提供
-
route
=string
- 设置服务器路由名称。
-
slow_start
=time
- 设置服务器从不健康变为健康时,或在一段时间被视为不可用后变为可用时,将其权重从零恢复到标称值所需的时间。默认值为零,即禁用慢启动。
此参数不能与 hash, ip_hash 和 random 负载均衡方法一起使用。
-
drain
- 将服务器置于“draining”(耗尽)模式(1.13.6)。在此模式下,只有绑定到该服务器的请求才会被代理到它。
在版本 1.13.6 之前,此参数只能通过 API 模块更改。
如果组中只有一个服务器,则忽略max_fails
,fail_timeout
和slow_start
参数,并且此类服务器永远不会被视为不可用。
语法 |
zone |
---|---|
默认值 | — |
上下文 |
upstream |
此指令出现在版本 1.9.0 中。
定义共享内存区域的 name
和 size
,该区域保存组的配置和运行时状态,并在 worker 进程之间共享。多个组可以共享同一区域。在这种情况下,只需指定 size
一次即可。
此外,作为我们的商业订阅的一部分,此类组允许更改组成员或修改特定服务器的设置,而无需重启 nginx。配置可通过 API 模块访问 (1.13.3)。
在版本 1.13.3 之前,配置只能通过由 upstream_conf 处理的特殊位置访问。
语法 |
state |
---|---|
默认值 | — |
上下文 |
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
当前状态仅限于服务器列表及其参数。配置文件在解析时读取,并在每次 更改 upstream 配置时更新。应避免直接修改文件内容。此指令不能与 server 指令一起使用。
在重新加载配置或二进制升级期间所做的更改可能会丢失。
此指令作为我们的商业订阅的一部分提供。
语法 |
hash |
---|---|
默认值 | — |
上下文 |
upstream |
此指令出现在版本 1.7.2 中。
指定服务器组的负载均衡方法,其中客户端-服务器映射基于哈希的 key
值。key
可以包含文本、变量及其组合。请注意,从组中添加或删除服务器可能会导致大多数键重新映射到不同的服务器。此方法与 Cache::Memcached Perl 库兼容。
如果指定了 consistent
参数,则将使用 ketama 一致性哈希方法。该方法确保在向组中添加或删除服务器时,只有少数键会被重新映射到不同的服务器。这有助于提高缓存服务器的缓存命中率。此方法与 ketama_points
参数设置为 160 的 Cache::Memcached::Fast Perl 库兼容。
语法 |
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 |
---|---|
默认值 | — |
上下文 |
upstream |
此指令出现在版本 1.1.4 中。
激活到 upstream 服务器连接的缓存。
connections
参数设置每个 worker 进程缓存中保留的到 upstream 服务器的最大空闲 keepalive 连接数。当此数量超出时,将关闭最近最少使用的连接。
特别需要注意的是,keepalive
指令并不限制 nginx worker 进程可以打开的到 upstream 服务器的总连接数。connections
参数应设置为足够小的数字,以便 upstream 服务器也能处理新的传入连接。
使用非默认轮询方法以外的负载均衡方法时,需要在 keepalive
指令之前激活它们。
带有 keepalive 连接的 memcached upstream 配置示例
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”头部字段传递给 upstream 服务器来使用 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 |
---|---|
默认值 |
keepalive_requests 1000; |
上下文 |
upstream |
此指令出现在版本 1.15.3 中。
设置可以通过一个 keepalive 连接服务的最大请求数。达到最大请求数后,连接将关闭。
定期关闭连接对于释放每个连接的内存分配是必需的。因此,使用过高的最大请求数可能导致过多的内存使用,不推荐这样做。
在版本 1.19.10 之前,默认值为 100。
语法 |
keepalive_time |
---|---|
默认值 |
keepalive_time 1h; |
上下文 |
upstream |
此指令出现在版本 1.19.10 中。
限制一个 keepalive 连接处理请求的最长时间。达到此时间后,连接将在后续请求处理完成后关闭。
语法 |
keepalive_timeout |
---|---|
默认值 |
keepalive_timeout 60s; |
上下文 |
upstream |
此指令出现在版本 1.15.3 中。
设置到 upstream 服务器的空闲 keepalive 连接保持开放的超时时间。
语法 |
ntlm; |
---|---|
默认值 | — |
上下文 |
upstream |
此指令出现在版本 1.9.2 中。
允许代理使用NTLM 认证的请求。一旦客户端发送的请求的“Authorization”头部字段值以“Negotiate
”或“NTLM
”开头,upstream 连接就会绑定到客户端连接。后续的客户端请求将通过同一个 upstream 连接代理,保持认证上下文。
为了使 NTLM 认证工作,需要启用到 upstream 服务器的 keepalive 连接。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 |
---|---|
默认值 | — |
上下文 |
upstream |
此指令出现在版本 1.7.10 中。
指定组应使用负载均衡方法,其中请求被传递到平均响应时间最短且活动连接数最少的服务器,并考虑服务器的权重。如果存在多个这样的服务器,则按顺序使用加权轮询均衡方法尝试它们。
如果指定了 header
参数,则使用接收响应头部的时间。如果指定了 last_byte
参数,则使用接收完整响应的时间。如果指定了 inflight
参数 (1.11.6),则也会考虑不完整的请求。
在版本 1.11.6 之前,默认情况下会考虑不完整的请求。
此指令作为我们的商业订阅的一部分提供。
语法 |
queue |
---|---|
默认值 | — |
上下文 |
upstream |
此指令出现在版本 1.5.12 中。
如果在处理请求时无法立即选择 upstream 服务器,请求将被放入队列。此指令指定队列中可以同时存在的最大请求数 number
。如果队列已满,或在 timeout
参数指定的时间内无法选择要将请求传递到的服务器,则会向客户端返回 502 (Bad Gateway) 错误。
timeout
参数的默认值为 60 秒。
使用非默认轮询方法以外的负载均衡方法时,需要在 queue
指令之前激活它们。
此指令作为我们的商业订阅的一部分提供。
语法 |
random [ |
---|---|
默认值 | — |
上下文 |
upstream |
此指令出现在版本 1.15.1 中。
指定组应使用负载均衡方法,其中请求被传递到随机选择的服务器,并考虑服务器的权重。
可选的 two
参数指示 nginx 随机选择两个服务器,然后使用指定的 method
选择一个服务器。默认方法是 least_conn
,它将请求传递给活动连接数最少的服务器。
least_time
方法将请求传递给平均响应时间最短且活动连接数最少的服务器。如果指定了 least_time=header
,则使用接收响应头部的时间。如果指定了 least_time=last_byte
,则使用接收完整响应的时间。
least_time
方法作为我们的商业订阅的一部分提供。
语法 |
resolver |
---|---|
默认值 | — |
上下文 |
upstream |
此指令出现在版本 1.27.3 中。
配置用于将 upstream 服务器名称解析为地址的名称服务器,例如
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
参数 (1.17.5) 启用在指定 zone
中收集 DNS 服务器请求和响应的统计信息。此参数作为我们的商业订阅的一部分提供。
自版本 1.17.5 至版本 1.27.3,此指令仅作为我们的商业订阅的一部分提供。
语法 |
resolver_timeout |
---|---|
默认值 |
resolver_timeout 30s; |
上下文 |
upstream |
此指令出现在版本 1.27.3 中。
设置名称解析的超时时间,例如
resolver_timeout 5s;
自版本 1.17.5 至版本 1.27.3,此指令仅作为我们的商业订阅的一部分提供。
语法 |
sticky sticky sticky |
---|---|
默认值 | — |
上下文 |
upstream |
此指令出现在版本 1.5.7 中。
启用会话粘滞(session affinity),这使得来自同一客户端的请求被传递到服务器组中的同一服务器。有三种方法可用
-
使用
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 的值将是a
或b
。其他参数可能如下
expires=
time
- 设置浏览器应保留 cookie 的时间
time
。特殊值max
将使 cookie 在“31 Dec 2037 23:55:55 GMT
”过期。如果未指定参数,则会使 cookie 在浏览器会话结束时过期。 domain=
domain
- 定义设置 cookie 的
domain
。参数值可以包含变量 (1.11.5)。 httponly
- 向 cookie 添加
HttpOnly
属性 (1.7.11)。 samesite=
strict
|lax
|none
|$variable
- 向 cookie 添加
SameSite
(1.19.4) 属性,其值可以是以下之一:Strict
,Lax
,None
,或使用变量 (1.23.3)。在后一种情况下,如果变量值为空,则不会向 cookie 添加SameSite
属性;如果值解析为Strict
,Lax
, 或None
,则分配相应的值,否则分配Strict
值。 secure
- 向 cookie 添加
Secure
属性 (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,则从中获取路由。否则,使用 URI 中的路由。 learn
-
使用
learn
方法 (1.7.1) 时,nginx 分析 upstream 服务器响应并学习通常在 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; }
在示例中,upstream 服务器通过在响应中设置 cookie“
EXAMPLECOOKIE
”来创建会话。带有此 cookie 的后续请求将传递到同一服务器。如果服务器无法处理请求,则选择新服务器,就像客户端尚未绑定一样。参数
create
和lookup
分别指定指示如何创建新会话和搜索现有会话的变量。这两个参数都可以指定多次,在这种情况下,使用第一个非空变量。会话存储在共享内存区域中,其
name
和size
由zone
参数配置。一兆字节的区域在 64 位平台上可以存储大约 4000 个会话。在timeout
参数指定的时间内未访问的会话会从区域中移除。默认情况下,timeout
设置为 10 分钟。header
参数 (1.13.1) 允许在从 upstream 服务器接收到响应头部后立即创建会话。sync
参数 (1.13.8) 启用共享内存区域的同步。
此指令作为我们的商业订阅的一部分提供。
语法 |
sticky_cookie_insert |
---|---|
默认值 | — |
上下文 |
upstream |
此指令自版本 1.5.7 起已过时。应使用具有新语法的等效 sticky 指令代替
sticky cookie
name
[expires=
time
] [domain=
domain
] [path=
path
];
内嵌变量
ngx_http_upstream_module
模块支持以下内嵌变量
$upstream_addr
- 保存 upstream 服务器的 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
- 从 upstream 服务器接收到的字节数 (1.11.4)。来自多个连接的值用逗号和冒号分隔,就像 $upstream_addr 变量中的地址一样。
$upstream_bytes_sent
- 发送到 upstream 服务器的字节数 (1.15.8)。来自多个连接的值用逗号和冒号分隔,就像 $upstream_addr 变量中的地址一样。
$upstream_cache_status
- 保存访问响应缓存的状态 (0.8.3)。状态可以是“
MISS
”, “BYPASS
”, “EXPIRED
”, “STALE
”, “UPDATING
”, “REVALIDATED
”, 或 “HIT
”之一。 $upstream_connect_time
- 保存与 upstream 服务器建立连接所花费的时间 (1.9.1);时间以秒为单位,精确到毫秒。在 SSL 情况下,包括握手所花费的时间。多个连接的时间用逗号和冒号分隔,就像 $upstream_addr 变量中的地址一样。
- upstream 服务器在“Set-Cookie”响应头部字段中发送的指定名称
name
的 cookie (1.7.1)。仅保存最后一个服务器响应中的 cookie。 $upstream_header_time
- 保存从 upstream 服务器接收响应头部所花费的时间 (1.7.10);时间以秒为单位,精确到毫秒。多个响应的时间用逗号和冒号分隔,就像 $upstream_addr 变量中的地址一样。
$upstream_http_
name
- 保留服务器响应头字段。例如,通过
$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 (Bad Gateway) 状态码。
$upstream_trailer_
name
- 保留从上游服务器获得的响应尾部字段 (1.13.10)。