模块 ngx_http_upstream_module

示例配置
指令
     上游服务器组
     服务器
     区域
     状态
     哈希
     IP 哈希
     保持活动连接
     保持活动连接请求数
     保持活动连接超时时间
     保持活动连接超时
     NTLM
     最少连接
     最少时间
     队列
     随机
     解析器
     解析器超时
     粘性
     粘性 Cookie 插入
嵌入式变量

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 名称 { ... }
默认值:
上下文: 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

定义服务器的地址和其他参数。地址可以指定为域名或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
将服务器标记为备用服务器。主服务器不可用时,它将传递请求。
该参数不能与haship_hashrandom负载平衡方法一起使用。
down
将服务器标记为永久不可用。

另外,以下参数作为我们的商业订阅的一部分可用:

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

为了使该参数工作,必须在http块或相应的上游块中指定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负载均衡方法一起使用。
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::Memcached Perl 库兼容。

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

语法: ip_hash;
默认:
上下文: upstream

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

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

如果需要临时移除其中一台服务器,应该使用 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中。

如果在处理请求时无法立即选择上游服务器,则该请求将被放入队列中。该指令指定了同时可以在队列中的请求的最大数量。如果队列已满,或者在指定的超时参数中无法选择要传递请求的服务器,则将向客户端返回 502 (Bad Gateway) 错误。

timeout 参数的默认值为 60 秒。

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

此指令包含在我们的商业订阅中。

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

此指令首次出现在版本 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];
默认值:
上下文: 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 参数启用在指定的 zone 中收集请求和响应的 DNS 服务器统计信息。

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

语法: resolver_timeout time;
默认:
resolver_timeout 30s;
上下文: upstream

该指令出现在版本 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];
默认:
上下文: 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地址和端口的MD5哈希的十六进制表示,或UNIX域套接字路径的十六进制表示。但是,如果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的时间。特殊值max将导致cookie在“2037年12月31日 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,则从中获取路由。否则,将使用 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参数指定指示如何创建新会话和搜索现有会话的变量,分别。这两个参数可以多次指定,此时将使用第一个非空变量。

会话存储在共享内存区域中,其名称大小zone参数配置。在64位平台上,1MB 区域可存储约4000个会话。在timeout参数指定的时间内未访问的会话将从区域中删除。默认情况下,timeout设置为10分钟。

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

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

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

语法: sticky_cookie_insert 名称 [expires=时间] [domain=] [path=路径];
默认:
上下文: upstream

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

sticky cookie 名称 [expires=时间] [domain=] [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)。