Skip to content
共绩算力文档中心

弹性扩缩容-FIFO 队列最佳实践

  • 服务端处理能力受限,不支持并发处理多个请求,同一时间只能执行一个任务。
  • 需要保证请求严格按照到达顺序进行处理(FIFO),避免请求乱序执行导致的数据一致性或业务逻辑问题。
  • 需要根据业务负载动态调整任务节点数量,在资源成本与系统处理能力之间实现平衡

需要准备一个带宽充足的云服务器,安装好 docker 环境。

如果只是本地测试使用,则不需要云服务器,只需要在本地安装好 docker 环境即可。

完整的配置文件如下:

{
"openapi_base_url": "https://openapi.suanli.cn", //共绩域名,固定
"token": "", // 用户密钥,用于调用共绩云 API 增减节点
"min_nodes": 1, //节点池最少保留的节点数,即使空闲也不会缩容到该值以下。可设为 `0`:允许缩容到 0,启动时不预创建任务,有请求时再冷启动。
"max_nodes": 3, //节点池最多允许创建的节点数,扩容时不会超过该上限。
"max_scale_down_nodes": 1, //单次缩容最多同时关闭的节点数,避免一次性关闭过多节点。
"scale_down_cooldown_secs": 180, // 两次缩容之间的最小间隔,避免短时间内反复关闭节点。
"queue_scale_wait_secs": 120, //请求队列超过阈值后,需要持续等待的秒数才触发扩容。
"queue_scale_count_threshold": 10, //触发扩容的队列长度阈值。
"idle_shutdown_secs": 180, //节点连续空闲超过该秒数后,会被关闭以释放资源。
"scale_up_cooldown_secs": 30, //两次扩容之间的最小间隔,避免短时间内反复创建节点。
"node_refresh_interval_secs": 15, //刷新节点状态的时间间隔。
"scale_check_interval_secs": 5, //检查是否需要扩缩容的时间间隔。
"stats_log_interval_secs": 15, //输出统计日志的时间间隔。
"proxy_port": 3000, //实际需要代理转发请求的容器端口,例如 3000。
"health_check_path": "/ready", //健康检查(就绪)接口路径,用于判断节点是否可用。
"scale_up_request": { //调用上游 API 创建新节点时的请求模板
"task_name": "gjtest-comfyui", //创建任务使用的任务名称前缀,不支持下划线(_),注意同账号下以该任务名称开头的任务,均将视为同一组任务节点池,会受本程序管控。
"points": 1, //创建的任务内有多少个节点,固定 1 个、便于本程序调度。
"resources": [
{
"mark": "" // `mark` 标识一组资源配额,可以通过分析控制台 search 接口返回值查找其它区的 mark 值。
}
],
"services": [ // 节点中运行的服务列表(容器配置信息)。
{
"service_name": "container-01", //服务名称。
"service_image": "", //服务使用的容器镜像。
"remote_ports": [ //服务对外暴露的端口列表。
{
"service_port": 3000
},
{
"service_port": 8188
}
],
"start_script_v2": { //服务启动参数与命令。
"args": [],
"command": null
},
"storage_config": [ //服务挂载的存储配置。可为空
{
"storage_id": 2451,
"target_dir": "/opt/ComfyUI/models"
}
]
}
]
}
}

大多数配置默认值即可满足需求,需要重点关注的配置为:

  • token:用户 token,可在平台控制台获取
  • min_nodes:最小节点数
  • max_nodes:最大节点数
  • proxy_port:该服务需要被转发的端口
  • health_check_path:该服务提供的健康监测路径,只有该路径返回状态码 200 时,才认为该任务可用、才会被转发请求
  • scale_up_request:创建任务的配置
    • mark:创建任务使用的资源配额标识。
docker run -d -v [配置文件]:/app/config.json -p 8080:8080 harbor.suanleme.cn/vm/gj_proxy:v0.6

注意将命令中的中文替换为正确的文件路径。

部署成功后,所有打入该服务的流量将进入排队,只有当后端任务处于空闲时、才会将请求转发给该任务进行处理,保证后端每个任务最多同时只会接收到一个请求。

本服务会对请求进行排队,所有进入的用户流量都会先进入队列,等待后端任务空闲,保证每个后端任务同一时间只处理一个用户请求。

  1. 触发条件:当请求队列非空,且满足以下任一条件时触发扩容:

    • 冷启动:当前无节点且无创建中任务(min_nodes=0 缩容到 0 后,或启动时未预创建);
    • 等待触发:队列中最久的请求等待时间达到 queue_scale_wait_secs 秒;
    • 数量触发:队列长度超过 queue_scale_count_threshold
  2. 冷却限制:如果距上次扩容时间不足 scale_up_cooldown_secs 秒,跳过本次扩容,避免短时间内反复创建节点。冷启动不受此冷却限制。

  3. 上限保护:扩容后的总节点数(当前就绪节点 + 正在创建中的节点 + 本次新增节点)不能超过 max_nodes。如果当前节点数加上正在创建的节点数已达 max_nodes,则本次扩容不会执行。

  4. 扩容数量:本次扩容数量取 max(队列长度 / 2, 1),并同时受 max_nodes 剩余可用槽位限制;如果计算值大于可用槽位,则按可用槽位扩容。

  1. 触发条件:当节点池中存在满足以下条件的节点时,会被列为缩容候选:

    • 请求队列为空(有排队请求时不缩容);
    • 节点当前处于空闲状态(没有正在处理的请求);
    • 该节点最近一次处理完请求后,空闲时间已超过 idle_shutdown_secs 秒。
  2. 冷却限制:如果距上次缩容时间不足 scale_down_cooldown_secs 秒,跳过本次缩容,避免频繁关闭节点。

  3. 下限保护:就绪节点数必须至少保留 min_nodes 个,即使这些节点空闲也不会被缩容。程序只会缩容“超出 min_nodes 数量的就绪节点”。min_nodes=0 时允许缩容到 0。未就绪的空闲节点在达到下限时仍可被清理。

  4. 单次上限:每次缩容最多关闭 max_scale_down_nodes 个节点,避免一次性关闭过多节点导致服务能力骤降。

  5. 优先顺序:优先缩容最早进入空闲状态的节点(按节点最近一次处理请求的时间 last_processed 从早到晚排序)。