news 2026/9/20 13:42:36

Floci EC2 Auto Scaling 服务实现解析:从 API 兼容到真实容量协调器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Floci EC2 Auto Scaling 服务实现解析:从 API 兼容到真实容量协调器

【免费下载链接】floci

Light, fluffy, and always free - The AWS Local Emulator alternative

项目地址:https://gitcode.com/gh_mirrors/fl/floci
点击查看免费下载

Floci 以内存态存储实现 EC2 Auto Scaling(autoscaling)Query API 的 45 个操作,覆盖启动配置、自动扩缩组、生命周期钩子、扩缩策略、计划任务与 Warm Pool 的完整状态管理,并配备一个每 10 秒运行一次的容量协调器(Reconciler),通过调用 EC2RunInstances/TerminateInstances真正拉起或销毁实例来维持 DesiredCapacity。本文结合 docs/services/autoscaling.md 与 AutoScalingService.java 等源码,逐层拆解其协议形态、操作清单、协调器原理与边界行为,帮助你在本地开发与测试中正确使用 Floci 的 Auto Scaling 能力。

协议与 ARN 形态

Floci 的 Auto Scaling 服务使用 AWS 经典Query 协议:客户端以POST /发起请求,Action表单参数指定具体操作,凭证作用域(credential scope)为autoscaling,服务端以 XML 响应返回结果。从源码看,请求分发由 AutoScalingQueryHandler.java 中的switch (action)完成,支持 45 个动作,未知动作返回UnsupportedOperation错误。

三类核心资源使用以下 ARN 格式:

  • 自动扩缩组:arn:aws:autoscaling:<region>:<account>:autoScalingGroup:<uuid>:autoScalingGroupName/<name>
  • 启动配置:arn:aws:autoscaling:<region>:<account>:launchConfiguration:<uuid>:launchConfigurationName/<name>
  • 扩缩策略:arn:aws:autoscaling:<region>:<account>:scalingPolicy:<uuid>:autoScalingGroupName/<group>/policyName/<name>

源码中 ARN 通过AwsArnUtils.Arn.of("autoscaling", region, accountId, ...)生成(见 AutoScalingService.java),<uuid>部分实际由资源类型与名称构成,区域与账号 ID 取自请求上下文。

存储模型:以区域为命名空间的内存态存储

Floci 的 Auto Scaling 状态全部保存在AutoScalingService持有的内存 Map 中,键统一为region::name(组、启动配置)或region::group::name(钩子、策略、计划任务)等组合。服务启动时通过StorageBackedMap将以下 8 类数据持久化到 JSON 文件(见 AutoScalingService.java):

存储文件内容
autoscaling-launch-configurations.json启动配置
autoscaling-groups.json自动扩缩组(含实例列表)
autoscaling-lifecycle-hooks.json生命周期钩子
autoscaling-policies.json扩缩策略
autoscaling-activities.json扩缩活动日志
autoscaling-instance-refreshes.json实例刷新记录
autoscaling-scheduled-actions.json计划任务
autoscaling-warm-pools.jsonWarm Pool 配置

由于键包含区域,同一名称在不同区域下互不干扰;describe类操作也会按区域过滤。这保证了对多区域、多账号模拟的一致行为。

操作全景:45 个 API 的兼容矩阵

启动配置(Launch Configurations)

操作说明
CreateLaunchConfiguration存储模板:ImageIdInstanceTypeKeyNameSecurityGroupsUserDataIamInstanceProfileInstanceMonitoringBlockDeviceMappings
DescribeLaunchConfigurations按名称列表过滤;无过滤时返回全部
DeleteLaunchConfiguration删除指定启动配置,不存在时抛ValidationError

源码中的校验逻辑与 AWS 保持一致:请求要么携带InstanceId,要么同时携带ImageIdInstanceType,否则抛ValidationError(错误消息见 AutoScalingService.java)。若传入InstanceId,Floci 会查询对应 EC2 实例并自动补全缺失的ImageIdInstanceTypeKeyNameSecurityGroupsUserDataIamInstanceProfile,模拟 AWS 的"从实例创建启动配置"行为。InstanceMonitoring默认视为启用(TRUE),而AssociatePublicIpAddress的缺席是有意义的(显式false优先于子网默认值),两者语义不同。

自动扩缩组(Auto Scaling Groups)

操作说明
CreateAutoScalingGroup创建组,支持 min/max/desired 容量、AZ、标签、启动配置/启动模板/混合实例策略;随即启动容量协调循环
DescribeAutoScalingGroups按名称过滤;返回实例列表(含生命周期状态)与混合实例策略形状
UpdateAutoScalingGroup更新容量边界、冷却时间、启动源、AZ
DeleteAutoScalingGroupForceDelete=true时先终止全部实例再删除

创建时默认值处理:DefaultCooldown缺省为300HealthCheckType缺省为EC2TerminationPolicies缺省为["Default"](见 AutoScalingService.java)。删除组时若仍有存活实例且未设ForceDelete,会抛ResourceInUseForceDelete=true则逐一调用 EC2 终止接口,随后清理关联的钩子、策略、实例刷新、计划任务与 Warm Pool。

实例管理

操作说明
DescribeAutoScalingInstances返回所有被 ASG 跟踪的实例及其生命周期与健康状态
SetDesiredCapacity更新期望数量;协调器在 10 秒内完成扩缩容
AttachInstances将已有 EC2 实例挂入组内,生命周期置为InService
DetachInstances从组内摘除实例,可选是否递减 DesiredCapacity
TerminateInstanceInAutoScalingGroup终止指定实例,可选递减 DesiredCapacity
SuspendProcesses记录被挂起的扩缩进程(空列表表示挂起全部),DescribeAutoScalingGroups回显
ResumeProcesses清除挂起记录(空列表表示恢复全部)

SetDesiredCapacity会校验新值必须落在[MinSize, MaxSize]区间内(见 AutoScalingService.java)。SuspendProcesses的"空列表挂起全部"语义对应 AWS 的 9 个标准进程:LaunchTerminateAddToLoadBalancerAlarmNotificationAZRebalanceHealthCheckInstanceRefreshReplaceUnhealthyScheduledActions。源码注释明确指出:Terraform AWS Provider 在wait_for_capacity_timeout非零(默认值)时总会无条件调用SuspendProcesses,因此该操作若未实现会导致 ASG 创建整体失败——Floci 采用"接受并记录"策略保证兼容。

此外,Floci 还实现了SetInstanceProtectionSetInstanceHealth:前者标记实例protectedFromScaleIn(缩容候选会被过滤),后者校验健康状态只能是HealthyUnhealthy。需注意源码注释提示:ShouldRespectGracePeriod参数仅做 wire 兼容解析,尚未真正对照HealthCheckGracePeriod生效。

负载均衡挂载

操作说明
AttachLoadBalancerTargetGroups挂载 ELB v2 目标组 ARN;新实例 InService 时自动注册
DetachLoadBalancerTargetGroups摘除目标组;实例随之反注册
DescribeLoadBalancerTargetGroups列出组关联的目标组
AttachLoadBalancers经典 ELB 挂载(仅存储,不做 ELB v1 路由)
DetachLoadBalancers经典 ELB 摘除
DescribeLoadBalancers列出组关联的经典 ELB

目标组挂载会持久化到组的TargetGroupARNs列表;协调器在实例进入InService时调用ElbV2Service.registerTargets完成真实注册(见 AutoScalingReconciler.java),同时也会向经典 ELBregisterInstances注册(LoadBalancerNames与目标组是相互独立的两条链路,可同时存在)。

流量源(Traffic Sources)

操作说明
AttachTrafficSources统一的 elb/elbv2/vpc-lattice 挂载 API,按 identifier 与 type 存储
DetachTrafficSources按 identifier 移除流量源
DescribeTrafficSources列出已挂载源,可按 type 过滤;每个源都报告InService

源码将其实现为Map<identifier, type>,type 缺省为elbv2。Terraform 的aws_autoscaling_traffic_source_attachment使用该 API 而非旧的AttachLoadBalancerTargetGroups。由于 Floci 没有真实的健康检查循环,所有挂载的流量源立即上报InService——注释明确说明这是"接受并记住"模式。

生命周期钩子

操作说明
PutLifecycleHook创建/更新钩子:LifecycleTransitionDefaultResultHeartbeatTimeout
DescribeLifecycleHooks列出组的钩子
DeleteLifecycleHook移除钩子
CompleteLifecycleAction对挂起的生命周期动作发出CONTINUEABANDON
RecordLifecycleActionHeartbeat延长进行中动作的心跳超时

钩子名校验严格遵循 AWS 模型(autoscaling/2011-01-01/service-2.json):长度 ≤ 255,且必须匹配^[A-Za-z0-9\-_/]+$LifecycleActionToken必须恰好 36 字符(见 AutoScalingService.java)。CompleteLifecycleAction当前为存储型实现,协调器通过实例生命周期状态间接观察结果。

扩缩策略与计划任务

操作说明
PutScalingPolicy创建/更新策略:SimpleScaling字段或带预定义指标、目标值、预热时间的TargetTrackingScaling
DescribePolicies按组或策略名过滤,回显存储的目标跟踪配置
DeletePolicy删除扩缩策略
PutScheduledUpdateGroupAction创建/更新计划:recurrence、时区、起止时间、容量边界
DescribeScheduledActions按组或动作名过滤
DeleteScheduledAction移除计划动作

策略 ARN 形如arn:aws:autoscaling:<region>:<account>:scalingPolicy:<group>:<policyName>。计划任务与策略一样采用"接受并记住"模式——Floci 没有真正的 cron 调度器去执行这些计划,但 Terraform Provider 的 Read 操作本就不期望模拟器内计划真的触发,因此足以支撑aws_autoscaling_schedule的完整生命周期(见 AutoScalingService.java 注释)。

Warm Pool 与活动日志

操作说明
PutWarmPool按 wire 模型整体替换:省略字段重置为默认;MaxGroupPreparedCapacity=-1清除该值
DescribeWarmPool返回存储配置;同时嵌入DescribeAutoScalingGroups的 AutoScalingGroup 形状
DeleteWarmPool移除配置;不存在时幂等成功
DescribeScalingActivities返回组的活动日志;扩缩容事件均有记录

Warm Pool 的实现与 AWS 行为对齐:MinSize省略时默认0PoolState省略时默认Stopped(省略字段重置为默认,而不是沿用旧值,因此putWarmPool总是从零重建配置);MaxGroupPreparedCapacity没有默认值,-1是 wire 模型文档化的"清除已设值"哨兵,映射回null而非渲染为-1。由于没有真正预热实例的循环,DescribeWarmPoolInstances列表恒为空(注释见 AutoScalingService.java)。

元数据类操作

以下操作返回标准枚举,用于支持 SDK/工具对能力边界的探测:

  • DescribeTerminationPolicyTypes:标准终止策略名
  • DescribeAccountLimits:组的最大数量/配置/实例限额
  • DescribeLifecycleHookTypesautoscaling:EC2_INSTANCE_LAUNCHINGautoscaling:EC2_INSTANCE_TERMINATING
  • DescribeAdjustmentTypes:四种标准调整类型
  • DescribeMetricCollectionTypes:标准指标与粒度名
  • DescribeAutoScalingNotificationTypes:全部通知类型名

Capacity Reconciler:真实的扩缩容引擎

Floci 的 Auto Scaling 不是纯"记状态"模拟。AutoScalingReconciler在应用启动后以scheduleAtFixedRate(this::reconcileAll, 5, 10, TimeUnit.SECONDS)的方式每10 秒固定频率运行一轮(见 AutoScalingReconciler.java),单线程调度线程名为asg-reconciler

每轮reconcile(asg)的执行顺序(AutoScalingReconciler.java):

  1. 移除终止中实例:将Terminating状态实例从目标组/经典 ELB 反注册,调用TerminateInstances,再移除记录。
  2. 清除陈旧实例InService但底层 EC2 已不运行的实例、Pending但 EC2 已缺失或处于终止/停止状态的实例会被清理,同时将相关活跃 SSM 命令调用标记为Undeliverable
  3. 清理孤儿目标注册:目标组中不属于任何活跃 ASG 实例的 target 会被反注册。
  4. 晋升就绪实例Pending状态的实例一旦 EC2 状态变为running,即晋升为InService并注册到所有已挂载目标组与经典 ELB。
  5. 容量对齐:统计Pending+InService的活跃容量,与DesiredCapacity比较后执行扩缩。

扩缩逻辑(AutoScalingReconciler.java):

  • Scale-out:解析启动源(启动配置 → 启动模板 → 混合实例策略,优先级依次降级),调用RunInstances按需数量拉起实例,新实例以Pending状态入库;若组已删除导致保存失败,会回滚终止这些实例。AZ 选择:组配置了 AZ 则取第一个,否则用<region>a;子网同理取第一个。组标签中标记为"启动时传播"的标签会随实例下发。
  • Scale-in:从InService且未被protectedFromScaleIn保护的实例中选取,先反注册目标组与经典 ELB,再调用TerminateInstances并移除记录。
  • 每次扩缩容事件都会写入一条活动记录(recordActivity),供DescribeScalingActivities查询。

协调器对启动源做了精细处理(resolveLaunchSource):启动模板解析时会读取指定版本的ImageIdInstanceTypeKeyName、安全组、实例标签、UserData 与 IAM 实例配置档;混合实例策略则取 override 中第一个显式InstanceType。启动模板被删除时,仅InvalidLaunchTemplateName.NotFoundException/InvalidLaunchTemplateId.NotFound被当作"模板已消失"而跳过该轮,其他异常会向上传播以免掩盖真实故障。

Launch Source 兼容性与混合实例策略

自动扩缩组只能保留三种启动源之一:启动配置、顶层启动模板、或MixedInstancesPolicy,在创建/更新请求中互斥。同时提供多个启动源会抛ValidationError("mutually exclusive")。混合实例策略存储并回显以下字段:

  • LaunchTemplate.LaunchTemplateSpecification.LaunchTemplateId
  • LaunchTemplate.LaunchTemplateSpecification.LaunchTemplateName
  • LaunchTemplate.LaunchTemplateSpecification.Version
  • LaunchTemplate.Overrides.member.N.InstanceType
  • LaunchTemplate.Overrides.member.N.InstanceRequirements
  • InstancesDistribution.OnDemandBaseCapacity
  • InstancesDistribution.OnDemandPercentageAboveBaseCapacity
  • InstancesDistribution.SpotAllocationStrategy

override 选择实例类型的方式二选一:按名称(InstanceType)或按属性(InstanceRequirements)。规则(见 AutoScalingService.java):

  • 同一 override 同时设置InstanceTypeInstanceRequirementsValidationError,与 AWS 一致;
  • 指定InstanceRequirements必须同时给出VCpuCountMemoryMiB(AWS 模型在该 shape 上标记的必填成员),否则抛ValidationError
  • InstanceRequirements的所有成员均可往返(round-trip),唯一例外是BaselinePerformanceFactors——接受但丢弃。

属性型实例类型选择(attribute-based selection)的判定规则:当生效的混合实例策略中至少一个 override 携带InstanceRequirements时,该组使用属性型选择。创建时生效策略即请求提供的策略;更新时则是请求提供的策略、未指定启动源时存储的策略、或请求切换到启动配置/普通启动模板时的"无"。

可选组字段:何时回显、何时省略

CreateAutoScalingGroupUpdateAutoScalingGroup都接受以下字段,而DescribeAutoScalingGroups仅在组设置了该字段时才回显——从未设置的字段从响应中省略,而非返回默认值(实现载体是 AsgOptionalFields.java):

字段说明
DesiredCapacityType取值unitsvcpumemory-mib,其他值抛ValidationError。AWS 仅支持其用于属性型实例类型选择,因此vcpu/memory-mib在生效的混合实例策略未使用InstanceRequirements时抛ValidationErrorunits是文档化默认值,始终接受
CapacityRebalance布尔值,存储并原样回显
MaxInstanceLifetime秒。必须为0或至少864000表示无上限,回显为0
DefaultInstanceWarmup秒。传-1移除已设值,之后字段再次省略

更新语义是部分更新:请求未设置的成员不动存量值(applyToExistingGroup仅覆盖显式传入成员),而创建时未设置则直接不设置。DefaultInstanceWarmup-1哨兵会被解析为null后省略,而不是存储-1

扩缩策略兼容性

目标跟踪策略保留TargetTrackingConfigurationDescribePolicies在配置存在时返回PredefinedMetricSpecification.PredefinedMetricTypeTargetValueEstimatedInstanceWarmupPutScalingPolicyPolicyType缺省为SimpleScaling,同时记录AdjustmentTypeScalingAdjustmentCooldown,供下游工具完整读回。

配置开关

变量默认值说明
FLOCI_SERVICES_AUTOSCALING_ENABLEDtrue启用或禁用 Auto Scaling 服务

该配置对应EmulatorConfig.AutoScalingServiceConfig.enabled()(@WithDefault("true")),与其他服务模块(如 Application Auto Scaling)的开关模式一致。环境变量名由 Quarkus 的配置映射规则推导(floci.services.autoscaling.enabled属性对应的环境变量形式)。将其设为false可整体关闭该服务的 API 入口。

使用示例

以下是基于文档的完整演练,覆盖"创建启动配置 → 创建组 → 挂载目标组 → 观察实例 → 扩容"的全流程:

# 创建启动配置 aws autoscaling create-launch-configuration \ --launch-configuration-name my-lc \ --image-id ami-12345678 \ --instance-type t3.micro # 创建目标 desired=2 的组 aws autoscaling create-auto-scaling-group \ --auto-scaling-group-name my-asg \ --launch-configuration-name my-lc \ --min-size 1 \ --max-size 5 \ --desired-capacity 2 \ --availability-zones us-east-1a # 挂载 ELB v2 目标组 aws autoscaling attach-load-balancer-target-groups \ --auto-scaling-group-name my-asg \ --target-group-arns arn:aws:elasticloadbalancing:us-east-1:000000000000:targetgroup/my-tg/abc123 # 观察实例出现(Pending → InService,约 10 秒内完成) aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names my-asg # 扩容 aws autoscaling set-desired-capacity \ --auto-scaling-group-name my-asg \ --desired-capacity 3

创建组后约 5~10 秒内协调器开始工作:RunInstances拉起 2 个实例进入Pending,EC2 进入running后晋升InService并自动注册到目标组。扩容到 3 后,下一轮协调器会补 1 个实例;反向调低 desired 则触发缩容。若需调试,可配合aws autoscaling describe-scaling-activities --auto-scaling-group-name my-asg查看每次扩缩容的活动记录。

边界与限制

从源码注释可以确认以下已知边界(均为有意的"接受并记住"设计,而非缺陷):

  • CompleteLifecycleAction不实际执行 SNS 通知,仅做存储级校验(CONTINUE/ABANDON由协调器通过实例状态间接体现);
  • 计划任务与扩缩策略只有存储语义,不会真正按 cron 或指标触发扩容——真实扩容仅由SetDesiredCapacity/ 容量边界变化驱动协调器完成;
  • Warm Pool 不预热实例,DescribeWarmPool.Instances恒为空;
  • 经典 ELB 挂载只做存储与实例注册,不做真实流量路由;
  • ShouldRespectGracePeriod尚未与HealthCheckGracePeriod联动;
  • BaselinePerformanceFactors接受后不保留。

这些边界覆盖了 AWS SDK、Terraform Provider 等主流工具在本地开发场景下的全部读回路径,使得基于 Floci 的 CI 流程可以无侵入地演练 ASG 的创建、扩容、缩容与销毁。

进一步阅读

  • 服务实现主类:AutoScalingService.java
  • 容量协调器:AutoScalingReconciler.java
  • Query 协议分发:AutoScalingQueryHandler.java
  • 可选字段模型:AsgOptionalFields.java
  • 集成测试:AutoScalingIntegrationTest.java
  • 协调器单元测试:AutoScalingReconcilerTest.java
  • 官方服务文档:docs/services/autoscaling.md

【免费下载链接】floci

Light, fluffy, and always free - The AWS Local Emulator alternative

项目地址:https://gitcode.com/gh_mirrors/fl/floci
点击查看免费下载
上一篇:CANN/ops-math全局平均池化算子
下一篇:【亲测免费】 Kubeflow 开源项目安装与使用指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 13:40:29

ZeroOmega 3.4.0 安装与配置实战:Chrome/Edge/Firefox 代理切换全指南

简介&#xff1a;ZeroOmega是一款面向新版Chrome浏览器的代理管理插件&#xff0c;作为Proxy SwitchyOmega的继任者&#xff0c;解决了旧插件无法使用的问题。它适合开发、测试以及需要频繁切换网络代理的进阶用户&#xff0c;通过弹出面板快速管理多套代理配置&#xff0c;并可…

作者头像 李华
网站建设 2026/9/20 13:40:04

3DGS投影变换矩阵全解析:从三维高斯到屏幕椭圆的数学推导

第一次把3DGS整个渲染管线读通的时候&#xff0c;我踩了一个特别蠢的坑&#xff1a;我以为只需要把每个高斯中心当成普通点云&#xff0c;用一个MVP矩阵投到屏幕上&#xff0c;再叠上一个固定大小的圆斑当模糊效果就行。结果跑出来的图全是边缘发亮的空心圈和奇怪的条纹&#x…

作者头像 李华
网站建设 2026/9/20 13:39:28

电视盒子播放管理完整教程:3 步装好 TVBoxOSC 就能播

电视盒子播放管理完整教程&#xff1a;3 步装好 TVBoxOSC 就能播 【免费下载链接】TVBoxOSC TVBoxOSC - 一个基于第三方项目的代码库&#xff0c;用于电视盒子的控制和管理。 项目地址: https://gitcode.com/GitHub_Trending/tv/TVBoxOSC 追更前翻两分钟盒子应用列表&am…

作者头像 李华