Upstream#

提供用于描述服务器组的上下文,可在 proxy_pass 指令中使用。

配置示例#

upstream backend {
    hash $remote_addr consistent;
    zone backend 1m;

    server backend1.example.com:1935  weight=5;
    server unix:/tmp/backend3;
    server backend3.example.com       service=_example._tcp resolve;

    server backup1.example.com:1935   backup;
    server backup2.example.com:1935   backup;
}

resolver 127.0.0.53 status_zone=resolver;

server {
    listen 1936;
    proxy_pass backend;
}

指令#

upstream#

语法

upstream name { ... }

默认值

上下文

stream

描述一个服务器组。服务器可以监听不同的端口。此外,监听 TCP 和 UNIX 域套接字的服务器可以混合使用。

示例:

upstream backend {
    server backend1.example.com:1935 weight=5;
    server 127.0.0.1:1935            max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend2;
    server backend3.example.com:1935 resolve;

    server backup1.example.com:1935  backup;
}

默认情况下,连接使用加权轮询均衡方法在服务器之间分配。在上面的示例中,每 7 个连接将按如下方式分配:5 个连接到 backend1.example.com:1935,第二个和第三个服务器各 1 个连接。

如果在与服务器通信期间发生错误,连接将传递给下一个服务器,依此类推,直到尝试所有正常工作的服务器。如果与所有服务器的通信都失败,连接将被关闭。

server#

语法

server address [parameters];

默认值

上下文

upstream

定义服务器的地址和其他参数。地址可以指定为域名或带有必需端口的 IP 地址,或者指定为 unix: 前缀后的 UNIX 域套接字路径。解析为多个 IP 地址的域名会一次定义多个服务器。

可以定义以下参数:

weight=number

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

max_conns=number

限制到代理服务器的最大同时活动连接数。默认值为 0,表示没有限制。如果服务器组不在 共享内存 中,则该限制对每个工作进程生效。

max_fails=number — 设置在 fail_timeout 设置的持续时间内 与服务器通信的失败尝试次数, 达到该次数后将服务器视为不可用; 然后在相同的持续时间后重试。

这里,失败尝试是指与服务器建立连接时的错误或超时。

备注

如果组中的 server 指令解析为多个服务器, 其 max_fails 设置将单独应用于每个服务器。

如果在解析所有 server 指令后,上游只包含一个服务器, 则 max_fails 设置无效并将被忽略。

max_fails=1

默认尝试次数。

max_fails=0

禁用尝试次数统计。

fail_timeout=time — 设置时间段,在此期间应发生指定次数的 与服务器通信失败尝试(max_fails)才将服务器视为不可用。 然后服务器在相同的时间段内保持不可用状态, 之后才会重试。

默认情况下,此值设置为 10 秒。

备注

如果组中的 server 指令解析为多个服务器, 其 fail_timeout 设置将单独应用于每个服务器。

如果在解析所有 server 指令后,上游只包含一个服务器, 则 fail_timeout 设置无效并将被忽略。

backup

将服务器标记为备份服务器。当主服务器不可用时,它将接收请求。

down

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

drain (PRO)

将服务器标记为排空状态;这意味着 它只接收来自之前通过 sticky 绑定的会话的请求。 否则其行为类似于 down

警告

backup 参数不能与 hashrandom 负载均衡方法一起使用。

downdrain 参数互斥。

resolve

启用监控与域名对应的 IP 地址列表的变化, 无需重新加载配置即可更新。 该组必须位于 共享内存区域 中; 还必须定义 resolver

service=name

启用解析 DNS SRV 记录并设置服务名称。 要使此参数生效,还必须指定 resolve 参数, 且不在主机名中指定服务器端口。

如果服务名称中没有点, 则根据 RFC 标准形成名称: 服务名称前加 _ 前缀, 然后在点后添加 _tcp。 因此,服务名称 http 将变成 _http._tcp

Angie 通过组合规范化的服务名称和主机名来解析 SRV 记录, 并通过 DNS 获取该组合的服务器列表, 以及它们的优先级和权重。

  • 最高优先级的 SRV 记录 (共享最小优先级值的记录) 解析为主服务器, 其他记录成为备份服务器。 如果 server 设置了 backup, 最高优先级的 SRV 记录解析为备份服务器, 其他记录被忽略。

  • 权重类似于 server 指令的 weight 参数。 如果指令和 SRV 记录都设置了权重, 则使用指令设置的权重。

此示例将查找 _http._tcp.backend.example.com 记录:

server backend.example.com service=http resolve;

sid=id

设置组中的服务器 ID。如果未指定该参数, ID 将设置为 IP 地址和端口或 UNIX 域套接字路径的 十六进制 MD5 哈希值。

slow_start=time

设置服务器在恢复服务时, 使用 轮询least_conn 负载均衡方法恢复其权重的 时间

如果设置了该参数, 并且服务器在根据 max_failsupstream_probe (PRO) 判定失败后再次被认为健康, 服务器将在指定的时间段内逐渐恢复其指定的权重。

如果未设置该参数, 在类似情况下, 服务器将立即以其指定的权重开始工作。

备注

如果 upstream 中只指定了一个 serverslow_start 将不起作用并被忽略。

state (PRO)#

语法

state file;

默认值

上下文

upstream

指定持久化存储上游服务器列表的 file。 从 我们的软件包 安装时, 会创建一个具有适当权限的专用目录 /var/lib/angie/state/ (FreeBSD 上为 /var/db/angie/state/) 用于存储此类文件, 因此您只需在配置中添加文件名:

upstream backend {

    zone backend 1m;
    state /var/lib/angie/state/<文件名>;
}

这里的服务器列表格式类似于 server。 每当通过配置 API 在 /config/stream/upstreams/ 部分 修改服务器时,文件内容都会更改。 该文件在 Angie 启动或配置重载时读取。

警告

要在 upstream 块中使用 state 指令, 其中不应有 server 指令, 但需要共享内存区(zone)。

zone#

语法

zone name [size];

默认值

上下文

upstream

定义共享内存区的名称和大小,该内存区存储组的配置和运行时状态,在工作进程之间共享。多个组可以使用同一个区。在这种情况下,只需指定一次大小即可。

backup_switch (PRO)#

语法

backup_switch permanent[=time];

默认值

上下文

upstream

该指令启用从 活动 组而不是主组开始服务器选择的能力, 即从之前成功找到服务器的组开始。 如果在活动组中无法为下一个请求找到服务器, 并且搜索移至备份组, 该备份组将成为活动组, 后续请求将首先定向到该组中的服务器。

如果定义了 permanent 参数但没有 时间 值, 该组在选择后保持活动状态, 不会自动重新检查优先级较低的组。 如果指定了 time, 组的活动状态在指定的时间间隔后过期, 负载均衡器将再次检查优先级较低的组, 如果服务器正常工作则返回到这些组。

示例:

upstream media_backend {
    server primary1.example.com:1935;
    server primary2.example.com:1935;

    server reserve1.example.com:1935 backup;
    server reserve2.example.com:1935 backup;

    backup_switch permanent=2m;
}

如果负载均衡器从主服务器切换到备份组, 所有后续请求将由该备份组处理 2 分钟。 2 分钟过期后,负载均衡器重新检查主服务器, 如果它们正常工作,则再次使其成为活动组。

feedback (PRO)#

语法

feedback variable [inverse] [factor=number] [account=condition_variable];

默认值

上下文

upstream

upstream 启用基于反馈的负载均衡机制。 它通过将每个代理服务器的权重乘以平均反馈值来动态调整负载均衡决策, 该值根据 variable 值随时间变化, 并受可选条件约束。

可以指定以下参数:

variable

从中获取反馈值的变量。 它应该表示性能或健康指标; 假定由服务器提供。

该值在服务器的每个响应中进行评估, 并根据 inversefactor 设置 纳入移动平均值。

inverse

如果设置了该参数,反馈值将被反向解释: 较低的值表示更好的性能。

factor

计算平均值时反馈值的加权因子。 有效值为 0 到 99 的整数。 默认值为 90

平均值使用 指数平滑 公式计算。

因子越大,新值对平均值的影响越小; 如果指定 90,将取 90% 的先前值 和仅 10% 的新值。

account

指定一个条件变量, 用于控制如何在计算中统计连接。 仅当条件变量 不等于 """0" 时, 才使用反馈值更新平均值。

备注

默认情况下,来自 探测 的流量 不包含在计算中; 将 $upstream_probe 变量 与 account 结合使用可以包含它们 或甚至排除其他所有内容。

示例:

upstream backend {

    zone backend 1m;

    feedback $feedback_value factor=80 account=$condition_value;

    server backend1.example.com:1935  weight=1;
    server backend2.example.com:1935  weight=2;
}

map $protocol $feedback_value {
    "TCP"                      100;
    "UDP"                      75;
    default                    10;
}

map $upstream_probe $condition_value {
    "high_priority" "1";
    "low_priority"  "0";
    default         "1";
}

此配置根据各个会话中使用的协议 按反馈级别对服务器进行分类, 并在 $upstream_probe 上添加条件, 仅统计 high_priority 探测 或常规客户端会话。

hash#

语法

hash key [consistent];

默认值

上下文

upstream

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

使用示例:

hash $remote_addr;

当使用解析为多个 IP 地址的域名时 (例如,使用 resolve 参数), 服务器不会对接收到的地址进行排序,因此它们的顺序可能在 不同服务器之间有所不同,这会影响客户端分布。 为确保一致的分布, 请使用 consistent 参数。

如果指定了 consistent 参数,将使用 ketama 一致性哈希方法代替上述方法。该方法确保当从组中添加或删除服务器时,只有最少数量的键会重新映射到其他服务器。将该方法用于缓存服务器可提供更高的缓存命中率。该方法与 Perl Cache::Memcached::Fast 库兼容,其中 ketama_points 参数设置为 160。

least_conn#

语法

least_conn;

默认值

上下文

upstream

为组指定负载均衡方法,其中连接传递给活动连接数最少的服务器,同时考虑服务器权重。如果有多个合适的服务器,则按照它们的权重以循环(轮询)方式选择它们。

least_time (PRO)#

语法

least_time connect | first_byte | last_byte [factor=number] [account=condition_variable];

默认值

上下文

upstream

为组指定负载均衡方法,将连接传递给活动服务器的概率与其平均响应时间成反比;响应时间越低,服务器将接收到的连接就越多。

connect

该指令考虑建立连接的平均时间。

first_byte

该指令使用接收响应第一个字节的平均时间。

last_byte

该指令使用接收完整响应的平均时间。

factor

执行与 response_time_factor (PRO) 相同的功能, 如果指定了该参数,则会覆盖它。

account

指定一个条件变量, 用于控制在计算中考虑哪些连接。 仅当连接的条件变量 不等于 """0" 时, 才会更新平均值。

备注

默认情况下,探测 不包含在计算中; 将 $upstream_probe 变量 与 account 结合使用可以包含它们, 甚至排除其他所有内容。

当前值在 API 的 upstream 指标 中, 以服务器的 health 对象中的 connect_timefirst_byte_timelast_byte_time 形式呈现。

random#

语法

random [two];

默认值

上下文

upstream

为组指定负载均衡方法,将连接传递给随机选择的服务器,同时考虑服务器权重。

如果指定了可选的 two 参数,Angie 会随机选择两个服务器,然后使用指定的方法选择一个服务器。默认方法是 least_conn,它将连接传递给活动连接数最少的服务器。

response_time_factor (PRO)#

语法

response_time_factor number;

默认值

response_time_factor 90;

上下文

upstream

least_time (PRO) 负载均衡方法指定在使用 指数加权移动平均 公式计算平均响应时间时, 先前 值的平滑因子。

指定的 number 越大,新值对平均值的影响就越小;如果 指定为 90,将采用 90% 的先前值,仅采用 10% 的 新值。有效值范围为 0 到 99(含)。

当前计算结果在 API 的 upstream 指标 中,以服务器的 health 对象中的 connect_time (建立连接的时间)、first_byte_time (接收响应第一个字节的时间)和 last_byte_time (接收完整响应的时间)形式呈现。

备注

计算中仅考虑成功的响应; 什么构成不成功的响应 由 proxy_next_upstream 指令确定。

sticky#

语法

sticky route $variable...;

sticky learn zone=zone create=$create_var1... lookup=$lookup_var1... [connect] [norefresh] [timeout=time];

sticky learn lookup=$lookup_var1... remote_action=uri remote_result=$remote_var [remote_uri=uri];

默认值

上下文

upstream

根据第一个参数中指定的模式, 配置客户端与上游服务器之间的粘性会话。 要逐步将带有 sticky 的服务器移出轮换, 可以在 server 块中使用 drain 选项(PRO)。

警告

sticky 指令必须出现在所有负载均衡方法指令之后, 否则将无法工作。

此模式使用预定义的路由标识符, 这些标识符可以嵌入到 Angie 可访问的连接属性中。 它的灵活性较低,因为它依赖于预定义的值, 但如果已经在使用此类标识符,则更适合。

在这里,建立连接时,上游服务器 可以为客户端分配一个路由,并以双方 都知道的方式返回其标识符。 路由标识符 应使用 server 指令的 sid 参数的值。 请注意,如果指定了 sticky_secret 指令, 该参数会被额外哈希处理。

希望使用此路由的客户端的后续连接 必须包含服务器颁发的标识符,并以这样的方式 使其最终出现在 Angie 变量中。

指令参数指定用于路由的变量。 要选择传入连接定向到的服务器, 使用第一个非空变量; 然后将其与 server 指令的 sid 参数进行比较。 如果服务器选择失败 或所选服务器无法接受连接, 将根据配置的负载均衡方法 选择另一台服务器。

这里 Angie 在 $route 变量中查找路由标识符, 该变量根据 $ssl_preread_server_name 接收其值(注意必须启用 ssl_preread):

stream {

    map $ssl_preread_server_name $route {

        a.example.com            a;
        b.example.com            b;
        default                  "";
    }

    upstream backend {

        server 127.0.0.1:8081 sid=a;
        server 127.0.0.1:8082 sid=b;

        sticky route $route;
    }

    server {

        listen 127.0.0.1:8080;

        ssl_preread on;

        proxy_pass backend;
    }
}

sticky 指令会考虑 upstream 中服务器的状态:

  • 标记为 down 或由于故障而暂时不可用的服务器 将被排除在选择之外。

  • 已达到最大连接数的服务器 (使用 max_conns 时)将被暂时跳过。

  • 带有 drain 选项的服务器(PRO) 在 sticky 模式下当标识符匹配时 可以被选择用于创建新会话。

  • 如果先前不可用的服务器恢复, sticky 会自动恢复使用它。

sticky 的行为可以通过 sticky_secretsticky_strict 指令进一步配置。 如果 sticky 无法选择服务器或服务器不可用, 请求将根据所选的负载均衡方法进行处理, 除非启用了 sticky_strict 指令。 在 sticky_strict on; 模式下,请求将被拒绝并返回错误。

sticky 指令的 zone 参数中 指定的共享内存区域 不能在不同的 upstream 组之间共享; 每个组必须使用自己的区域。

sticky_secret#

语法

sticky_secret string;

默认值

上下文

upstream

string 作为盐值添加到 MD5 哈希函数中, 用于 route 模式下的 sticky 指令。 String 可以包含变量,例如 $remote_addr

upstream backend {
    server 127.0.0.1:8081 sid=a;
    server 127.0.0.1:8082 sid=b;

    sticky route $route;
    sticky_secret my_secret.$remote_addr;
}

盐值添加在哈希值之后; 要独立验证哈希机制:

$ echo -n "<VALUE><SALT>" | md5sum

sticky_strict#

语法

sticky_strict on | off;

默认值

sticky_strict off;

上下文

upstream

启用时,如果所需的服务器不可用, Angie 将向客户端返回连接错误, 而不是回退到另一个可用的服务器, 后者是未找到匹配服务器时的默认行为。

内置变量#

stream_upstream 模块支持以下内置变量:

$sticky_sessid#

sticky 中的 remote_action 一起使用; 存储从 lookup 获取的初始会话标识符。

$sticky_sid#

sticky 中的 remote_action 一起使用; 存储先前与会话关联的服务器标识符。

sticky_sid 包含 upstream 块中 server 指令的 sid= 参数的值(如果指定), 或者服务器名称的 MD5 哈希值。

$upstream_addr#

存储上游服务器的 IP 地址和端口,或 UNIX 域套接字的路径。如果在代理过程中联系了多个服务器,它们的地址用逗号分隔,例如:

192.168.1.1:1935, 192.168.1.2:1935, unix:/tmp/sock

如果无法选择服务器,该变量保留 服务器组 的名称。

$upstream_bytes_received#

从上游服务器接收的字节数。多个连接的值用逗号和冒号分隔,类似于 $upstream_addr 变量中的地址。

$upstream_bytes_sent#

发送到上游服务器的字节数。多个连接的值用逗号和冒号分隔,类似于 $upstream_addr 变量中的地址。

$upstream_connect_time#

连接到上游服务器的时间;时间以秒为单位保存,具有毫秒分辨率。多个连接的时间用逗号和冒号分隔,类似于 $upstream_addr 变量中的地址。

$upstream_first_byte_time#

接收第一个数据字节的时间;时间以秒为单位保存,具有毫秒分辨率。多个连接的时间用逗号分隔,类似于 $upstream_addr 变量中的地址。

$upstream_session_time#

会话持续时间,以秒为单位,具有毫秒分辨率。多个连接的时间用逗号分隔,类似于 $upstream_addr 变量中的地址。

$upstream_sticky_status#

粘性连接的状态。

""

连接路由到未启用 sticky 的服务器组。

NEW

连接不包含粘性信息。

HIT

包含粘性信息的连接路由到所需的服务器。

MISS

包含粘性信息的连接路由到由负载均衡算法选择的服务器。

多个连接的值用逗号和冒号分隔, 类似于 $upstream_addr 变量中的地址。