AWS ECS上Application Auto Scaling实现

436 阅读7分钟

简介

这是上一篇”创建ECS Fargate“中申引部分“自动扩容降级”的展开。

多数应用不同时间的访问量并不相同。有些应用的访问量与特定时间有关,比如企业的考勤系统,早晚固定时间点访问量激增,其它时间则很空闲。

有些应用则无法预估访问高峰的时段,比如微博,经常会有突发热点事件挤爆服务器。

因此我们的服务需要有自动扩容的能力,以应对访问量高峰,以及及时降级的能力来节省成本。

AWS提供了Application Auto Scaling服务,用来扩展应用所需的AWS资源。下面列出了部分可以通过Application Auto Scaling来进行扩展的服务。

  • AppStream 2.0 fleets
  • Aurora replicas
  • DynamoDB tables and global secondary indexes
  • Amazon Elastic Container Service (ECS) services
  • Amazon EMR clusters

需要注意的是,EC2 Fleet扩展是通来Auto Scaling Groups来实现,并不属于Application Auto Scaling服务。

Amazon ECS Service Auto Scaling扩容专指增加ECS集群中运行中的task数量。

新增加的task会自动注册到target group中。访问ALB的请求转发到target group后,默认按轮询调度的方式选择可用的task转发请求。(也可以在target group中设成least outstanding requests模式)

ECS的扩容并不需要对其它服务做出改变,ALB会自动获得新的task信息,并在其可用时,向其转发请求。

理论上每增加一个task,处理能力会增加一倍,当然这里没考虑带宽,数据库,硬盘读写带来的消耗。

ECS目前支持下列三种扩容(增加Task运行数量)策略

  • Target Tracking Scaling Policies 基于CPU/Mem阈值
  • Step Scaling Policies 基于告警突破
  • Scheduled Scaling 基于定时任务

AWS推荐使用Target Tracking Scaling Policies的策略,所以本文只讨论Target Tracking Scaling Policies的策略。

Target Tracking Scaling Policies简单来说就是按阈值来增减task数量,目前有三种阈值可选,这些阈值可以单独使用也可以混合使用。

  • ECSServiceAverageCPUUtilization 基于CPU利用率
  • ECSServiceAverageMemoryUtilization 基于内存利用率
  • ALBRequestCountPerTarget 基于每个task完成请求数

本文以”创建ECS Fargate“文章中建好的ECS为基础,增加Application Auto Scaling,通过设置Task CPU利用率的阈值来控制运行Task的个数,从而实现自动扩容降级。

在配置完成后,利用ab工具模拟峰值访问量,实战检测ECS自动扩容。

目录

  • 环境(配置)
  • 实战步骤
    1. 注册auto scaling资源
    2. 增加auto scaling策略
      • 编写策略文件
    3. 测试自动扩容
      • 降低CPU阈值
      • 模拟高访问量
  • 引申
  • 资源下载
  • 后记

环境(配置)

  • AWS中国或Global帐号,可在官网申请,一年内使用指定资源免费
  • AWS cli, 本文在win10 + terminal下使用aws cli
  • linux + docker 或 win + docker
  • linux + ab

实战步骤

1. 注册auto scaling资源

首先我们要注册需要扩容的资源及扩容的维度,我们要扩容的资源是ECS service,扩容的维度是task的数量。

运行如下命令

aws application-autoscaling register-scalable-target \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/tstest/tstest-svc \
--min-capacity 1 \
--max-capacity 3 \
--region cn-north-1

提示:这个”\“放在每行的最后,和前面的字符有一个空格,是代表这行命令还没有结束。这是在Linux环境下的常用的技巧,主要是为了使长命令更容易懂。也可以像下一条命令那样写成一行,效果一样。

说明:

  • service-namespace 指定资源的类别
  • scalable-dimension 扩展的维度,这里是希望运行task个数
  • resource-id 注册的具体资源。
    • ”service“ ECS service
    • ”tstest“ 测试用的ECS cluster名称
    • ”tstest-svc“ 测试用的ECS cluster中service的名称
  • min-capacity 最小运行数量,降级不会少于此数量
  • max-capacity 最大运行数量,扩容不会超出此数量
  • region 测试用ECS运行的地区

此命令运行成功后并没有结果返回,查看注册的资源用如下命令。

aws application-autoscaling describe-scalable-targets --service-namespace ecs --resource-id service/tstest/tstest-svc --region cn-north-1

运行结果如下

图1

1.jpg

撤消注册命令

aws application-autoscaling deregister-scalable-target --service-namespace ecs --resource-id service/tstest/tstest-svc --scalable-dimension ecs:service:DesiredCount  --region cn-north-1

2. 增加auto scaling策略

编写策略文件

创建文件cpu70-target-tracking-scaling-policy-config.json,并加入以下内容。

{
     "TargetValue": 70.0,
     "PredefinedMetricSpecification": {
         "PredefinedMetricType": "ECSServiceAverageCPUUtilization"
     },
     "ScaleOutCooldown": 60,
    "ScaleInCooldown": 60
}

说明:

  • TargetValue CPU利用率阈值
  • PredefinedMetricType 阈值类型
  • ScaleOutCooldown 扩容冷静时间,单位秒
  • ScaleInCooldown 降级冷静时间,单位秒

冷静时间是指,当扩容阈值超过时,需要等待的距离上次的扩容时间,避免短时间内过度扩容。

然后运行以下命令

aws application-autoscaling put-scaling-policy \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/tstest/tstest-svc \
--policy-name cpu70-target-tracking-scaling-policy \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration file://cpu70-target-tracking-scaling-policy-config.json \
--region cn-north-1

返回结果

图2

2_add policy.jpg

在ECS cluter中击service可以在Auto Scaling下看到新的policy

图3

3_policy_web1.jpg

3. 测试自动扩容

降低CPU阈值

我们先降低CPU扩容的阈值,以便于观察到实际效果。把之前的文件cpu70-target-tracking-scaling-policy-config.json中"TargetValue”,改成30

{
     "TargetValue": 30.0,
     "PredefinedMetricSpecification": {
         "PredefinedMetricType": "ECSServiceAverageCPUUtilization"
     },
     "ScaleOutCooldown": 60,
    "ScaleInCooldown": 60
}

再次运行以下命令,修改policy

aws application-autoscaling put-scaling-policy \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/tstest/tstest-svc \
--policy-name cpu70-target-tracking-scaling-policy \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration file://cpu70-target-tracking-scaling-policy-config.json \
--region cn-north-1

返回结果

图4 4.jpg

界面上可以看到阈值降低

图5

5.jpg

模拟高访问量

首先我们先记下当前CPU利用率及Cloud Watch中相关告警

进入Cluster -> service -> Metrics 可以看到现在只有1个task在运行,CPU利用率不到1%

图7

7.jpg

进入Cloud Watch -> Alarm 这里有一个CPU利用率 < 27%告警,说明很空闲。

图6

6.jpg

提示:虽然我们设的是30%,但这里显示的是27%,官网说这种差别是正常,可以忽略

找一台可以访问到我们ALB域名的服务器,安装apache httpd,然后进入你的apache文件夹并运行ab命令

/apache2.4/bin/ab -n 500000 -c 10000 http://yourdnsalb.cn-north-1.elb.amazonaws.com.cn/
  • -n 发送的总请求数量
  • -c 每次发送请求的数量

说明: httpd自带的ab命令可以很方便的模拟大访问量,ab会自动生成大量访问请求,因其在使用时会大量占用系统资源,需小心使用。

运行时

图8

这时我们观察ECS这边情况

CPU利用率达到100%了,Desired count也从1变成了3,但是启动运行还要一段时间,所以Running count还是1。

图9

9.jpg

Cloud Watch中也出现了超出阈值的告警

图11

过几分钟再刷新页面,可以看到Running count变成了3

图10

10.jpg

扩容后运行了3个task

图12

12.jpg

这里alarm变成OK,因为action(扩容)已经完成

图13

13.jpg

ab命令结束后会有一些统计数据汇总

图14

等到ab命令执行完,或者手工停止后过一段时间,task数量就会变成原来设定的1,这里就不截图了。

引申

  1. 扩容降级逻辑:当设定了某个阈值时比如CPU时,auto scaling会自动在Cloud Watch创建一个告警。当检测出连续3个超出阈值的datapoint时,就会进行扩容。扩容后仍然超出阈值则在等待冷静期时间后,继续扩容,直到达到设定的最大值。降级原理也是一样,只是在速度上有不同——积极扩容,消极降级。就是扩容要快,降级要慢,防止出现资源不足的情况。

  2. policy:这里只是设了一个值,其实还可以设成一个区域,另外也可以把多个policy组合起来使用。

资源下载

ECS auto scaling详细说明 docs.aws.amazon.com/AmazonECS/l…

模板文件下载,注意需要修改 github.com/tansong0091…

后记

auto scaling功能强大,也很方便。不过,实践中一般做为突发事件的补充,毕竟加载新的task还是需要一段时间的。

做这个测试时从检测到3次告警到扩容完成需要4,5分钟,考虑到多数task里未必只有一个镜像的容器,每个容器的复杂程度也不同,实际的启动时间只会更长。

所以我们需要根据实际情况综合运用auto scaling,schedule scaling还有手工扩容等手段才会取得比较好的效果。

喜欢请关注微信公众号“全是AWS干货”