Incident Flow: 감지 → Triage → Mitigation → RCA

1,476 단어·3 분·원문(.md)

Incident Flow는 장애 대응 라이프 사이클이다.

감지 triage mitigation, RCA 순의 flow를 오늘 한번 알아보겠다.

Detection #

장애 대응의 시작은 감지이다. detection, 이상적인 감지는 고객의 cs 문의가 들어오기 이전에 시스템이 먼저 비명을 지르는 것이다/

이를 측정하는 지표를 MTTD(Mean Time To Detect, 평균 감지 시간)이라고 한다.

핵심 목표는 장애 인지 시간을 최소화 하는것이다.

주요 액션은 APM(Datadog, Scouter) 및 메트릭(Prometheus) 모니터링 이후 SLO 서비스 수준 목표 기반의 에러율 및 지연시간 스파이크를 감지한다.

알람 피로도 alert fatigue를 피하기 위해서 cpu 80% 도달과 같은 증상 기반 알림보다는 결제 api 성공률 95%미만같은 비즈니스 임팩트 기반 알람으로 세팅해야한다.

Triage (분류 및 전파) #

알람을 확인한 엔지니어가 상황의 심각성을 판단하고 필요한 사람을 모으는 단계다.

이를 측정하는 지표율을 MTTA Mean Time to Acknowledge 즉 평균 인지/응답 시간이라고 한다.

핵심 목표는 장애 등급 Severity를 확정하고 워 룸을 꾸리는 것이다.

주요 액션으로는 severity 산정 메트릭스를 통해 SEV-1 ~ SEV-4를 부여한다.

pagerdutiy, slack 연동등을 통해서 관련 도메인 담당자 인프라 엔지니어 리더그룹 강제 소집한다.

팁으로는 제가 한번 볼게요 하고 혼자 30분 동안 파고드는것보다 5분 안에 파악이 안되면 무조건 Incident를 선언하고 주변에 전파하자/

Mitigation (완화 및 지혈) #

사이클의 핵심이자 엔지니어 역량이 가장 적나라하게 드러나는 단계다. 지표로는 MTTR Resolve/Recover, 평균 복구 시간으로 측정된다.

핵심 목표는 비즈니스 임팩트(고객 피해 최소화)이다.

  • Rollback: 직전 배포 버전으로 코드 원복
  • Scale-out: 트래픽 폭주시 즉각적인 서버 증설
  • Circuit Breaking: 죽어가는 하위 시스템으로 가는 트래픽 강제 차단.
  • Feature Toggle: 문제 되는 신규 기능 스위치 off

이 단계에서는 소스코드를 열어보거나 db query를 디버깅하지말고 일단 격리와 우회에만 먼저 집중을 하자 빨리 처리해야하니까.

물론 쿼리로 빠르게 확인할 수 있는 상황이라면, 해도 좋겠지만.. 일단 대응이 우선이다.

RCA (Root cause Analysis) #

불을 끄고 서버가 안정화 되었다면 이제 차분하게 로그와 덤프를 분석해 원인을 찾고 예방책을 세우자

동일한 장애의 재발 방지가 목적이며 post moterm 사후 분석 보고서를 작성한다. 5whys로 근본 원인을 도출하고 시스템적 방어로직이 포함된 action item 수립 및 티켓을 발행한다.

비난없는 문화가 필수인데 xxx님이 잘못 코드를 짜셨어요 보다는 이 코드가 배포된 ci/cd의 맹점을 파악하거나 함께 책임을 지는 문화가 좋다.

Example #

[감지] prometheus alertmanager룰 설정 예시

고객이 불만을 말하기 전에 결제 실패율을 치솟는 것을 먼저 감지하기

groups:
- name: payment_alerts
  rules:
  - alert: HighPaymentFailureRate
    expr: rate(http_requests_total{job="payment_api", status=~"5.."}[5m]) / rate(http_requests_total{job="payment_api"}[5m]) > 0.05
    for: 5m
    labels:
      severity: critical # Triage 단계로 넘어갈 SEV 등급
    annotations:
      summary: "Payment API Failure Rate is too high"
      description: "현재 결제 API의 5xx 에러율이 5%를 초과했습니다. 즉각적인 확인이 필요합니다."

[Mitigation] Istio를 활용한 Circuit Breaker 긴급 적용

RCA를 할 시간이 없어 죽어가는 외부 api 연동 때문에 우리 서버가 터지는걸 방지. fault injection

# 외부 API(external-point-service)가 계속 타임아웃을 내서 우리 스레드가 밀릴 때,
# 즉시 이 설정을 배포하여 해당 서비스로 가는 트래픽을 차단(Circuit Open)합니다.
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: external-point-service-cb
spec:
  host: external-point-service.internal
  trafficPolicy:
    outlierDetection:
      consecutive5xxErrors: 3 # 3번 연속 5xx 에러 발생 시
      interval: 10s           # 10초 동안 관찰하여
      baseEjectionTime: 3m    # 3분 동안 해당 서버로 요청을 아예 안 보냄 (빠른 실패 처리로 우리 스레드 보호)
      maxEjectionPercent: 100

[RCA] 5Whys 작성 예시 (post-moterm)

  • 문제: 결제 api가 20분간 전면 마비
  • why 1: 결제 db의 cpu가 100%를 치면서 새로운 커넥션을 맺지 못함
  • why 2: 유저 통계를 뽑는 무거운 slow query가 결제 db에 사용됨
  • why 3: 통계 api가 읽기 전용 db가 아닌 쓰기로 잘못 바라보도록 배포되어있음
  • why 4: db 엔드포인트를 관리하는 환경변수 분리가 명확하지 않음
  • action tiem: jpa/mybatis 레벨에서 @Transactional(readOnly = true)인 경우 무조건 read-replica db로 라우팅되도록 datasource 동적 라우팅을 시스템적으로 강제 적용함
SRE/question/q_47.md