上游#
该模块用于定义可以通过 proxy_pass、fastcgi_pass、uwsgi_pass、scgi_pass、memcached_pass 和 grpc_pass 指令引用的服务器组。
配置示例#
upstream backend {
zone backend 1m;
server backend1.example.com weight=5;
server backend2.example.com:8080;
server backend3.example.com service=_example._tcp resolve;
server unix:/tmp/backend3;
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}
resolver 127.0.0.53 status_zone=resolver;
server {
location / {
proxy_pass http://backend;
}
}
指令#
bind_conn (PRO)#
当 value 被设置为变量字符串,且值不是 ""
和 "0"
时,启用将服务器连接绑定到客户端。
注意
bind_conn
指令必须在设置负载均衡方法的所有指令之后使用;
否则将不起作用。
如果同时使用了 sticky,
bind_conn
应该出现在 sticky
之后。
该指令的典型用例是代理 NTLM 认证连接,当协商开始时,客户端应与服务器绑定:
map $http_authorization $ntlm {
~*^N(?:TLM|egotiate) 1;
}
upstream ntlm_backend {
server 127.0.0.1:8080;
bind_conn $ntlm;
}
server {
# ...
location / {
proxy_pass http://ntlm_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
# ...
}
}
feedback (PRO)#
Added in version 1.6.0: PRO
|
|
默认值 |
— |
upstream |
为 upstream
启用基于反馈的负载均衡机制。
它动态调整负载均衡决策,
通过将每个对等体的权重乘以其平均反馈值来实现,
反馈值受到 variable 的时间值的影响,
并受可选条件的约束。
接受以下参数:
|
从中获取反馈值的变量。 它应代表性能或健康指标, 并且应由对等体通过头字段或其他方式提供。 该值在每次来自对等体的响应时被评估,
并根据 |
|
如果设置,反馈值将被解释为相反的, 即较低的值表示更好的性能。 |
|
反馈值在计算平均值时的权重因子。
有效值为 0 到 99 之间的整数。
默认值为 平均反馈是使用 指数移动平均 公式计算的。 因子越大,平均值受新值影响越小;
如果因子设置为 |
|
指定一个条件变量,
控制哪些响应应包含在计算中。
平均值仅在响应的条件变量不为 备注 默认情况下,来自 probes 的响应不包含在计算中;
将 $upstream_probe 变量与 |
|
允许在接收到完整响应后处理来自上游服务器的反馈, 而不仅仅是在头之后。 |
示例:
upstream backend {
zone backend 1m;
feedback $feedback_value factor=80 account=$condition_value;
server backend1.example.com;
server backend2.example.com;
}
map $upstream_http_custom_score $feedback_value {
"high" 100;
"medium" 75;
"low" 50;
default 10;
}
map $upstream_probe $condition_value {
"high_priority" "1";
"low_priority" "0";
default "1";
}
这将根据从响应头字段获得的特定分数将服务器响应分类到不同的反馈级别,
并且还添加了从 $upstream_probe 映射的条件,
仅考虑来自 high_priority
探针的响应或常规客户端请求的响应。
hash#
指定服务器组的负载均衡方法,其中客户端与服务器的映射基于哈希键值。键可以包含文本、变量及其组合。请注意,添加或移除服务器可能导致大部分键重新映射到不同的服务器。该方法与 Cache::Memcached Perl 库兼容。
如果指定了 consistent
参数,将使用 ketama 一致性哈希方法。该方法确保在添加或移除服务器时,仅有少量键会重新映射到不同的服务器。这有助于提高缓存服务器的缓存命中率。该方法与 Cache::Memcached::Fast Perl 库兼容,并设置 ketama_points 参数为 160。
ip_hash#
指定一个组应使用基于客户端 IP 地址的负载均衡方法。使用客户端 IPv4 地址的前三个八位字节或整个 IPv6 地址作为哈希键。该方法确保来自同一客户端的请求将始终传递到同一服务器,除非该服务器不可用。在这种情况下,客户端请求将传递到另一台服务器。大多数情况下,它将始终是同一台服务器。
如果需要暂时移除其中一台服务器,应使用 down
参数标记,以保留当前的客户端 IP 地址哈希。
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com down;
server backend4.example.com;
}
keepalive#
启用到上游服务器连接的缓存。
connections
参数设置每个工作进程中空闲保持连接到上游服务器的最大数量。当超过此数量时,最不常用的连接将被关闭。
备注
特别需要注意的是,keepalive 指令并不限制工作进程可以打开的上游服务器连接总数。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#
设置可以通过一个保持连接服务的最大请求数。在达到最大请求数后,连接将关闭。
定期关闭连接是为了释放每个连接的内存分配。因此,使用过高的最大请求数可能导致过多的内存使用,不推荐这样做。
keepalive_time#
限制通过一个保持连接处理请求的最长时间。在达到此时间后,连接将在后续请求处理后关闭。
keepalive_timeout#
设置一个超时时间,在此期间,与上游服务器的空闲 keepalive 连接将保持打开状态。
least_conn#
指定一个组应该使用一种负载均衡方法,将请求传递给活动连接最少的服务器,同时考虑服务器的权重。如果有多个这样的服务器,它们将按照加权轮询的方式依次尝试。
least_time (PRO)#
指定该组应使用一种负载均衡方法,其中活动服务器接收请求的机会与其平均响应时间成反比;响应时间越短,服务器接收的请求就越多。
|
指令仅计算响应头。 |
|
指令使用接收整个响应的平均时间。 |
Added in version 1.7.0: PRO
|
具有与 response_time_factor (PRO) 相同的目的,并在设置时覆盖它。 |
|
指定一个条件变量,以控制应包含在计算中的响应。只有当响应的条件变量不为 备注 默认情况下,来自 probes 的响应不会包含在计算中;将 $upstream_probe 变量与 |
相应的移动平均值,经过 factor
和 account
的调整,也在服务器的 health
对象中作为 header_time
和 response_time
呈现,位于 API 中的 upstream metrics 中。
queue (PRO)#
Added in version 1.4.0: PRO
如果无法在第一次尝试时将请求分配给代理服务器(例如,在短暂的服务中断期间或负载激增达到 max_conns 限制时),请求不会被拒绝;相反,Angie 尝试将其排队等待处理。
指令中的数字设置了 worker process 的队列中请求的最大数量。如果队列已满,将向客户端返回 502 (Bad Gateway)
错误。
备注
proxy_next_upstream 指令的逻辑也适用于排队请求。具体而言,如果为请求选择了一个服务器,但无法将其传递给该服务器,请求可能会被返回到队列中。
如果在由 timeout
设置的 时间 内未选择服务器处理排队请求(默认为60秒),将向客户端返回 502 (Bad Gateway)
错误。提前关闭连接的客户端请求也将从队列中移除;队列中请求的计数器在 API 中提供。
注意
必须在所有设置负载均衡方法的指令之后使用 queue
指令,否则将无效。
random#
指定一个组应该使用一种负载均衡方法,将请求传递给随机选择的服务器,同时考虑服务器的权重。
可选的 two
参数指示 Angie 随机选择两个服务器,然后使用指定的方法选择一个服务器。默认方法是 least_conn,将请求传递给活动连接最少的服务器。
response_time_factor (PRO)#
如果使用了 least_time (PRO) 负载均衡方法,则设置计算平均响应时间时对 前一个 值的平滑因子,使用 指数移动平均 公式。
数字越大,新值对平均值的影响就越小;如果数字设置为 90
,结果有90%的前一个值和仅10%的新值。允许的范围是0到99(含)。
相应的移动平均值在服务器的 health
对象中作为 header_time
(仅头)和 response_time
(整个响应)呈现,位于 API 中的 upstream metrics 中。
备注
计算仅考虑成功的响应;什么被认为是不成功的响应由 proxy_next_upstream、fastcgi_next_upstream、uwsgi_next_upstream、scgi_next_upstream、memcached_next_upstream 和 grpc_next_upstream 指令定义。此外,仅当所有头接收并处理时,header_time
才会更新,并且仅当整个响应接收时,response_time
才会更新。
server#
定义服务器的地址和其他参数。地址可以指定为域名或IP地址,带有可选端口,或者作为在 unix:
前缀之后指定的 UNIX 域套接字路径。如果未指定端口,则使用端口80。解析为多个IP地址的域名一次定义多个服务器。
可以定义以下参数:
|
设置服务器的权重 |
|
限制到代理服务器的最大同时活动连接数。 |
max_fails=
数字 — 设置在 fail_timeout 期间与服务器通信不成功的尝试次数,以认为服务器不可用;然后将在相同的持续时间后重试。
什么被认为是不成功的尝试由 proxy_next_upstream, fastcgi_next_upstream, uwsgi_next_upstream, scgi_next_upstream, memcached_next_upstream, 和 grpc_next_upstream 指令定义。
当达到 max_fails
时,upstream_probe (PRO) 探测也会认为该对等体不健康;除非探测认为其再次健康,否则不会接收客户端请求。
备注
如果上游中的一个 server
解析为多个对等体,其 max_fails
设置适用于每个对等体。
如果上游在解析其所有 server
指令后只包含一个对等体,则 max_fails
设置无效并将被忽略。
|
默认的不成功尝试次数 |
|
禁用尝试的计数 |
fail_timeout=
时间 — 设置在此期间与服务器通信的多次不成功尝试(max_fails)应发生的时间段,以认为服务器不可用。然后服务器在相同的时间段内不可用,然后再重试。
默认情况下,这设置为10秒。
备注
如果上游中的一个 server
解析为多个对等体,其 fail_timeout
设置适用于每个对等体。
如果上游在解析其所有 server
指令后只包含一个对等体,则 fail_timeout
设置无效并将被忽略。
|
将服务器标记为备份服务器。当主要服务器不可用时,将传递请求给它。 |
|
将服务器标记为永久不可用。 |
|
将服务器设置为排水;这意味着它仅接收以前使用 sticky 绑定的会话的请求。否则,其行为类似于 |
Added in version 1.1.0.
|
启用监控与域名对应的IP地址列表的变化,无需重新加载配置即可更新。该组应存储在 共享内存区域 中;您还需要定义一个 resolver。 |
|
启用解析DNS SRV记录并设置服务名称。要使此参数生效,请指定 resolve 服务器参数,提供不带端口号的主机名。 如果服务名称中没有点,名称将按照RFC标准形成:服务名称以 Angie通过组合规范化的服务名称和主机名来解析SRV记录,并通过DNS获得该组合的服务器列表,以及它们的优先级和权重。
|
权重影响服务器的选择,根据分配的容量:权重越高接收到的请求越多。如果由
server
指令和 SRV 记录同时设置,使用server
设置的权重。
此示例将查询 _http._tcp.backend.example.com
记录:
server backend.example.com service=http resolve;
Added in version 1.2.0: Angie
Added in version 1.1.0-P1: Angie PRO
|
设置组内的服务器 ID。 |
Added in version 1.4.0.
|
设置服务器重新上线时恢复 如果设置了该值,并且服务器再次被视为可用和健康(由 如果未设置该值,在类似情况下服务器将立即恢复其指定的权重。 |
备注
如果一个上游中只有一个 server
,slow_start
将无效并被忽略。
state (PRO)#
Added in version 1.2.0: PRO
指定保存上游服务器列表的 file。在从 我们的包 安装时,会创建一个指定的目录 /var/lib/angie/state/
(FreeBSD 上为 /var/db/angie/state/
),并赋予适当的权限来存储这些文件,因此您只需在配置中添加文件的基本名称:
upstream backend {
zone backend 1m;
state /var/lib/angie/state/<FILE NAME>;
}
此服务器列表的格式类似于 server
。文件的内容在通过配置 API 对 /config/http/upstreams/ 部分的服务器进行任何修改时都会改变。文件在 Angie 启动或配置重载时读取。
小心
为了在 upstream
块中使用 state
指令,该块不应有 server
指令;相反,必须具有共享内存区域 (zone)。
sticky#
Added in version 1.2.0: Angie
Added in version 1.1.0-P1: Angie PRO
|
|
默认值 |
— |
upstream |
配置客户端会话到代理服务器的绑定,模式由第一个参数指定;要从定义了 sticky
的服务器中排空请求,请在 server 块中使用 drain
选项。
注意
sticky
指令必须在设置负载均衡方法的所有指令之后使用;否则,将不起作用。如果也使用 bind_conn (PRO),则 bind_conn
应在 sticky
之后出现。
此模式使用 cookie 维护会话持久性。更适合于已经使用 cookie 管理会话的情况。
在此情况下,尚未绑定到任何服务器的客户端请求将根据配置的负载均衡方法发送到一个服务器。此外,Angie 会设置一个唯一值标识服务器的 cookie。
cookie 的名称 (name
) 由 sticky
指令设置,值 (value
) 对应于 server 指令的 sid 参数。如果设置了 sticky_secret 指令,参数将被另外哈希。
包含此 cookie 的后续客户端请求将转发到由 cookie 的值标识的服务器,即具有指定 sid 的服务器。如果选择服务器失败或选定服务器无法处理请求,将根据配置的负载均衡方法选择其他服务器。
该指令允许为 cookie 分配属性;默认设置的唯一属性是 path=/
。属性值指定为带变量的字符串。要删除属性,请为其设置空值:attr=
。因此,sticky cookie path=
创建一个没有 path
的 cookie。
在此情况下,Angie 创建一个名为 srv_id
的 cookie,寿命为一小时,并具有变量指定的域:
upstream backend {
server backend1.example.com:8080;
server backend2.example.com:8080;
sticky cookie srv_id domain=$my_domain max-age=3600;
}
此模式使用预定义的路由标识符,可以嵌入在 URL、cookie 或其他请求属性中。因依赖于预定义值而较不灵活,但如果这些标识符已经存在可能更适合。
在此情况下,当代理服务器收到请求时,可以为客户端分配一个路由,并以客户端和服务器都知道的方式返回其标识符。server 指令的 sid 参数值必须用作路由标识符。如果设置了 sticky_secret 指令,参数将被另外哈希。
希望使用此路由的客户端的后续请求必须包含服务器发出的标识符,以确保它进入 Angie 变量,例如在 cookie 或 请求参数 中。
指令列出了用于路由的特定变量。为选择要转发传入请求的服务器,使用第一个非空变量;然后将其与 server 指令的 sid 参数进行比较。如果选择服务器失败或选定服务器无法处理请求,将根据配置的负载均衡方法选择其他服务器。
在此情况下,Angie 在 route
cookie 中查找路由标识符,然后在 route
请求参数中查找:
upstream backend {
server backend1.example.com:8080 "sid=server 1";
server backend2.example.com:8080 "sid=server 2";
sticky route $cookie_route $arg_route;
}
此模式使用动态生成的密钥将客户端与特定代理服务器相关联;更灵活,因为它可以动态分配服务器,在共享内存区域存储会话,并支持不同的会话标识符传递方式。
在此情况下,会话基于代理服务器的响应创建。create
和 lookup
参数列出变量,指示如何创建新会话以及如何查找现有会话。两个参数可以多次出现。
会话标识符是使用 create
指定的第一个非空变量的值;例如,这可以是来自代理服务器的 cookie。
会话存储在共享内存区域;其名称和大小由 zone
参数设置。如果会话在 timeout
设置的时间内处于非活动状态,则会被删除。默认是10分钟。
希望使用会话的客户端的后续请求必须包含其标识符,以确保它进入指定为 lookup
的非空变量中;其值将与共享内存中的会话匹配。如果选择服务器失败或选定服务器无法处理请求,将根据配置的负载均衡方法选择其他服务器。
header
参数允许在接收来自代理服务器的头部后立即创建会话。如果不使用它,会话仅在处理请求后创建。
在此示例中,Angie 创建了一个会话,在响应中设置了一个名为 examplecookie
的 cookie:
upstream backend {
server backend1.example.com:8080;
server backend2.example.com:8080;
sticky learn
create=$upstream_cookie_examplecookie
lookup=$cookie_examplecookie
zone=client_sessions:1m;
}
sticky_secret#
Added in version 1.2.0: Angie
Added in version 1.1.0-P1: Angie PRO
在 cookie
和 route
模式下,为 sticky 指令的 MD5 哈希函数添加 string 作为盐值。string 可以包含变量,例如 $remote_addr:
upstream backend {
server backend1.example.com:8080;
server backend2.example.com:8080;
sticky cookie cookie_name;
sticky_secret my_secret.$remote_addr;
}
盐附加到被哈希的值;要独立验证哈希机制:
$ echo -n "<VALUE><SALT>" | md5sum
sticky_strict#
Added in version 1.2.0: Angie
Added in version 1.1.0-P1: Angie PRO
启用时,如果所需服务器不可用,Angie 将返回 HTTP 502 错误给客户端,而不是使用上游中任何其他可用服务器。
upstream#
定义一组服务器。服务器可以监听不同的端口。此外,监听 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,第二和第三个服务器各接收到一个请求。
如果与服务器通信时发生错误,请求将传递给下一个服务器,依此类推,直到尝试所有正常工作的服务器为止。如果无法从任何服务器获得成功响应,客户端将收到与最后一个服务器通信的结果。
zone#
定义共享内存区域的名称和大小,该区域保存工作进程之间共享的组的配置和运行时状态。多个组可以共享同一个区域。在这种情况下,只需指定一次大小即可。
内置变量#
http_upstream
模块支持以下内置变量:
$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
如果无法选择服务器,该变量将保存 服务器组 的 name。
$upstream_bytes_received
#
从上游服务器接收到的字节数。多个连接的值用逗号和冒号分隔,类似于 $upstream_addr 变量中的地址。
$upstream_bytes_sent
#
发送到上游服务器的字节数。多个连接的值用逗号和冒号分隔,类似于 $upstream_addr 变量中的地址。
$upstream_cache_status
#
保存访问响应缓存的状态。状态可以是 MISS
、BYPASS
、EXPIRED
、STALE
、UPDATING
、REVALIDATED
或 HIT
:
MISS
: 响应未在缓存中找到,请求转发到上游服务器。BYPASS
: 缓存被绕过,请求直接转发到上游服务器。EXPIRED
: 缓存的响应已过期,并向上游服务器发送更新内容的新请求。STALE
: 缓存的响应已过期,但仍会提供给客户端,直到从上游服务器最终获取更新。UPDATING
: 缓存的响应已过期,但仍会提供给客户端,直到从上游服务器进行的当前更新完成。REVALIDATED
: 缓存的响应已过期,但已成功重新验证,无需从上游服务器更新。HIT
: 响应已从缓存提供。
如果缓存完全被绕过而没有访问,则变量未设置。
$upstream_connect_time
#
保存与上游服务器建立连接所花费的时间;时间以秒为单位,精确到毫秒。在 SSL 的情况下,包括握手时间。多个连接的时间用逗号和冒号分隔,类似于 $upstream_addr 变量中的地址。
$upstream_header_time
#
保存从上游服务器接收响应头所花费的时间;时间以秒为单位,精确到毫秒。多个响应的时间用逗号和冒号分隔,类似于 $upstream_addr 变量中的地址。
$upstream_http_<name>
#
存储服务器响应头字段。例如,“Server”响应头字段可以通过 $upstream_http_server 变量获得。将头字段名称转换为变量名称的规则与以 "$http_" 前缀开头的变量相同。仅保存来自最后一个服务器响应的头字段。
$upstream_queue_time
#
保存请求在选择服务器之前在 队列 中花费的时间;时间以秒为单位,精确到毫秒。多个选择尝试的时间用逗号和冒号分隔,类似于 $upstream_addr 变量中的地址。
$upstream_response_length
#
保存从上游服务器获取的响应长度;长度以字节为单位。多个响应的长度用逗号和冒号分隔,类似于 $upstream_addr 变量中的地址。
$upstream_response_time
#
保存从上游服务器接收响应所花费的时间;时间以秒为单位,精确到毫秒。多个响应的时间用逗号和冒号分隔,类似于 $upstream_addr 变量中的地址。
$upstream_status
#
保存从上游服务器获取的响应的状态码。多个响应的状态码用逗号和冒号分隔,类似于 $upstream_addr 变量中的地址。如果无法选择服务器,该变量将保存 502(错误网关)状态码。
$upstream_sticky_status
#
粘性请求的状态。
|
请求发送到上游,没有启用粘性。 |
|
没有粘性信息的请求。 |
|
带有粘性信息的请求路由到所需的后端。 |
|
带有粘性信息的请求路由到由负载均衡算法选择的后端。 |
来自多个连接的值用逗号和冒号分隔,类似于 $upstream_addr 变量中的地址。
$upstream_trailer_<name>
#
存储从上游服务器获取的响应末尾的字段。