CloudWatch 可以看到 EC2 的 CPU 使用率,但總不能一直開著圖表,等它變高吧?今天我們要讓 AWS 在符合條件時,主動寄信通知自己
CloudWatch 裡的 Alarm(警報) 負責檢查 CPU 有沒有達到設定的門檻,Amazon SNS(通知服務) 再把訊息送到訂閱的信箱
假設程式剛啟動,CPU 短暫升高,幾秒後就降回來。如果這樣也寄信,通知一多,最後你大概也懶得看了 XD
所以這次會以五分鐘為一個區間,看 CPU 的平均使用率;最近三個區間都達到 70%,才觸發警報。這裡先看 CPU 資料都有正常回報的情況:
假設三個區間分別是 75%、82%、78%,就符合條件;換成 75%、40%、78%,中間降下來了,就不符合這次的設定
圖上每一格都是五分鐘的平均值,不是要求每一秒都高於 70%。EC2 基本監控的 CPU 資料通常每五分鐘提供一次,所以這裡也用五分鐘來看,附上(EC2 監控週期)
70% 是這次練習的門檻。用在自己的網站時,還是要看平常的負載,以及希望多快收到提醒,再調整數字
先在 SNS 建立一個 Topic(主題),讓自己的信箱訂閱它。之後 CloudWatch 把警報送進這個 Topic,SNS 就會通知訂閱者
這跟 SES 寄會員驗證信的用途不同:這篇是讓 AWS 在主機符合警報條件時通知我們,不用回 Node.js 寫寄信程式
回 AWS 網頁,區域切到東京,進入 SNS → Topics → Create topic:
demo-api-alerts,建立 Topic。按完後,回 SNS 的 Subscriptions 清單,確認這個信箱不再顯示 Pending confirmation。信箱要同意訂閱,SNS 才會把通知寄過去;做過 SES 的信箱驗證
收件者準備好了,接著設定要看哪台主機、什麼情況才觸發
進入 CloudWatch → Alarms → All alarms → Create alarm。畫面假使先出現 Data source 與 Type,分別選 Metrics 和 Classic,再按 Select metric
從 EC2 → Per-Instance Metrics 找到自己的 InstanceId,勾選 CPUUtilization。不確定 ID,就回 EC2 的 Instances 清單對照;這樣才不會監控到另一台主機
接著填入剛才討論的條件:
| 欄位 | 填寫內容 |
|---|---|
| Statistic | Average,看平均值 |
| Period | 5 minutes,每五分鐘一個區間 |
| Threshold type | Static,使用固定門檻 |
| Condition | Greater/Equal,門檻填 70 |
| Datapoints to alarm | 3 out of 3,三個區間都要符合 |
| Missing data treatment | Treat missing data as missing,缺資料時不直接算成正常或超標 |
下面是填寫時的畫面。展開 Additional configuration,就能找到 Datapoints to alarm,Missing data treatment 也在這個區塊裡

條件填好後,按 Next → Configure actions → Add notification。狀態選 In alarm,再選 Select an existing SNS topic,指定剛才建立的 demo-api-alerts
上圖還沒指定 Topic,你操作時記得選好。這次只加 SNS 通知,其他像停止 EC2、刪除 EC2 的動作先不加
接著將 Alarm 命名為 demo-api-cpu-high,在最後的預覽頁確認主機 ID、CPU 條件與 Topic 都正確,再按 Create alarm
回到 Alarms 清單,會看到這個 Alarm 的狀態:
剛建立時如果看到 INSUFFICIENT_DATA,先回 CPU 圖表,確認這台 EC2 有沒有持續送出資料。這次選 missing,評估範圍內完全收不到資料時,就會進入這個狀態,也附上(缺資料的處理方式)
也提醒下,OK 只是在說這條 CPU 規則沒有觸發。假設程式連不到資料庫,CPU 可能還很低,所以網站能不能正常使用,還是要另外測 API
可以用 set-alarm-state,暫時把 Alarm 從 OK 改成 ALARM。這次狀態變更會真的執行通知動作,所以先打開 demo-api-cpu-high,確認它目前是 OK、Actions 已啟用,而且只設定了剛才的 SNS 通知
這個指令在 AWS 網頁裡的 CloudShell 執行就好。到頂端搜尋 CloudShell 並開啟,它是 AWS 提供的終端機,已經裝好 CLI,使用的也是你目前登入 AWS 的身分(CloudShell 開啟方式)
保持東京區,等終端機出現提示後,先輸入:
aws sts get-caller-identity
確認回傳的 Account 和 Arn 是這次練習的帳號與登入身分,再貼上下面指令。CloudShell 預設使用 Bash,Mac、Windows 都可以照貼:
aws cloudwatch set-alarm-state \
--region ap-northeast-1 \
--alarm-name demo-api-cpu-high \
--state-value ALARM \
--state-reason 'notification path test only'
--alarm-name 是要測的 Alarm 名稱,--state-value 指定新狀態,--state-reason 是留下這次變更的原因。如果你前面取了別的名字,這裡也要跟著換
成功時通常沒有回傳文字,回到提示列就好。接著打開這個 Alarm 的 History,看剛才的狀態變更與通知動作,再去信箱找同一個 Alarm 名稱、同一個時間的信
狀態可能很快被下一次 CPU 判斷改回來,所以要看 History,不用一直等畫面變紅(SetAlarmState 測試方式)
剛才是我們直接把狀態改成 ALARM,CPU 並沒有真的升高。所以收到信,表示圖中 Alarm → SNS → 信箱 這一段走通了。CPU 門檻那一段,還要等實際資料符合條件,再看它是否觸發
如果沒收到,先沿著剛才的操作查:
| 看到什麼 | 先檢查哪裡 |
|---|---|
| CloudShell 無法開啟,或指令出現 AccessDenied | 目前登入身分是否有 CloudShell 存取權,以及這個 Alarm 的 cloudwatch:SetAlarmState 權限 |
| History 沒有這次改成 ALARM 的紀錄 | 指令是否成功、Region 與 Alarm 名稱是否正確。原本就已是 ALARM 時,沒有新的狀態變更 |
| 有狀態變更,通知動作卻失敗 | Actions 是否啟用、選到的 Topic 是否正確;假使顯示權限錯誤,檢查 Topic 的存取政策是否允許這個 Alarm 發布通知 |
| History 顯示已送到 SNS,信箱卻沒收到 | SNS 訂閱是否已確認、Email 有沒有填對,再看垃圾郵件匣 |
之後真的收到 CPU 警報,我會先看信中的主機、時間與判斷原因,再回 CloudWatch 對照那段時間的 CPU 圖表和程式紀錄
假設剛好在部署或匯入資料,就先確認是不是這個動作造成的。知道原因後,再決定要改程式、調整工作執行時間,還是增加主機資源
練習結束後,不再需要這組通知,就刪除專用的 Alarm、SNS Email subscription 和 Topic。要繼續觀察也可以保留,但 CloudWatch 與 SNS 都要留意用量和費用(CloudWatch 計價、SNS 計價)
下一篇再回到整張架構圖,看看使用者操作一次網站時,這些 AWS 服務怎麼分工。我們下篇見 :D