区域加权负载均衡

此示例演示了 Envoy 代理中的 区域加权负载均衡 功能。演示模拟了一个后端服务驻留在两个本地区域和一个远程区域的场景。

此演示中使用的组件如下:

  • 一个客户端容器:运行 Envoy 代理

  • 与客户端位于同一区域的后端容器,优先级设置为 0,称为 local-1

  • 与客户端位于同一区域的后端容器,优先级设置为 1,称为 local-2

  • 位于远程区域的后端容器,优先级设置为 1,称为 remote-1

  • 位于远程区域的后端容器,优先级设置为 2,称为 remote-2

客户端 Envoy 代理在同一个 Envoy 集群中配置了 4 个后端容器,以便 Envoy 处理对这些后端服务器的负载均衡。从这里我们可以看到,我们有 3 个不同优先级的区域

  • 优先级 0:local-1

  • 优先级 1:local-2remote-1

  • 优先级 2:remote-2

在 Envoy 中,当给定区域的健康状况下降到阈值以下时(默认情况下为 71%),下一个优先级区域将开始共享请求负载。以下演示将展示此行为。

步骤 1:启动所有容器

在终端中,移动到 examples/locality_load_balancing 目录。

要构建此沙箱示例并启动示例服务,请运行以下命令

# Start demo
$ docker compose up --build -d

区域配置通过静态 Envoy 配置文件在客户端容器中设置。请参阅 proxy configuration 文件的 cluster 部分。

注意

必须在 common_lb_config 中设置 locality_weighted_lb_config 才能使用 load_balancing_weight

步骤 2:在最高优先级区域中只有一个副本的场景

在此场景中,每个区域都运行着 1 个健康副本,所有请求都应发送到具有最高优先级的区域(即为优先级设置的最低整数 - 0),即 local-1

# all requests to local-1
$ docker compose exec -T client-envoy python3 client.py https://127.0.0.1:3000/ 100
Hello from backend-local-1!: 100, 100.0%
Failed: 0

如果区域 local-1 变得不健康(即未能通过 Envoy 健康检查),则请求应在后续优先级区域之间进行负载均衡,这些区域是 local-2remote-1。它们都具有优先级 1。然后我们向后端集群发送 100 个请求,并检查响应者。

# bring down local-1
$ docker compose exec -T client-envoy curl -s locality-load-balancing_backend-local-1_1:8080/unhealthy
[backend-local-1] Set to unhealthy

# local-2 and remote-1 localities split the traffic 50:50
$ docker compose exec -T client-envoy python3 client.py https://127.0.0.1:3000/ 100
Hello from backend-remote-1!: 51, 51.0%
Hello from backend-local-2!: 49, 49.0%
Failed: 0

现在如果 local-2 也变得不健康,则优先级 1 区域的健康状况仅为 50%。因此,优先级 2 区域开始共享请求负载。请求将发送到 remote-1remote-2

# bring down local-2
$ docker compose exec -T client-envoy curl -s locality-load-balancing_backend-local-2_1:8080/unhealthy

# remote-1 locality receive 100% of the traffic
$ docker compose exec -T client-envoy python3 client.py https://127.0.0.1:3000/ 100
Hello from backend-remote-1!: actual weight 69.0%
Hello from backend-remote-2!: actual weight 31.0%
Failed: 0

步骤 3:恢复服务器

在继续之前,我们需要先启动 local-1 和 local-2 服务器。

# recover local-1 and local-2 after the demo
$ docker compose exec -T client-envoy curl -s locality-load-balancing_backend-local-1_1:8080/healthy
$ docker compose exec -T client-envoy curl -s locality-load-balancing_backend-local-2_1:8080/healthy

步骤 4:在最高优先级区域中有多个副本的场景

为了演示基于区域的负载均衡在多个副本设置中的工作方式,现在让我们将 local-1 区域扩展到 5 个副本。

$ docker compose up --scale backend-local-1=5 -d

我们将展示 local-1 只是部分健康的场景。因此,让我们在 local-1 中关闭 4 个副本。

# bring down local-1 replicas
$ docker compose exec -T client-envoy curl -s locality-load-balancing_backend-local-1_2:8080/unhealthy
$ docker compose exec -T client-envoy curl -s locality-load-balancing_backend-local-1_3:8080/unhealthy
$ docker compose exec -T client-envoy curl -s locality-load-balancing_backend-local-1_4:8080/unhealthy
$ docker compose exec -T client-envoy curl -s locality-load-balancing_backend-local-1_5:8080/unhealthy

然后我们再次检查端点

# check healthiness
$ docker compose exec -T client-envoy curl -s localhost:8001/clusters | grep health_flags

backend::172.28.0.4:8080::health_flags::/failed_active_hc
backend::172.28.0.2:8080::health_flags::/failed_active_hc
backend::172.28.0.5:8080::health_flags::/failed_active_hc
backend::172.28.0.6:8080::health_flags::/failed_active_hc
backend::172.28.0.7:8080::health_flags::healthy
backend::172.28.0.8:8080::health_flags::healthy
backend::172.28.0.3:8080::health_flags::healthy

我们可以确认有 4 个后端端点变得不健康。

现在我们再次发送 100 个请求。

# watch traffic change
$ docker compose exec -T client-envoy python3 client.py https://127.0.0.1:3000/ 100

Hello from backend-remote-1!: actual weight 37.0%
Hello from backend-local-2!: actual weight 36.0%
Hello from backend-local-1!: actual weight 27.0%
Failed: 0

由于 local-1 没有足够的健康工作负载,因此请求由次级区域部分共享。

如果我们关闭优先级 1 区域中的所有服务器,它将使优先级 1 区域的健康状况降至 0%。流量应在优先级 0 区域和优先级 2 区域之间分配。

$ docker compose exec -T client-envoy curl -s locality-load-balancing_backend-local-2_1:8080/unhealthy
$ docker compose exec -T client-envoy curl -s locality-load-balancing_backend-remote-1_1:8080/unhealthy
$ docker compose exec -T client-envoy python3 client.py https://127.0.0.1:3000/ 100

Hello from backend-remote-2!: actual weight 77.0%
Hello from backend-local-1!: actual weight 23.0%
Failed: 0