AWS AutoScaling的一個ScaleDown策略問題以及解決方法

網易雲社群發表於2018-10-31

此文已由作者袁歡授權網易雲社群釋出。

歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。


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官方文件: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 流程步驟

簡要的流程圖如下所示:

AWS AutoScaling的一個ScaleDown策略問題以及解決方法

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上,地址為:github.com/yuanhuan200…

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時間,單位:秒
notificationEmails=user1@example.com;user2@example.com;user3@example.com #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的指令碼

這些指令碼的呼叫關係見下圖所示:

AWS AutoScaling的一個ScaleDown策略問題以及解決方法


免費體驗雲安全(易盾)內容安全、驗證碼等服務

更多網易技術、產品、運營經驗分享請點選



相關文章:
【推薦】 網站驗證碼WEB前端接入例項


相關文章