使用 CloudWatch 整合 SNS 與 SQS

AWS 監控與疑難排解

John Q. Martin

Principal Consultant

將 CloudWatch 警示連接到 SNS

aws cloudwatch put-metric-alarm \
  --alarm-name HighCPUUtilization \
  --metric-name CPUUtilization \
  --namespace AWS/EC2 \
  --statistic Average \
  --period 300 \
  --evaluation-periods 2 \
  --threshold 80 \
  --comparison-operator GreaterThanThreshold \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:production-alerts \
  --ok-actions arn:aws:sns:us-east-1:123456789012:recovery-notifications

 

流程:CloudWatch 警示透過 --alarm-actions 傳送到 SNS 主題,並向外分送給訂閱者——Email、SMS、Lambda 與 SQS

AWS 監控與疑難排解

SNS 核心概念

元件

  • SNS 採發布/訂閱:主題、發布者、訂閱者
  • 主題:具名通道;發布者送出、訂閱者接收
  • 發布一次,同步送達所有訂閱者

訂閱協定(單一主題,多個端點):

  • Email、SMS
  • HTTP/HTTPS
  • Lambda、SQS
  • 行動推播、Kinesis Firehose
AWS 監控與疑難排解

SNS 主題型別

 

比較 SNS Standard 與 FIFO 主題型別在排序、輸送量與傳遞保證的差異

AWS 監控與疑難排解

建立 SNS 主題:AWS CLI

標準主題

aws sns create-topic \
  --name production-alerts

FIFO 主題

aws sns create-topic \
  --name production-alerts.fifo \
  --attributes FifoTopic=true,\
    ContentBasedDeduplication=true

啟用加密

aws sns create-topic \
  --name production-alerts \
  --attributes KmsMasterKeyId=alias/aws/sns
AWS 監控與疑難排解

新增 Lambda 與 SMS 訂閱者

 

Lambda

aws sns subscribe \
  --topic-arn arn:aws:sns:us-east-1:123456789012:production-alerts \
  --protocol lambda \
  --notification-endpoint arn:aws:lambda:us-east-1:123456789012:function:ProcessAlert

SMS

aws sns subscribe \
  --topic-arn arn:aws:sns:us-east-1:123456789012:critical-alerts \
  --protocol sms \
  --notification-endpoint +1234567890
AWS 監控與疑難排解

CloudWatch 警示的 SNS 訊息格式

{
  "AlarmName": "HighCPUUtilization",
  "NewStateValue": "ALARM",
  "OldStateValue": "OK",
  "NewStateReason": "Threshold Crossed: 2 datapoints [85.0, 90.0] were greater than the threshold (80.0).",
  "StateChangeTime": "2026-03-27T10:30:45.123+0000",
  "Trigger": {
    "MetricName": "CPUUtilization",
    "Namespace": "AWS/EC2",
    "Statistic": "AVERAGE",
    "Period": 300,
    "Threshold": 80.0,
    "ComparisonOperator": "GreaterThanThreshold"
  }
}
AWS 監控與疑難排解

SNS 訊息過濾

aws sns set-subscription-attributes \
  --subscription-arn arn:aws:sns:...:production-alerts:abc123 \
  --attribute-name FilterPolicy \
  --attribute-value '{"AlarmName":["HighCPUUtilization"],"NewStateValue":["ALARM"]}'

aws sns set-subscription-attributes \
  --subscription-arn arn:aws:sns:...:production-alerts:abc123 \
  --attribute-name FilterPolicyScope \
  --attribute-value MessageBody
AWS 監控與疑難排解

用 Lambda 自訂通知格式

def lambda_handler(event, context):
    alarm = json.loads(event['Records'][0]['Sns']['Message'])

    message = f"""
ALERT: {alarm['AlarmName']}
Status: {alarm['NewStateValue']}
Reason: {alarm['NewStateReason']}
Resource: {alarm['Trigger']['Dimensions'][0]['value']}
Runbook: https://wiki.example.com/runbooks/high-cpu
    """

    sns.publish(
        TopicArn='arn:aws:sns:...:formatted-alerts',
        Subject=f"{alarm['AlarmName']}",
        Message=message
    )

 

串接:原始警示主題觸發 Lambda,格式化為易讀訊息後再發布到 formatted-alerts 主題給值班工程師,機器消費者則留在原始主題

AWS 監控與疑難排解

結合 SQS 的扇出架構

扇出架構:一則 SNS 訊息傳遞到多個 SQS 佇列與一個 Lambda 消費者

AWS 監控與疑難排解

設定扇出

四個步驟

  1. 建立 SQS 佇列(每個消費者一個)
  2. 設定佇列原則(允許 SNS 傳送訊息)
  3. 訂閱佇列到 SNS 主題
  4. 建置消費者(輪詢、處理、刪除)

佇列原則

{
  "Effect": "Allow",
  "Principal": { "Service": "sns.amazonaws.com" },
  "Action": "sqs:SendMessage",
  "Resource": "arn:aws:sqs:...:alarm-logging-queue",
  "Condition": {
    "ArnEquals": {
      "aws:SourceArn": "arn:aws:sns:...:production-alerts"
    }
  }
}
AWS 監控與疑難排解

訂閱佇列

 

訂閱每個佇列

aws sns subscribe \
  --topic-arn arn:aws:sns:...:production-alerts \
  --protocol sqs \
  --notification-endpoint arn:aws:sqs:...:alarm-logging-queue
AWS 監控與疑難排解

處理訊息

消費者樣式

response = sqs.receive_message(
    QueueUrl=queue_url,
    MaxNumberOfMessages=10,
    WaitTimeSeconds=20       # 長輪詢
)
for message in response.get('Messages', []):
    sns_msg = json.loads(message['Body'])
    alarm = json.loads(sns_msg['Message'])
    # 處理警示資料
    sqs.delete_message(QueueUrl=queue_url,
                       ReceiptHandle=message['ReceiptHandle'])
AWS 監控與疑難排解

含過濾與死信佇列的扇出

依訂閱定向傳遞

  • 工單佇列:{"NewStateValue":["ALARM"],"Severity":["Critical"]}
  • 紀錄佇列:無過濾(全部接收)
  • 指標佇列:{"MessageType":["Metric"]}

 

死信佇列(DLQ)

aws sqs set-queue-attributes \
  --queue-url https://sqs..../alarm-logging-queue \
  --attributes '{
    "RedrivePolicy": "{\"deadLetterTargetArn\":\"arn:aws:sqs:...:alarm-logging-dlq\",\"maxReceiveCount\":\"3\"}"
  }'
AWS 監控與疑難排解

SNS 與 SQS:何時使用

比較 SNS 推播式傳遞與 SQS 拉取式訊息佇列

AWS 監控與疑難排解

架構範例

 

簡易警示樣式:透過 SNS 發送通知到 email

 

非同步處理樣式:API 傳送到 SQS 佇列,由工作者消費

多通道警示樣式:一個警示向外分送到多個通知通道

事件管線樣式:將來源事件路由到多個 SQS 佇列處理

AWS 監控與疑難排解

影片總結

 

  • SNS 主題可透過 email、SMS、HTTP、Lambda、SQS 傳遞警示通知
  • 扇出樣式:一則 SNS 訊息 → 多個 SQS 佇列,並行且可靠處理
  • 訊息過濾可為每個訂閱者降噪
  • 死信佇列攔截處理失敗的訊息
  • SNS 用於推播通知,SQS 用於可靠處理;兩者結合可兼具扇出與可靠性
AWS 監控與疑難排解

一起來練習吧!

AWS 監控與疑難排解

Preparing Video For Download...