Module ngx_http_upstream_module

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

Example Configuration

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;
    }
}

周期性health checks的动态可配置组可作为我们commercial subscription的一部分使用:

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;
    }
}

Directives

Syntax:upstream name { ... }
Default:
Context:http

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

Example:

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,一个请求发送到第二和第三服务器。如果在与服务器通信期间发生错误,该请求将被传递到下一个服务器,依此类推,直到尝试所有正常运行的服务器为止。如果无法从任何一台服务器获得成功的响应,则客户端将收到与最后一台服务器的通信结果。

Syntax:server address [parameters];
Default:
Context:upstream

定义服务器的address和其他parameters。该地址可以指定为域名或 IP 地址(带有可选端口),也可以指定为在“ unix:”前缀之后指定的 UNIX 域套接字路径。如果未指定端口,则使用端口 80.解析为多个 IP 地址的域名一次定义了多个服务器。

可以定义以下参数:

weight= number

  • 设置服务器的权重,默认情况下为 1.

max_conns= number

  • 限制到代理服务器(1.11.5)的同时活动连接的最大number。默认值为零,表示没有限制。如果服务器组不在shared memory中,则此限制在每个工作进程中均有效。

Note

如果启用了idle keepalive个连接,多个workersshared memory,则到代理服务器的活动和空闲连接总数可能会超过max_conns值。

Note

从 1.5.9 版开始,在 1.11.5 版之前,此参数可作为commercial subscription的一部分使用。

max_fails= number

fail_timeout= time

  • sets

  • 在指定次数的不成功尝试与服务器通信的时间范围内,应考虑服务器不可用;

  • 以及服务器将不可用的时间段。

默认情况下,该参数设置为 10 秒。

backup

  • 将服务器标记为备份服务器。当主服务器不可用时,将传递请求。

Note

该参数不能与haship_hashrandom负载平衡方法一起使用。

down

  • 将服务器标记为永久不可用。

此外,以下参数是我们的commercial subscription的一部分:

resolve

  • 监视与服务器域名相对应的 IP 地址的更改,并自动修改上游配置,而无需重新启动 nginx(1.5.12)。服务器组必须位于shared memory中。

为了使该参数起作用,必须在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,当不正常的服务器变为healthy或在一段时间后服务器变为unavailable可用时,服务器会将其重量从零恢复到标称值。默认值为零,即禁用慢速启动。

Note

该参数不能与haship_hashrandom负载平衡方法一起使用。

drain

  • 将服务器置于“排水”模式(1.13.6)。在这种模式下,仅对服务器的bound请求将被代理。

Note

在版本 1.13.6 之前,只能使用API模块更改参数。

Note

如果组中只有一台服务器,则max_failsfail_timeoutslow_start参数将被忽略,并且永远不会认为该服务器不可用。

Syntax:zone name [size];
Default:
Context:upstream

该指令出现在 1.9.0 版中。

定义共享内存区域的namesize,该区域保留工作进程之间共享的组的配置和运行时状态。几个组可以共享同一区域。在这种情况下,仅指定一次size就足够了。

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

Note

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

Syntax:state file;
Default:
Context:upstream

该指令出现在 1.9.7 版中。

指定一个file,以保留动态可配置组的状态。

Examples:

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

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

Note

configuration reloadbinary upgrade期间所做的更改可能会丢失。

Note

该指令可作为commercial subscription的一部分使用。

Syntax:hash key [consistent];
Default:
Context:upstream

该指令出现在版本 1.7.2 中。

指定服务器组的负载平衡方法,其中客户端-服务器映射基于散列的key值。 key可以包含文本,变量及其组合。请注意,从组中添加或删除服务器可能会导致将大多数密钥重新映射到其他服务器。该方法与Cache::Memcached Perl 库兼容。

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

Syntax:ip_hash;
Default:
Context:upstream

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

Note

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

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

Example:

upstream backend {
    ip_hash;

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

Note

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

Syntax:keepalive connections;
Default:
Context:upstream

该指令出现在版本 1.1.4 中。

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

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

Note

特别要注意的是,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”,并且应清除“连接”Headers 字段:

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 "";
        ...
    }
}

Note

或者,可以通过将“ Connection:Keep-Alive”Headers 字段传递给上游服务器来使用 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;
        ...
    }
}

Note

当使用默认循环方法以外的负载平衡器方法时,有必要在keepalive指令之前将其激活。

Note

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

Syntax:keepalive_requests number;
Default:keepalive_requests 100;
Context:upstream

该指令出现在 1.15.3 版中。

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

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

Syntax:keepalive_timeout timeout;
Default:keepalive_timeout 60s;
Context:upstream

该指令出现在 1.15.3 版中。

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

Syntax:ntlm;
Default:
Context:upstream

该指令出现在 1.9.2 版中。

允许使用NTLM Authentication代理请求。一旦客户端发送带有“ Authorization”Headers 字段值以“ Negotiate”或“ NTLM”开头的请求,则上游连接将绑定到客户端连接。其他客户端请求将通过相同的上游连接进行代理,同时保留身份验证上下文。

为了使 NTLM 身份验证起作用,必须启用到上游服务器的保持连接。 proxy_http_version伪指令应设置为“ 1.1”,并且应清除“连接”Headers 字段:

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 "";
        ...
    }
}

Note

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

Note

该指令可作为commercial subscription的一部分使用。

Syntax:least_conn;
Default:
Context:upstream

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

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

Syntax:least_time header | last_byte [inflight];
Default:
Context:upstream

该指令出现在 1.7.10 版本中。

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

如果指定了header参数,则将使用接收response header的时间。如果指定了last_byte参数,则使用接收full response的时间。如果指定了inflight参数(1.11.6),还将考虑不完整的请求。

Note

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

Note

该指令可作为commercial subscription的一部分使用。

Syntax:queue number [timeout=time];
Default:
Context:upstream

该指令出现在 1.5.12 版本中。

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

timeout参数的默认值为 60 秒。

Note

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

Note

该指令可作为commercial subscription的一部分使用。

Syntax:random [two [method]];
Default:
Context:upstream

该指令出现在 1.15.1 版中。

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

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

least_time方法以最小的平均响应时间和最少的活动连接数将请求传递给服务器。如果指定least_time=header,则使用接收response header的时间。如果指定least_time=last_byte,则使用接收full response的时间。

Note

least_time方法可作为commercial subscription的一部分使用。

Syntax:resolver address ... [valid=time] [ipv6=on|off] [status_zone=zone];
Default:
Context:upstream

该指令出现在 1.17.5 版中。

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

resolver 127.0.0.1 [::1]:5353;

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

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

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

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

Note

为防止 DNS 欺骗,建议在适当安全的受信任本地网络中配置 DNS 服务器。

可选的status_zone参数启用zone中指定请求和响应的 DNS 服务器统计信息的collection

Note

该指令可作为commercial subscription的一部分使用。

Syntax:resolver_timeout time;
Default:resolver_timeout 30s;
Context:upstream

该指令出现在 1.17.5 版中。

设置名称解析超时,例如:

resolver_timeout 5s;

Note

该指令可作为commercial subscription的一部分使用。

Syntax:sticky cookie name [expires=time] [domain=domain] [httponly] [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 地址和端口或 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)。
    • secure

      • Secure属性添加到 cookie(1.7.11)。
    • path= path

      • 定义为其设置了 Cookie 的path

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

route

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

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

Example:

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参数配置。一个 1 MB 的区域可以在 64 位平台上存储大约 4000 个会话。在timeout参数指定的时间内未访问的会话将从区域中删除。默认情况下,timeout设置为 10 分钟。

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

sync参数(1.13.8)启用共享存储区的synchronization

Note

该指令可作为commercial subscription的一部分使用。

Syntax:sticky_cookie_insert name [expires=time] [domain=domain] [path=path];
Default:
Context:upstream

从 1.5.7 版开始,此指令已过时。应该使用具有新语法的等效sticky指令代替:

Note

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

Embedded Variables

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”响应 Headers 字段(1.7.1)中发送的具有指定name的 cookie。仅保存来自最后一个服务器响应的 cookie。

$upstream_header_time

  • 花费时间从上游服务器接收响应头(1.7.10);时间以毫秒为单位,以秒为单位。多个响应的时间之间用逗号和冒号分隔,例如$upstream_addr变量中的地址。

$upstream_http_ name

  • 保留服务器响应头字段。例如,“服务器”响应 Headers 字段可通过$upstream_http_server变量获得。将标题字段名称转换为变量名称的规则与以“ $http_”开头的变量的规则相同。仅保存来自最后一个服务器的响应的 Headers 字段。

$upstream_queue_time

  • 保持请求花费在上游queue(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)获得的响应末尾保留字段。