弹性扩缩容 - 多策略负载均衡最佳实践
- 需要根据业务负载动态调整任务节点数量,在资源成本与系统处理能力之间实现平衡。
- 需要支持自定义扩缩容策略,根据业务指标、资源状态或运行规则进行精细化控制。
- 需要更灵活的流量调度与负载均衡机制,满足复杂业务场景下的请求分发需求。
1.环境准备
Section titled “1.环境准备”需要准备一个带宽充足的云服务器,初期可选择按量计费,安装好 docker 环境。
如果只是本地测试使用,则不需要云服务器,只需要在本地安装好 docker 环境即可。
2.配置文件填写
Section titled “2.配置文件填写”完整的配置文件如下:
{ "openapi_base_url": "https://openapi.suanli.cn", // 共绩域名,固定 "token":"", //用户密钥,用于调用共绩云 API 增减节点 "lb_policy":"LEAST_REQUEST", //负载均衡策略,支持 ROUND_ROBIN、LEAST_REQUEST、RANDOM、RING_HASH、MAGLEV "max_connections": 1000, //单节点最大连接数 "max_requests":1000, //单节点最大请求数 "max_pending_requests": 100, // 单节点最大排队请求数(由于默认使用 http2 协议,该指标可能不生效) "max_nodes": 20, //最大节点数,注意平台有最大节点用量限制,该值不应超过平台限制 "min_nodes": 2, //最小节点数,启动时检测节点数,小于该值时会自动扩容至该值,大于该值则会进入缩容逻辑 "p95_latency_threshold": 500, //单位 ms,p95 延时阈值 "p95_delay_duration":30, //单位 s,p95 超过阈值持续时间,超过该时间开始扩容 "shrinkage_delay_time": 600,//单位 s,缩容延迟时间,当满足缩容条件,多久后开始缩容 "shrinkage_number":1, //满足缩容条件时,单次最大缩容数量。 "drain_timeout": 60, //单位 s,缩容时等待已有链接完成最大等待时间,超过该时间即使还有连接也会强制下线。 "acq_frequency":10, //采集数据频率,默认 10s 采集一次计算相关指标 "dashboard": { //面板配置,数据保存在/var/log/supervisor/node_history.json "default_days": 7, //面板默认显示最近几天的数据 "retain_days": 30 //磁盘数据保留天数,超过的数据会在下一次启动时删除 }, "expansion_strategies": [ // 扩容策略配置,未添加到本配置的策略不会启用 "trend_expansion", "delay_prediction", "p95_expansion" ], "trend_expansion":{ //趋势扩容配置 "expand_cooling_time": 180, //触发扩容后的冷却时间,至少大于 60s,因为节点冷启动需要 60s }, "delay_prediction":{ //延时预测扩容配置 "min_sample_size": 100, //最小样本数,当最近一分钟的总请求数量小于该值,则忽略 "expand_cooling_time": 180, //触发扩容后的冷却时间,至少大于 60s,因为节点冷启动需要 60s "delay_time": 2, //单位 s,触发扩容条件的延时指标,当预测当前请求最晚需要 2s 及以上完成时触发 "expansion_ratio": 0.2, //扩容比例,用于计算需要扩容的数量:当前节点数*expansion_ratio "min_expansion": 2, //最小扩容数量,实际扩容数量取 min_expansion 与 expansion_ratio 计算结果 的最大值 }, "p95_expansion":{ //p95 策略扩容 "min_sample_size": 100, //最小样本数,当最近一分钟的总请求数量小于该值,则忽略 "expand_cooling_time": 180, //触发扩容后的冷却时间,至少大于 60s,因为节点冷启动需要 60s "threshold":500 ,//单位 ms,触发阈值,当近一分钟超过 5% 的请求数量延时超过该值时,触发阈值, "threshold_duration": 30, //阈值持续时间,当触发阈值的持续时间超过该值时,触发扩容 "expansion_ratio": 0.2, //扩容比例,用于计算需要扩容的数量:当前节点数*expansion_ratio "min_expansion": 2, //最小扩容数量,实际扩容数量取 min_expansion 与 expansion_ratio 计算结果 的最大值 }, "scale_up_request": { //通过发新任务进行扩容 "task_name": "test", //任务名,扩容时自动追加后缀,所有包含该名的任务都将作为扩容任务点 "points": 1, //单次任务新增节点数,将忽略该值,默认单任务启动单节点、以适配调度。 "resources": [ { "mark": "REPLACE_WITH_RESOURCE_MARK_FROM_CLOUD" //实例信息(比如北京区 4090 等)标识,可通过 api 查询集群资源详情。 } ], "services": [ //容器列表 { "service_name": "svc1", //容器名,不支持下划线(_) "service_image": "REPLACE_WITH_IMAGE", //镜像 "remote_ports": [ //该镜像需要暴露服务的端口 { "service_port": 8080 } ], "start_script_v2": { "args": [], //参数 "command": null //镜像的启动命令,若镜像本身存在启动命令可不填 }, "env": [ { "name": "gongji_share", "value": "True" } ] } ] }}其中需要重点关注的值:
- token:在平台控制台获取
- lb_policy:调度策略
- max_nodes:设置最大扩容节点数
- min_nodes:设置最小扩容节点数
- scale_up_request:扩容任务时发生的请求体
- mark:资源标识,例如【河北四区 4090】,可通过接口或控制台获取
如需要调整扩缩容策略,可参考其它现有的参数值进行修改即可。
3.部署服务
Section titled “3.部署服务”docker run -d -v [本地配置文件]:/app/configs/config.json -v [本地保存日志目录]:/var/log/supervisor -p 8080:8080 harbor.suanleme.cn/vm/gongji-slb:v0.9注意将命令中的中文替换为正确的文件路径、目录路径。
部署成功后,所有打入该服务的流量将根据策略,自动将流量均衡转发到共绩云的任务内。
服务架构如下:
本服务不做排队,所有进入的用户流量都会按调度策略转发给后端任务处理,因此需要保证后端任务支持同时处理多个用户请求的能力。
该服务的所有请求转发行为均可参考开源项目 Envoy,本项目只是对 Envoy 的一层封装:根据指标判断扩容与缩容。
2.扩缩容规则
Section titled “2.扩缩容规则”趋势扩容:
-
采集最近 60s 连接数增长速率,当 链接数 + 速率*60s 大于 单节点最大请求数,则提前扩容。
- 每 10 秒采集一次
- 例如单节点最大支持 1000 请求,目前活跃请求 600,一分钟内增长到 820,则平均 每秒 4 个请求,一分钟后将超过 1000 个,因此需要在 820 时就要开始扩容。
-
需要节点数:总请求数/安全容量
- 安全容量:单节点最大请求数 - 增速*60s
- 例如:当前达到 1000 请求,过去一分钟增速为 5 个/s,安全容量为:1000-5*60=700。则需要的节点数为:1000/700=1.42,向上取整,需要扩容到两个节点。
- 扩容冷却:触发扩容后,将进入一段时间的观察期(时间可配置)
延时预测扩容:
-
统计当前 新增 + 处理 + 排队中的请求数,除以 过去一分钟完成的请求数,得到剩余请求完成的最大完成时间。
- 每 10 秒统计一次最近一分钟完成请求数 与 新增 + 处理 + 排队中的请求数
- 需配置最小样本数,防止少数几个请求因为网络抖动超过阈值而扩容
-
当延时时间超过 2s(可配置)时,触发扩容
-
单次扩容节点数:Max(当前节点数 * 20%, 2),(比例与数量可配置)
-
扩容冷却:触发扩容后,将进入一段时间的观察期(时间可配置)
- 防止“扩容震荡”(扩容节点还未加入、而继续触发扩容)
p95 扩容:
-
当最近一分钟有 5% 的请求延迟大于 500ms(持续 30s)时开始扩容,该值可配置。
- 每 10 秒统计一次最近一分钟的 p95 数值。
- 需配置最小样本量,防止 qps 极低时,少数几个请求因为网络抖动超过阈值而扩容。
-
每次触发扩容、扩容节点数为:Max(当前节点数 * 20%, 2),(比例与数量可配置)
- P95 触发的扩容,通常意味着系统已经感受到压力,此时的扩容应该果断。
-
扩容冷却:触发扩容后,将进入一段时间的观察期(时间可配置)
- 防止“扩容震荡”
扩容策略均彼此独立,任意一个满足扩容条件,都会触发扩容。
缩容策略:
-
健康状态(趋势扩容、延时预测、p95 均正常)持续十分钟(时间可配置),则触发缩容。
- 按趋势扩容计算可缩容的数量,单次最大缩容一个节点(可配置)。
-
配置 envoy 停止将新流量打入将要下线的节点、并等待旧连接完成。
-
待节点 active_rq 请求链接数归零/或超时后,调用共绩云 api 移除节点。
极端情况:
- 瞬时连接数超过当前所有节点的最大连接数之和,允许在 envoy 排队一定数量的请求(比如 100,可配置),继续超过阈值则丢弃新到来的请求。