我有一个区域实例组在端口 8000 上有 2 个实例,没有启用自动缩放。
此实例组是全球外部应用程序负载均衡器。
实例上的 Web 服务器正在运行 flask,每个请求需要 1 秒钟来处理:
@app.route("/", methods=["GET"])
def main() -> Response:
sleep(1)
response = jsonify(
success=True,
hostname=gethostname(),
)
response.status_code = 200
response.headers["Access-Control-Allow-Origin"] = "*"
return response
我可以通过访问全局负载均衡器公共 IP 来确认行为,即需要 1 秒钟才能得到响应。
如果我同时运行 2 个请求,因为有 2 个实例,我期望每个请求将转到不同的实例,而不是它们总是转到同一个实例并且在该实例上排队,因此:
- 一个请求需要 1 秒
- 另一个请求将花费 2 秒
我曾尝试将 改为Locality load balancing policy
和Round-Robin
,Least-Request
但Random
总是得到相同的结果。
我理解的是否正确?这只Locality load balancing policy
与选择哪个后端有关?如果是,您如何在后端(即实例组)内配置负载平衡策略?
谢谢
配置
实例组
- 区域
- 目标分布形状:均匀
- [x] 允许实例重新分配
- 自动缩放:最少 2 个,最多 2 个
- 自动缩放信号:HTTP 负载平衡 100%
- 初始化时间:60秒
- 健康检查:
- 路径:/health
- 协议:HTTP
- 端口:8000
- 间隔:30 秒
- 超时:30 秒
- 健康阈值:1
- 不健康阈值:10
负载均衡器
- 前端:
- 协议:HTTP
- IP:xxx
- 网络等级:高级
- HTTP 保持连接超时:610 秒
- 路由规则:全部不匹配
- 后端服务:
- 端点协议:HTTP
- 命名端口:web
- 超时:300 秒
- 云 CDN:已禁用
- 记录:已启用(采样率:1)
- 会话亲和性:无
- 连接耗尽超时:300 秒
- 交通政策:
- 本地负载平衡策略:循环
- 异常值检测:已禁用
- 后端安全策略:无
- 边缘安全策略:无
- 身份识别代理:已禁用
- 平衡模式:最大 RPS:1(每个实例)
- 容量:100%
测试
siege \
--concurrent 1 \
--time 60s \
"http://x.x.x.x"
有 2 个节点:
concurrent=1
:平均 1.02 秒concurrent=2
:平均 1.66 秒concurrent=4
:平均 3.35 秒concurrent=8
:平均 5.54 秒
有 4 个节点:
concurrent=1
:平均 1.02 秒concurrent=2
:平均 1.18 秒concurrent=4
:平均 2.70 秒concurrent=8
:平均 3.83 秒concurrent=16
:平均 7.26 秒
有 8 个节点:
concurrent=2
:平均 1.20 秒concurrent=4
:平均 1.85 秒concurrent=16
:平均 4.40 秒concurrent=64
:平均 14.06 秒concurrent=128
:平均 19.04 秒
预期行为
我本来预期的结果如下:
- 2个节点:
concurrent=1
: 1秒concurrent=2
: 1秒concurrent=4
:约 2 秒concurrent=8
:约 4 秒
- 4个节点:
concurrent=1
: 1秒concurrent=2
: 1秒concurrent=4
: 1秒concurrent=8
:约 2 秒concurrent=16
:约 4 秒
更新 1
如果我切换到 aClassic proxy network load balancer
并发送 100 个请求:
- 56 转到 vm0
- 44 转到vm1
对于 HTTP LB,则:
- 99 转到 vm0
- 1 转到 vm1
答案1
基于全球外部应用程序负载均衡器GFE(Google Front End)估计哪些后端实例有能力接收请求。您可以扫描分享的链接以了解有关流量分布的更多信息。
如果你认为循环法不适合你,我建议使用平衡模式其中的概念或配置是均匀分配流量。
我也发现了这个关联来自 stackoverflow 的一个问题可能对使用平衡模式有帮助。