模块 ngx_http_upstream_module

示例配置
指令
     上游
     服务器
     区域
     状态
     哈希
     ip_hash
     保持连接
     keepalive_requests
     keepalive_time
     keepalive_timeout
     ntlm
     least_conn
     least_time
     队列
     随机
     解析器
     resolver_timeout
     粘性
     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];
默认值
上下文 上游

定义服务器的 address 和其他 parameters。地址可以指定为域名或 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 秒。
备份
将服务器标记为备份服务器。当主服务器不可用时,将向其传递请求。
此参数不能与 haship_hashrandom 负载均衡方法一起使用。
关闭
将服务器标记为永久不可用。

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

解析
监视与服务器域名相对应的 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,在此期间,服务器的权重将从零恢复到标称值,当不健康的服务器变为 健康 时,或当服务器在被视为 不可用 的一段时间后变为可用时。默认值为零,即禁用慢启动。
此参数不能与 haship_hashrandom 负载均衡方法一起使用。
排水
将服务器置于“排水”模式(1.13.6)。在此模式下,只有 绑定 到服务器的请求才会被代理到该服务器。
在 1.13.6 版之前,只能使用 API 模块更改此参数。

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

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

此指令出现在 1.9.0 版中。

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

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

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

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

此指令出现在 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];
默认值
上下文 上游

此指令出现在 1.7.2 版中。

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

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

语法 ip_hash;
默认值
上下文 上游

指定一个组应使用一种负载均衡方法,其中请求根据客户端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;
默认值
上下文 上游

此指令出现在1.1.4版中。

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

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

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

使用除默认轮询方法之外的其他负载均衡方法时,需要在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才能使保持活动连接正常工作

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_requests number;
默认值
keepalive_requests 1000;
上下文 上游

此指令出现在1.15.3版中。

设置可以通过一个保持活动连接服务的请求最大数量。发出最大数量的请求后,连接将关闭。

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

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

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

此指令出现在1.19.10版中。

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

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

此指令出现在1.15.3版中。

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

语法 ntlm;
默认值
上下文 上游

此指令出现在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;
默认值
上下文 上游

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

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

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

此指令出现在1.7.10版中。

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

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

在1.11.6版之前,默认情况下会考虑未完成的请求。

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

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

此指令出现在1.5.12版中。

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

timeout参数的默认值为60秒。

使用除默认轮询方法之外的其他负载均衡方法时,需要在queue指令之前激活它们。

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

语法 random [two [method]];
默认值
上下文 上游

此指令出现在1.15.1版中。

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

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

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

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

语法 resolver address ... [valid=time] [ipv4=on|off] [ipv6=on|off] [status_zone=zone];
默认值
上下文 上游

此指令出现在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参数启用在指定的zone收集请求和响应的DNS服务器统计信息。

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

语法 resolver_timeout time;
默认值
resolver_timeout 30s;
上下文 上游

此指令出现在1.17.5版中。

设置名称解析的超时时间,例如

resolver_timeout 5s;

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

语法 sticky cookie name [expires=time] [domain=domain] [httponly] [samesite=strict|lax|none|$variable] [secure] [path=path];
sticky route $variable ...;
sticky learn create=$variable lookup=$variable zone=name:size [timeout=time] [header] [sync];
默认值
上下文 上游

此指令出现在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 设置的。参数值可以包含变量 (1.11.5)。
httponly
为 Cookie 添加HttpOnly 属性 (1.7.11)。
samesite=strict | lax | none | $variable
为 Cookie 添加SameSite (1.19.4) 属性,并使用以下值之一:StrictLaxNone 或使用变量 (1.23.3)。在后一种情况下,如果变量值为空,则不会将SameSite 属性添加到 Cookie 中;如果该值解析为StrictLaxNone,则分配相应的值;否则分配Strict 值。
secure
为 Cookie 添加Secure 属性 (1.7.11)。
path=path
定义 Cookie 设置的路径

如果省略任何参数,则不会设置相应的 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 会分析上游服务器的响应,并学习通常通过 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];
默认值
上下文 上游

此指令自版本 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_name
保留服务器响应标头字段。例如,“Server”响应标头字段可通过$upstream_http_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_name
保留从上游服务器获取的响应末尾的字段 (1.13.10)。