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官方文件:
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上,地址為: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 |
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的指令碼 |
這些指令碼的呼叫關係見下圖所示:
更多網易技術、產品、運營經驗分享請點選。
相關文章:
【推薦】 網站驗證碼WEB前端接入例項