Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

83장. CloudWatch 메트릭과 알람

이 장에서 말하고자 하는 것

마이크로서비스 환경의 운영 난이도 절반은

“지금 무슨 일이 일어나고 있는지 보이지 않는다”

에서 온다.

이걸 풀어주는 게 관측성(Observability) 이다.

AWS의 출발점은

Amazon CloudWatch

이고, 그 중에서도 가장 기본이

메트릭(Metrics) + 알람(Alarms)

이다.


1. 메트릭 — 시간에 따라 변하는 숫자

CPUUtilization  : 65.3 (2026-01-01 10:00:00)
RequestCount    : 1240 (2026-01-01 10:00:00)
Latency         : 184  (2026-01-01 10:00:00)

AWS 서비스 대부분이 자기 메트릭을 자동으로 CloudWatch에 보낸다.

EC2          → CPU · 네트워크 · 디스크
ALB          → RequestCount · 5xx · TargetResponseTime
ECS          → CPU · Memory · TaskCount
RDS          → CPU · Connections · ReplicaLag
DynamoDB     → ConsumedCapacity · ThrottledRequests
SQS          → ApproximateNumberOfMessages
CloudFront   → Requests · CacheHitRate

운영자는 이 숫자들을 본다.


2. Namespace · Dimension · Metric

Namespace  : "AWS/ECS"
Metric Name: "CPUUtilization"
Dimensions : ServiceName=orders, ClusterName=msa
Statistic  : Average / Sum / Max / Min / p95 / p99
Period     : 1분 / 5분 / …

이 5개 축이 메트릭의 좌표다.

같은 이름의 메트릭도 Dimension 이 다르면 별도 시계열


3. 통계와 백분위 (p95 · p99)

평균은 진실을 가린다.

평균 응답 시간: 80ms
하지만 p99: 1.2초   ← 1%의 사용자는 끔찍한 경험

운영에서 자주 보는 건

  • p50 — 중앙값
  • p95 — 상위 5%의 경계
  • p99 — 상위 1%의 경계

평균과 p99 를 함께 본다


4. 알람 (Alarm)

조건: 지표가 임계를 넘으면 알린다
ALB 5xx > 10건 / 5분  → 알람 발생
        ↓
SNS → Slack · 이메일 · 호출

알람의 상태:

  • OK — 정상
  • ALARM — 조건 충족
  • INSUFFICIENT_DATA — 데이터 부족

알람이 시끄러우면 사람이 무시한다.
“정말 행동이 필요할 때만” 울리도록 만든다.


5. Composite Alarm — 여러 조건의 조합

"ALB 5xx 가 늘고 AND ECS CPU 가 높을 때만" → 진짜 운영 문제

단일 메트릭 알람은 노이즈가 많다.
Composite Alarm으로 조합해 정밀도를 높인다.


6. Custom Metric — 우리 애플리케이션 지표

AWS 메트릭만으로 부족할 때, 코드에서 직접 메트릭을 보낸다.

OrdersCreated     (도메인 지표)
PaymentLatency
QueueLag

방법:

  • PutMetricData API 호출
  • CloudWatch Agent 의 StatsD 인터페이스
  • CloudWatch Embedded Metric Format (EMF) — 로그 한 줄에 메트릭을 포함

EMF가 컨테이너 환경에 가장 자연스럽다 (로그만 출력하면 자동 메트릭화)


7. Dashboard

여러 메트릭을 한 화면에서 본다.

[서비스 orders 대시보드]
  ├─ RequestCount
  ├─ p95 / p99 Latency
  ├─ 5xx Rate
  ├─ ECS CPU / Memory
  └─ RDS Connections · ReplicaLag

서비스마다 하나씩.


8. 어떤 메트릭에 알람을 거나 — 출발점

사용자 관점 (가장 중요)

  • 응답 시간 p95 / p99
  • 에러율 (4xx / 5xx)

시스템 관점

  • ECS CPU · Memory
  • RDS CPU · Connections · ReplicaLag
  • SQS Queue depth · ApproximateAgeOfOldestMessage

비용 관점

  • DynamoDB ThrottledRequests
  • NAT Gateway BytesOut
  • Lambda Errors / Throttles

SLO(서비스 수준 목표) 기반으로 정한다
“p95 가 200ms 이하” 같은 약속에서 알람이 나온다


9. 우리 서비스에서

서비스마다 (orders / users / payments):
  ├─ ALB 5xx > 1%        → Slack
  ├─ ALB p99 > 1s         → Slack
  ├─ ECS CPU > 80%        → Slack
  ├─ Task 가용 < min      → Page (호출)

DB:
  ├─ RDS CPU > 80%
  ├─ RDS Connections > 80% of max
  └─ ReplicaLag > 30s

큐:
  ├─ DLQ 메시지 > 0       → Page
  └─ ApproximateAge > 10분

알람의 등급을 나눈다 — 모두 호출하지 않는다.


10. 직접 확인해보기 — CLI

메트릭 조회

aws cloudwatch get-metric-statistics \
  --namespace AWS/ECS \
  --metric-name CPUUtilization \
  --dimensions Name=ServiceName,Value=orders Name=ClusterName,Value=msa \
  --start-time 2026-01-01T00:00:00Z \
  --end-time   2026-01-02T00:00:00Z \
  --period 60 \
  --statistics Average

알람 만들기

aws cloudwatch put-metric-alarm \
  --alarm-name orders-cpu-high \
  --metric-name CPUUtilization \
  --namespace AWS/ECS \
  --statistic Average \
  --dimensions Name=ServiceName,Value=orders Name=ClusterName,Value=msa \
  --period 60 \
  --threshold 80 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 5 \
  --alarm-actions arn:aws:sns:...:ops-alerts

커스텀 메트릭 (PutMetricData)

aws cloudwatch put-metric-data \
  --namespace MyApp \
  --metric-name OrdersCreated \
  --value 1 \
  --dimensions Service=orders,Env=prod

11. 코드로는 이렇게 생겼다 — Terraform

resource "aws_cloudwatch_metric_alarm" "orders_5xx" {
  alarm_name          = "orders-alb-5xx"
  namespace           = "AWS/ApplicationELB"
  metric_name         = "HTTPCode_Target_5XX_Count"
  statistic           = "Sum"
  period              = 60
  evaluation_periods  = 5
  threshold           = 10
  comparison_operator = "GreaterThanThreshold"

  dimensions = {
    LoadBalancer = aws_lb.main.arn_suffix
    TargetGroup  = aws_lb_target_group.orders.arn_suffix
  }

  alarm_actions = [aws_sns_topic.ops_alerts.arn]
  ok_actions    = [aws_sns_topic.ops_alerts.arn]

  treat_missing_data = "notBreaching"
}

treat_missing_data 설정이 운영에서 중요하다 — 데이터가 없을 때의 기본 동작.


12. 이렇게 쓰면 망한다 — 안티패턴

안티패턴 1. 평균만 본다

p95 · p99 가 보이지 않으면 사용자 경험을 알 수 없다.

안티패턴 2. 알람을 너무 많이 만든다

모두가 알람을 무시하는 “알람 피로(alert fatigue)” 가 온다.

정말 행동이 필요할 때만 울리도록

안티패턴 3. 알람을 임곗값만으로 거고 사람 행동 매뉴얼이 없다

“왜 울렸지?” 만 반복.

알람에 Runbook 링크를 함께 둔다

안티패턴 4. CPU 만 본다

CPU 가 한가한데도 사용자 응답이 느린 경우가 많다 (DB · 외부 호출 · 네트워크).

사용자 메트릭 (5xx · p95) 부터 본다


13. 한 줄로 정리

CloudWatch 메트릭과 알람은 운영의 눈이며,
“사용자 메트릭 + p95/p99 + 의미 있는 알람” 이 핵심이다


14. 이 장의 핵심 정리

  1. CloudWatch는 AWS 서비스 메트릭을 자동으로 모은다.
  2. Namespace · Dimension · Metric · Statistic · Period 가 좌표다.
  3. p95 / p99 는 평균이 가리는 진실을 보여준다.
  4. Custom Metric은 EMF가 컨테이너에 가장 자연스럽다.
  5. Composite Alarm으로 노이즈를 줄인다.
  6. 알람은 SLO 기반으로, 등급을 나눠 — 모두 호출하지 않는다.