AWS AutoScaling的一个ScaleDown策略问题以及解决方法

1. AWS AutoScaling简介

AutoScaling是AWS的一个重要服务,用来弹性的自动创建(ScaleUp)或者删除(ScaleDown)EC2虚拟机,并且Scale的策略完全是用户自定义的、或者是基于虚拟机健康状态检查结果、或者是按照计划来实施Scale策略。

例如,考虑如下的业务场景,系统部署在EC2虚拟机上,所有任务分发均是通过AWS SQS来完成的,即请求按照特定格式发送到SQS指定队列中,而EC2虚拟机上运行的系统从这个队列读取消息来运行任务。

借助于AutoScaling,我们可以简单的设置下面的伸缩策略:

1)确保至少有2台EC2虚拟机正常提供服务;

2)ScaleUp:当SQS队列中的消息个数超过20个的时候,就自动创建一台或者多台虚拟机,ScaleUp策略执行之后CoolDown一段时间再次检查ScaleUp策略。当然创建该虚拟机的镜像需要提前预制好,确保虚拟机创建之后OS运行的时候,我们的业务系统能够自动运行起来。

3)ScaleDown:当SQS队列中的消息个数小于20个的时候,自动删除一台虚拟机。

说明:上面的例子只是简单的演示了AutoScaling的使用方式,可以借助于CloudWatch来实现更强大更精细的AutoScaling配置。

更多介绍详见AWS AutoScaling官方文档:http://aws.amazon.com/autoscaling/

2. AWS AutoScaling的ScaleDown策略存在的问题

对于一般的同步请求业务系统而言,AutoScaling的功能是比较强大的,借助于它,我们可以方便的实现业务的弹性自动伸缩。

但是,在使用过程中,发现AWS的AutoScaling(下文简称AmazonAS)存在一个问题,就是对于长时间运行的业务而言,比如一个视频转码请求需要几个小时才能处理完的,任务运行的时间几乎和视频时长一样长。在这种情况下,AmazonAS的ScaleDown策略就会出现一个问题:如果在一个虚拟机正在运行任务的时候,AmazonAS根据CloudWatch数据触发了ScaleDown策略,那么很有可能会删除掉该虚拟机,从而引起业务数据丢失或混乱。由此可见,AmzonAS并不适合于我们的业务特性,因此有必要仿照AmazonAS来实现一套定制化的AutoScaling来满足我们的业务需求。

3. 解决方法

3.1 ScaleUp策略

基本类似AmazonAS的ScaleUp策略来实现,或者说是它的简化版本。 通过监控SQS中指定队列的消息个数来自动新建一定数量的虚拟机,来运行队列中的任务消息,新建虚拟机的同时发送邮件到指定邮箱。

3.2 ScaleDown策略

由上文介绍的AmazonAS存在的问题或不足,我们就不能简单的根据SQS中消息个数来删除虚拟机了。我们的策略是让虚拟机内部自动根据任务运行情况来自我删除。

实现方式如下: 在虚拟机内部预制好检查任务运行状态(我们是通过检测日志来实现的)的脚本,如果发现系统空转一段时间之后就执行关机命令,进而触发AWS EC2虚拟机的Shutdown Behavior进行自我删除。备注:这就要求创建虚拟机的时候设置Shutdown Behavior为Terminate,即删除。

3.3 流程步骤

简要的流程图如下所示:

1) 首先,AutoScaling启动一个线程,进入循环;

2)在当前循环周期内,根据SQS中消息个数进行ScaleUp策略检查,如果满足策略条件,则调用EC2创建虚拟机的API创建一台或者多台虚拟机,并将Shutdown Behavior设置为Terminate,虚拟机参数会在AutoScaling中进行预先配置。如果创建了虚拟机则会根据预制的邮件列表发送邮件通知,并且CooleDown一段时间。

3)在当前循环周期内,ScaleUp完成之后就进行ScaleDown策略检查,真正运行ScaleDown策略的机制是在EC2虚拟机里面通过cron任务来执行的,在AutoScaling中仅仅是判断哪些虚拟机在当前循环周期内被删除了,如果检测到有虚拟机被删除掉,则发邮件通知。

4)ScaleUp和ScaleDown在当前周期全部执行完毕之后,等待一段时间,然后重新进入下一次循环周期。

3.4 代码实现

使用Java开发了该系统,并且运行在tomcat容器中,所有代码和脚本全部公开在github上,地址为:https://github.com/yuanhuan2005/autoscaling.git

3.4.1 代码结构

代码位于autoscaling/src/main/java/com/tcl/autoscaling下面:


awsec2    #EC2创建新的虚拟机接口

awsses #SES接口,用于发邮件

awssqs #SQS接口,用于操作SQS中的消息

common #公共方法

listener #监听器

mail #发邮件接口

transcode #执行业务Scale的核心代码

3.4.2 配置文件

配置文件位于autoscaling/src/main/resources/autoscaling.propertites中:

awsAccessKeyId=YOUR_ACCESS_KEY #AWS的access key id        
awsSecretAccessKey=YOUR_SECRET_KEY #access key对应的secret key          
queueMessageCheckDuration=600 #队列中的消息检查周期,单位:秒          
transcodeMonitorQueueURL=https://sqs.us-east-1.amazonaws.com/xxxxxxxxxxxxx/transcoderQueue #队列地址          
transcodeMonitorQueueTotalNumberThreshold=1 #队列消息个数的阀值          
transcodeInstanceLanchNumber=1 #启动的虚拟机个数          
transcodeImageIdToLanchInstances=ami-88888888888 #启动虚拟机使用的镜像id          
transcodeRegion=us-west-2 #虚拟机在哪个region创建          
transcodeAvailabilityZones=us-west-2a,us-west-2b,us-west-2c #虚拟机在上面的region中哪个可用分区中创建          
transcodeMaxInstancesNum=20 #创建虚拟机的最大个数          
transcodeInstanceType=m1.xlarge #虚拟机规格          
transcodeKeyPair=transcoder_for_asg #虚拟机keypair,用于ssh登录          
transcodeSecurityGroupId=sg-f321c896 #虚拟机所在的安全组          
transcodeInstanceName=test #虚拟机名称,便于管理          
transcodeCoolDownTimeInSeconds=1200 #cooldown时间,单位:秒          
[email protected];[email protected];[email protected] #email列表,多个email用分号分割

3.4.3 shell脚本

在EC2虚拟机中需要安装如下的脚本,默认安装路径是/home/ec2-user/bin/,如有变化可对应修改。

脚本解释如下:


check_dispatcher_status.sh #检查运行状态。如果空转,则将idle_number的数字加1,当idle_number达到配置的上限时执行关机命令进行自我删除;如果没有空转即正在运行任务,则将idle_number清零,等待进入下次检查周期。

idle_number #记录空转次数的文件

dispatcher #注册为系统服务,以便可以用service命令进行管理,文件路径:/etc/init.d/dispatcher

restart_tomcat.sh #重启tomcat的脚本

start_tomcat.sh #启动tomcat的脚本

status_tomcat.sh #检查tomcat运行状态的脚本

stop_tomcat.sh #停止tomcat的脚本

这些脚本的调用关系见下图所示:

时间: 2024-08-07 20:18:52

AWS AutoScaling的一个ScaleDown策略问题以及解决方法的相关文章

Ajax跨域、Json跨域、Socket跨域和Canvas跨域等同源策略限制的解决方法

同源是指同样的协议.域名.port,三者都同样才属于同域.不符合上述定义的请求,则称为跨域. 相信每一个开发者都曾遇到过跨域请求的情况,尽管情况不一样,但问题的本质都能够归为浏览器出于安全考虑下的同源策略的限制. 跨域的情形有非常多,最常见的有Ajax跨域.Socket跨域和Canvas跨域.以下列举一些我们常见的跨域情形下.某些浏览器控制台给出的错误提示: FireFox下的提示: 已阻止交叉源请求:同源策略不同意读取***上的远程资源.能够将资源移动到同样的域名上或者启用 CORS 来解决问

Firefox提示“安全连接失败,您收到了一个无效的证书”的解决方法

当你看到这篇文章的时候,我已经坐上轻轨准备前往某个地方游玩去了,这篇文章实际上是我昨天写好然后用wordpress的定时发布功能发布的,实际上这里大部分文章都是我事先写好然后定时发布的,特别是这个月希望能够保持每天更新一篇文章的频率,一有想法就会赶快记录下来,害怕忘记什么. 在Firefox上搭配AutoProxy/FoxyProxy和goagent穿越的时候需要导入证书,不过我在导入证书后浏览某个网站会有以下提示:(AutoProxy/FoxyProxy对该网站启用) 安全连接失败 连接 XX

IIS发布网站出现“未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项。”的解决方法

未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项.试图加载格式不正确的程序.              说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息.             异常详细信息: System.BadImageFormatException: 未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项.试图加载格式不正确的程序.源错误: 执行当前 Web

关于在for循环里调用ajax时只能取到最后一个数据的bug的解决方法

首先,造成这中情况的原因在与ajax的异步请求机制,for循环的运行速度远大于ajax异步请求的速度,这就造成了ajax运行时,需要的在for循环里的参数已经运行到最后一个了,所以取到的都是最后一个参数数据. 解决方法:将ajax的请求封装成一个单独的方法,然后在for循环里调用该方法.

43.关于浮点数的乘除法预算误差,一个看似没什么问题的解决方法

commission是一个浮点数,在进行乘除法预算的时候会存在误差,下面是我的解决方法

Win10组策略命名空间占用解决方法

对很多资深电脑用户来说"组策略编辑器"并不陌生,使用组策略编辑器可以对系统进行一些更深度的设置.不过最近有Win10用户反馈"组策略"打开后总是弹出"命名空间--已经被定义为存储中另一文件的目标命名空间"的对话框,虽然点击"确定"后可以关闭,而且不影响组策略功能,但每次开启都要应付弹窗实在是有些麻烦,怎么解决呢? 不过我们可以根据这个对话框给出的内容顺藤摸瓜,找出问题的根源,然后加以解决.具体方法如下: 1.进入C:\Wind

CSS中的各个选择节点,都有样式最后一个无样式的快捷解决方法

2.1.3 多标签 多标签选择器一般和html上下文有关,它有以下集中分类 选择一个祖先的所有子孙节点,例如 div p{…} 选择一个父元素的所有直属节点,例如 div > p{…} 选择某一个元素紧挨着的兄弟节点,例如 li + li{…} 选择某一个元素的所有同胞节点,例如 span ~ a{…} 以上各种情况的组合应用(不要组合过于复杂,编码讲求可读性第一) 给大家列举一个比较典型的应用,如下图 上图中的效果应该比较常见,在各个菜单之间加下划线.我之前的实现是:每个li都加一个borde

一个数学问题的Python解决方法

一个正整数n.它是由数字3和7组成,且这个数以及这个数各位数字之和都是3和7的倍数,求n的最小值要有过程. # coding=utf-8 import numpy as np x_num = 1 while True: x_str = str(x_num) #数字转换为字符 x_str_list = list(x_str) #为将元组转换为列表 x_str_len = len(x_str_list) #列表元素个数 x_com=x_num #为了后续是否因为不满足条件而到导致数字继续推后 x_s

记录一个浏览器主页被篡改的解决方法

前两天新装了win7,然后发现无论打开谷歌浏览器还是IE,都会跳到毒霸网址大全,非常流氓,猜测有百分之七八十是因为用了某驱动管理软件造成的,试了各种解决办法,在我电脑上生效的方法是: 1.卸载了各种驱动管理软件 2.谷歌浏览器打开后,设置--启动时--打开特定网页或一组网页--删掉毒霸的网址 3.IE浏览器打开后,工具--Internet选项--常规--主页--删掉毒霸的网址 最后感叹一声:有文化的流氓真可怕......