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 指令

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

server 指令

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

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

可以定义以下参数:

weight=number

设置服务器的权重,默认为 1。

max_conns=number

限制与代理服务器 (1.11.5) 的同时活动连接的最大数量。默认值为零,表示没有限制。如果服务器组不驻留在共享内存中,则限制适用于每个工作进程。

如果启用了空闲保活连接、多个工作人员和共享内存,则与代理服务器的活动和空闲连接总数可能会超过 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

  • sets 与服务器通信的指定次数的不成功尝试碰巧认为服务器不可用的时间;以及服务器将被视为不可用的时间段。默认情况下,该参数设置为 10 秒。

  • backup 将服务器标记为备份服务器。当主服务器不可用时,它将被传递请求。该参数不能与 hash、ip_hash 和随机负载均衡方法一起使用。

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

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

  • resolve 监控服务器域名对应的IP地址变化,自动修改upstream配置,无需重启nginx(1.5.12)。服务器组必须驻留在共享内存中。为了使此参数起作用,必须在 http 块或相应的上游块中指定解析器指令。

  • route=string 设置服务器路由名称。

  • service=name 启用 DNS SRV 记录解析并设置服务名称 (1.9.13)。为了使该参数起作用,必须为服务器指定解析参数并指定不带端口号的主机名。

如果服务名称不包含点(“.”),则构造符合 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 记录被解析为备用服务器。如果为服务器指定了备份参数,则将高优先级的 SRV 记录解析为备份服务器,其余的 SRV 记录将被忽略。

  • slow_start=time 设置服务器将其权重从零恢复到标称值的时间,当不健康的服务器变得健康时,或者当服务器在一段时间后变得可用时,它被认为不可用。 默认值为零,即禁用慢启动。

该参数不能与 hash、ip_hash 和随机负载均衡方法一起使用。

drain

将服务器置于“排水”模式(1.13.6)。在这种模式下,只有绑定到服务器的请求才会被代理。

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

如果组中只有一个服务器,则忽略 max_fails、fail_timeout 和 slow_start 参数,这样的服务器永远不会被视为不可用。

zone 指令

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

该指令出现在版本 1.9.0 中。

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

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

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

state 指令

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

该指令出现在版本 1.9.7 中。

指定一个保持动态可配置组状态的文件。

例子:

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

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

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

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

hash 指令

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

该指令出现在版本 1.7.2 中。

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

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

ip_hash 指令

语 法: 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 指令

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

该指令出现在版本 1.1.4 中。

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

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

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

当使用默认循环方法以外的负载平衡方法时,需要在 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_requests 指令

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

该指令出现在版本 1.15.3 中。

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

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

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

keepalive_time 指令

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

该指令出现在 1.19.10 版本中。

限制通过一个保活连接处理请求的最长时间。 达到这个时间后,连接在后续请求处理后关闭。

keepalive_timeout 指令

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

该指令出现在版本 1.15.3 中。

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

ntlm 指令

语 法: ntlm;
默认值:—
上下文:upstream

该指令出现在版本 1.9.2 中。

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

为了使 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 指令

语 法: least_conn;
默认值:—
上下文:upstream

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

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

least_time 指令

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

该指令出现在 1.7.10 版本中。

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

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

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

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

queue 指令

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

该指令出现在版本 1.5.12 中。

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

timeout 参数的默认值为 60 秒。

当使用默认循环方法以外的负载平衡器方法时,需要在队列指令之前激活它们。

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

random 指令

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

该指令出现在版本 1.15.1 中。

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

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

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

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

resolver 指令

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

该指令出现在版本 1.17.5 中。

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

resolver 127.0.0.1 [::1]:5353;

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

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

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

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

为防止 DNS 欺骗,建议在安全可靠的本地网络中配置 DNS 服务器。

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

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

resolver_timeout 指令

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

该指令出现在版本 1.17.5 中。

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

resolver_timeout 5s;

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

sticky 指令

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

此指令出现在版本1.5.7中。

启用会话关联,使来自同一客户端的请求传递到一组服务器中的同一服务器。

有三种方法可用:

cookie

使用 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 的时间。 特殊值 max 将导致 cookie 在“2037 年 12 月 31 日 23:55:55 GMT”过期。 如果未指定该参数,则会导致 cookie 在浏览器会话结束时过期。

domain=domain

定义为其设置 cookie 的域。参数值可以包含变量 (1.11.5)。

httponly

将 HttpOnly 属性添加到 cookie (1.7.11)。

samesite=strict | lax | none

使用以下值 (1.19.4) 之一将 SameSite 属性添加到 cookie:Strict、Lax 或 None。

secure

将 Secure 属性添加到 cookie (1.7.11)。

path=path

定义为其设置 cookie 的路径。

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

route

当使用 route 方法时,代理服务器在收到第一个请求时为客户端分配一个路由。此客户端的所有后续请求都将在 cookie 或 URI 中携带路由信息。将此信息与服务器指令的 “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 的进一步请求将被传递到同一服务器。如果服务器无法处理请求,则选择新服务器,就好像客户端尚未绑定一样。

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

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

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

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

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

sticky_cookie_insert 指令

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

该指令自 1.5.7 版起已过时。 应改用具有新语法的等效粘性指令:

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 变量中的地址一样。

$upstream_cookie_name

上游服务器在 “Set-Cookie” 响应头字段(1.7.1)中发送的具有指定名称的 cookie。仅保存来自最后一个服务器响应的 cookie。

$upstream_header_time

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

$upstream_http_name

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

$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)获得的响应末尾的字段。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号