서비스에서 장애 자체를 완전히 없애는 것은 어렵다.
문제는 장애가 발생했을 때다.
알림톡 실패율 급증
주문 생성 API 오류
DB Connection 증가
Webhook 처리 지연
배포 직후 500 Error 발생
이때 대응 순서가 없으면 보통 다음처럼 된다.
로그부터 봄
↓
DB 확인
↓
코드 확인
↓
AWS 확인
↓
최근 배포 확인
↓
다시 로그 확인
↓
어디부터 볼지 헷갈림
특히 1인 개발 환경에서는 더 위험하다.
개발자 본인이:
개발자
운영자
배포 담당자
DB 담당자
장애 대응자
역할을 전부 하기 때문이다.
그래서 장애 대응은 기억에 의존하면 안 된다.
Incident는 단순 Error 한 건과 다르다.
예:
알림톡 1건 실패
는 일반적인 오류일 수 있다.
하지만:
알림톡 전체 실패율 40%
주문 생성 불가
관리자 페이지 전체 접속 불가
라면 Incident로 관리할 가치가 있다.
즉:
서비스 품질 또는 비즈니스 흐름에 의미 있는 영향을 주는 운영 문제
를 Incident라고 볼 수 있다.
예:
개별 API Timeout 1회
→ Error
5분 동안 Timeout 500회
→ Incident
즉 Error는 사건 하나이고,
Incident는:
여러 Error가 모이거나
하나의 큰 장애가 발생하여
서비스 영향이 생긴 상태
다.
0922에서 Alert를 다뤘다.
Alert는:
이상 징후가 발견되었다
는 신호다.
Incident는:
실제로 대응이 필요한 문제라고 판단했다
는 상태다.
예:
Alert
알림톡 실패율 6%
↓ 확인
Provider 일시 지연
1분 후 정상화
→ Incident 생성하지 않을 수도 있음
반대로:
Alert
주문 API 실패율 20%
↓ 확인
실제 고객 신청 실패 발생
→ Incident 생성
이다.
모든 장애를 같은 우선순위로 대응하면 안 된다.
그래서 Severity를 사용한다.
예:
P0
P1
P2
P3
또는:
SEV0
SEV1
SEV2
SEV3
처럼 사용할 수 있다.
중요한 것은 이름보다 기준이 명확한 것이다.
현재 프로젝트 기준으로는 다음처럼 볼 수 있다.
고객 주문 생성 전체 불가
메인 서비스 전체 접속 불가
운영 DB 손상
대규모 개인정보 노출 가능성
결제/주문 데이터 대량 손실
즉시 대응 대상이다.
주문 생성 실패율 급증
일부 통신사 상품 전체 신청 불가
관리자 주문 처리 불가
알림톡 전체 발송 중단
배정 현황 조회 전체 장애
고객 및 매출 영향이 크다.
Excel Export 실패
특정 필터 검색 오류
일부 Webhook 지연
알림톡 일부 Retry 증가
관리자 특정 기능 오류
서비스 전체는 동작하지만 운영 불편이 있다.
UI 깨짐
통계 일부 지연
내부 AI Report 실패
운영 편의 기능 오류
즉각 대응이 필요하지 않을 수 있다.
예를 들어:
CPU 100%
라고 해서 무조건 P0가 아니다.
서비스가 정상이라면:
P2 또는 Warning
일 수도 있다.
반대로 CPU가 정상이어도:
주문 생성 100% 실패
면 P0에 가까울 수 있다.
따라서 기준은:
고객 영향
매출 영향
데이터 손실 위험
영향 범위
복구 가능성
위주로 본다.
장애가 발생하면 개발자는 본능적으로:
왜 발생했지?
부터 파고들기 쉽다.
하지만 운영에서는 먼저:
영향을 줄이는 것
이 우선이다.
예:
배포 이후 주문 API 장애
라면:
코드 원인 30분 분석
보다
직전 버전 Rollback
이 더 빠른 대응일 수 있다.
둘을 구분하면 좋다.
장애 영향을 줄이는 조치
예:
Rollback
기능 임시 비활성화
Traffic 우회
Worker 재시작
근본 문제를 해결하는 것
예:
Bug 수정
DB Index 추가
Retry 정책 수정
Incident 상황에서는 Mitigation이 먼저일 수 있다.
전체 흐름은:
Detect
↓
Triage
↓
Mitigate
↓
Diagnose
↓
Resolve
↓
Verify
↓
Postmortem
정도로 생각하면 된다.
장애를 발견한다.
경로는 여러 개다.
Alert
고객 문의
관리자 제보
로그 확인
SLO 위반
Dashboard
외부 Provider 장애 공지
좋은 시스템은 고객 문의보다 먼저 장애를 발견해야 한다.
장애의 범위를 빠르게 판단한다.
예:
전체 장애인가?
특정 API인가?
특정 통신사인가?
특정 Provider인가?
일부 고객만 발생하는가?
최근 배포와 연관 있는가?
이 단계에서는 완벽한 원인 분석이 필요하지 않다.
최소한:
언제 시작됐는가?
무엇이 영향받는가?
몇 명이 영향받는가?
현재도 계속 발생하는가?
최근 Deploy가 있었는가?
외부 Provider 장애인가?
를 빠르게 확인한다.
운영 장애의 상당수는 최근 변경과 연결될 수 있다.
따라서:
최근 Deploy
Migration
환경 변수 변경
Provider 설정 변경
Infrastructure 변경
을 확인한다.
이 때문에 0921에서 Deploy Marker를 언급했다.
장애 대응 중에는 시간이 지나면 기억이 섞인다.
따라서 바로 기록한다.
예:
10:02
알림톡 실패율 증가 Alert
10:04
Incident 확인
10:06
Provider API Timeout 확인
10:08
Retry 중단
10:12
Provider 장애 공지 확인
10:28
Provider 정상화
10:31
Queue 처리 재개
10:37
정상화 확인
이 기록이 나중에 Postmortem의 기반이 된다.
Incident마다 ID를 하나 만들면 좋다.
예:
INC-20260923-001
모든 관련 로그, 작업, 문서에 연결한다.
예:
correlationId
incidentId
releaseId
를 같이 추적할 수 있다.
interface Incident {
id: string;
title: string;
severity:
| 'P0'
| 'P1'
| 'P2'
| 'P3';
status:
| 'OPEN'
| 'MITIGATING'
| 'MONITORING'
| 'RESOLVED';
startedAt: Date;
detectedAt: Date;
resolvedAt?: Date;
impact?: string;
rootCause?: string;
}
단순히 OPEN / CLOSED만 두는 것보다 조금 더 나누는 것이 좋다.
OPEN
↓
INVESTIGATING
↓
MITIGATING
↓
MONITORING
↓
RESOLVED
예:
MITIGATING
Rollback 진행 중
MONITORING
복구는 됐지만 정상 상태 유지 여부 확인 중
이다.
예:
Worker 재시작
→ 정상
이라고 바로 Incident를 종료하면 안 된다.
5~10분 후 다시 멈출 수도 있다.
그래서:
MONITORING
상태를 두고 일정 시간 지표를 확인한다.
예:
주문 API
5분 동안 Error Rate < 1%
p95 < 2초
주문 생성 정상
조건이 만족되면:
RESOLVED
로 전환한다.
즉 복구 판단도 감이 아니라 Metric으로 한다.
Runbook은:
특정 운영 문제 발생 시 어떤 순서로 확인하고 조치할지 작성한 실행 절차
다.
예:
Notification Worker 장애 Runbook
이라면:
1. Queue Lag 확인
2. Worker 상태 확인
3. Provider 상태 확인
4. DB Connection 확인
5. Retry 상태 확인
6. Worker 재시작
7. Stale Job Reconciliation
8. 정상화 확인
형태다.
일반 문서:
Queue 시스템 설명
Runbook:
Queue가 멈췄을 때 실제로 뭘 해야 하는지
즉 Runbook은 실행 중심이다.
좋은 Runbook은:
짧고
구체적이고
순서가 있고
위험한 명령은 표시하고
Rollback 방법이 있고
완료 기준이 있다.
예:
# Notification Worker Recovery
## 증상
- Queue Lag 증가
- Notification Pending 증가
## 영향
고객 알림 지연
## 확인
1. Worker 상태
2. Queue 상태
3. Provider 상태
4. DB 연결
## 안전한 조치
1. Worker Restart
2. Stale Job Reconcile
## 위험한 조치
- 대량 Retry
- Queue Purge
## 정상화 기준
- Queue Lag < 30초
- Pending 감소
- 실패율 정상
## Rollback
N/A
예:
docker restart worker
같은 명령은 유용하다.
하지만:
DELETE FROM jobs;
같은 위험한 명령은 문서에 그대로 두면 사고가 날 수 있다.
위험 작업은:
MANUAL APPROVAL REQUIRED
를 명확하게 표시한다.
처음부터 완벽한 Runbook은 없다.
Incident를 겪으면:
이 단계는 필요 없었음
이 정보가 부족했음
새로운 확인 방법 발견
등이 생긴다.
그래서 Incident 이후 Runbook을 업데이트한다.
현재 프로젝트 기준으로는:
주문 생성 장애
Notification Worker 장애
Webhook 처리 장애
DB Connection 장애
배포 실패
Export Worker 장애
AI Automation 실패
정도가 우선순위가 높다.
증상
- 고객 신청 실패
- POST /orders Error 증가
확인
1. API Health
2. DB Health
3. Prisma Error
4. 최근 Deploy
5. Migration
6. External Dependency
Mitigation
- 최근 Deploy Rollback 검토
- 문제 기능 Feature Flag Off
- Traffic 제한
정상화
- 주문 생성 성공
- Error Rate 정상
- p95 정상
증상
Notification Failed 증가
확인
1. Provider 장애 여부
2. Queue Pending
3. Worker Health
4. Retry Rate
5. Rate Limit
조치
Provider 장애
→ Retry 속도 제한
Worker 장애
→ Worker Restart
Unknown Job
→ Reconciliation
정상화
Queue Lag 정상
Error Rate 정상
DB 문제는 위험도가 높다.
예:
Connection Pool Exhausted
Slow Query 급증
RDS CPU 증가
Lock 증가
Runbook:
1. RDS 상태 확인
2. Connection 수 확인
3. Slow Query 확인
4. 최근 Deploy 확인
5. Long Transaction 확인
6. 필요 시 Traffic 감소
바로 DB를 재시작하는 것은 최후 수단에 가깝다.
예:
배포 직후 Error Rate 증가
확인:
Release SHA
Health Check
최근 Migration
Environment Variable
Build Artifact
Error Logs
조치:
안전한 Rollback 가능
→ 이전 Release 복구
Migration 비호환
→ 별도 판단 필요
코드만 이전 버전으로 돌리면 되는 경우도 있지만:
DB Schema 변경
이 포함됐다면 단순 Rollback이 위험할 수 있다.
예:
새 Column 삭제
Column Rename
Data Migration
이런 변경은 이전 코드와 호환되지 않을 수 있다.
예:
1단계
새 Column 추가
2단계
새 코드 배포
3단계
데이터 Migration
4단계
이전 Column 제거
처럼 단계적으로 진행한다.
그러면 Rollback이 쉬워진다.
문제 기능을 코드 배포 없이 끌 수 있다면 유용하다.
예:
newOrderRecommendation = false
문제가 발생하면:
전체 서비스 Rollback
대신:
문제 기능만 Off
할 수 있다.
외부 자동화에는 Kill Switch가 유용하다.
예:
알림톡 자동 발송 전체 중단
Webhook 후속 Action 중단
AI Production Action 중단
문제가 발생하면 한 번에 차단할 수 있다.
비상시에 처음 써보면 위험하다.
정기적으로:
Staging
Test Environment
에서 동작 여부를 확인한다.
큰 조직에서는 장애 시 역할을 나눈다.
예:
Incident Commander
Investigator
Communicator
하지만 현재는 1인 개발자이므로 전부 나눌 수 없다.
그래도 역할을 개념적으로 분리하면 도움이 된다.
혼자 대응할 때는 순서를 정해두는 것이 좋다.
1. 고객 영향 확인
2. Severity 지정
3. 최근 Deploy 확인
4. Mitigation 우선
5. Timeline 기록
6. 원인 분석
7. 복구 확인
8. Postmortem
이 순서만 유지해도 혼란이 크게 줄어든다.
예:
Worker 재시작
DB 설정 변경
코드 수정
환경변수 변경
Queue Retry
를 동시에 하면 어느 변경이 문제를 해결했는지 모르게 된다.
가능하면:
한 단계
→ 결과 확인
→ 다음 단계
순서로 진행한다.
Incident 중 실행한 조치를 Timeline에 남긴다.
10:18
Worker restart
10:21
Queue Lag 15m → 3m
10:25
Queue 정상화
나중에 어떤 조치가 실제 효과가 있었는지 알 수 있다.
Postmortem은 Incident 종료 후:
무슨 일이 있었고
왜 발생했고
어떻게 복구했고
어떻게 재발을 막을지
정리하는 문서다.
단순 장애 보고서가 아니라 개선을 위한 문서다.
목적은:
누가 실수했는가?
를 찾는 것이 아니다.
더 중요한 질문은:
왜 이 실수가 실제 장애로 이어질 수 있었는가?
다.
예:
개발자가 환경변수를 잘못 입력함
으로 끝내면 개선이 없다.
더 깊게 보면:
환경변수 Validation이 없었음
배포 전 Check가 없었음
Staging과 Production 설정 차이를 확인하지 못함
이 문제다.
Postmortem은 책임 회피가 아니라:
재발 방지
를 위한 것이다.
따라서:
개발자가 실수함
보다:
배포 과정에 자동 Validation이 없어
잘못된 값이 Production까지 전달될 수 있었다.
라고 정리하는 편이 낫다.
1. Summary
2. Impact
3. Timeline
4. Detection
5. Root Cause
6. Contributing Factors
7. Mitigation
8. Resolution
9. What Went Well
10. What Went Poorly
11. Action Items
이 정도면 충분하다.
짧게 상황을 설명한다.
예:
2026-09-23 10:02부터 약 25분 동안
알림톡 Provider Timeout이 증가하면서
NotificationJob 처리가 지연되었다.
기술 설명보다 실제 영향을 쓴다.
예:
427건의 알림톡이 지연됨
중복 발송 없음
주문 생성 영향 없음
최종 실패 3건
이 정보가 중요하다.
어떻게 발견했는지 쓴다.
예:
Notification Failure Rate Alert로 감지
고객 문의보다 7분 먼저 발견
만약 고객 문의로 처음 발견했다면:
Monitoring 개선 필요
라는 Action Item이 생긴다.
근본 원인을 작성한다.
예:
외부 Provider의 API 응답 지연으로
Worker 요청이 Timeout되었다.
하지만 이것만으로 끝내지 않는다.
장애를 더 크게 만든 요인을 본다.
예:
Retry 간격이 너무 짧았음
Rate Limit 고려 부족
Provider 상태 조회 기능 없음
UNKNOWN 상태 처리 미흡
이런 요인들이 실제 개선 포인트다.
근본 원인을 찾을 때 사용할 수 있다.
예:
왜 알림톡이 지연됐나?
Provider Timeout 때문에
왜 Queue가 급격히 쌓였나?
Worker가 계속 Retry했기 때문
왜 Retry가 계속 발생했나?
Backoff가 없었기 때문
왜 Backoff가 없었나?
Retry 정책이 단순했기 때문
이런 식으로 내려간다.
5 Whys는 사고 도구일 뿐이다.
항상 정확히 5번 질문할 필요는 없다.
실제 원인이 명확해지면 멈춘다.
장애 중 잘 작동한 것도 기록한다.
예:
Alert가 빠르게 발생함
Correlation ID로 관련 로그를 빠르게 찾음
중복 발송 방지 Idempotency 정상 작동
Reconciliation으로 UNKNOWN 복구
이런 내용은 기존 설계가 효과 있었는지 확인하는 데 중요하다.
예:
Provider 상태 페이지 확인이 늦었음
Runbook 부족
Retry 폭주
Dashboard에서 Queue Lag 확인 어려움
등을 적는다.
Postmortem에서 가장 중요한 부분이다.
다음 장애에서 같은 문제가 반복되지 않도록
실제 작업을 만든다.
예:
Retry Backoff 추가
Provider Health Check 추가
Queue Lag Alert 추가
Runbook 작성
Reconciliation 개선
나쁜 예:
모니터링 개선
좋은 예:
Notification Queue Oldest Job Age가
5분을 초과하면 Warning Alert 생성
이다.
예:
P0
Retry 폭주 방지
P1
Provider Health Check
P1
Queue Alert
P2
Dashboard 개선
모든 Action을 같은 우선순위로 처리하면 실제로 아무것도 안 끝날 수 있다.
P3 수준의 작은 오류까지 매번 문서를 쓰면 부담이 크다.
예:
P0
필수
P1
필수
P2
반복 장애면 작성
P3
필요 시
정도로 운영하면 된다.
예:
매주 Excel Export가 한 번씩 실패
개별 Incident는 P3여도 반복된다면 구조적 문제일 수 있다.
따라서:
Frequency
도 중요하다.
비슷한 Error를 묶기 위해 Fingerprint를 사용할 수 있다.
예:
service
+
errorCode
+
endpoint
+
provider
조합으로:
notification:
PROVIDER_TIMEOUT:
kakao
같은 형태를 만든다.
Alert가 여러 개 들어와도 같은 장애라면 Incident 하나로 묶어야 한다.
예:
Notification Error Rate Alert
Queue Lag Alert
Provider Timeout Alert
세 개가 동시에 발생해도 실제 원인이 하나일 수 있다.
Incident Fingerprint나 Correlation 정보를 이용해 묶는다.
예:
Incident INC-102
├─ Alert 1
│ Notification Error Rate
│
├─ Alert 2
│ Queue Lag
│
└─ Alert 3
Provider Timeout
이렇게 보면 장애 전체를 한 사건으로 관리할 수 있다.
Incident Record에:
releaseId
를 넣을 수도 있다.
예:
INC-102
Started
10:12
Latest Release
release_20260923_3
Deployed
10:04
최근 배포와 시점을 비교하기 쉽다.
모든 실패 요청을 저장할 필요는 없고 대표 Correlation ID를 몇 개 연결할 수 있다.
예:
sampleCorrelationIds:
cor_921
cor_944
cor_982
그러면 실제 실패 요청을 빠르게 재구성할 수 있다.
관리자에 다음 정도를 만들 수 있다.
| Incident | Severity | 상태 | 시작 | 영향 |
|---|---|---|---|---|
| INC-101 | P1 | RESOLVED | 10:02 | 알림톡 지연 |
| INC-102 | P2 | MONITORING | 14:32 | Export 실패 |
| INC-103 | P3 | OPEN | 15:10 | 통계 지연 |
복잡한 시스템이 아니어도 운영 가시성이 크게 좋아진다.
예:
INC-101
Severity
P1
Status
RESOLVED
Duration
35분
Impact
알림톡 427건 지연
Timeline
Alerts
Related Release
Sample Correlations
Root Cause
Action Items
이 정도면 충분하다.
운영 지표 중 하나다.
Mean Time To Acknowledge
즉:
장애 발생
→ 사람이 인지
까지 걸린 시간이다.
Mean Time To Detect
장애 발생
→ 시스템이 감지
까지의 시간이다.
Observability 개선과 연결된다.
0917에서도 언급한 지표다.
Mean Time To Recovery
장애 발생
→ 서비스 복구
까지 걸린 시간이다.
좋은 운영 시스템은:
장애를 절대 안 만드는 것
보다:
빠르게 감지
빠르게 영향 축소
빠르게 복구
같은 장애 재발 방지
에 가깝다.
0922의 Error Budget을 Incident 우선순위에도 사용할 수 있다.
예:
Error Budget 급격히 소진
하면:
신규 기능 개발 잠시 중단
안정화 작업 우선
결정을 내릴 수 있다.
예:
INC-101
Error Budget Consumed
17%
그러면 어떤 장애가 서비스 신뢰성을 가장 많이 떨어뜨렸는지 알 수 있다.
한 번의 큰 장애보다:
매일 1% 실패
가 더 심각할 수 있다.
그래서 Incident 개수뿐만 아니라:
Error Budget Consumption
을 보는 것이다.
AI에게 처음부터:
장애를 알아서 고쳐
라고 하지 않는다.
우선:
로그 요약
Timeline 생성
관련 Correlation 탐색
최근 Deploy 비교
Top Error 분석
Runbook 추천
등 Read-Only 분석을 맡긴다.
예를 들어:
Incident 발생
↓
AI가 관련 로그 조회
↓
최근 Deploy 확인
↓
Metric 요약
↓
가능한 원인 후보 정리
↓
관련 Runbook 제안
형태다.
실제 조치는 사람이 승인한다.
예:
Incident:
Notification Failure Spike
Started:
10:02
Detected:
10:04
Affected:
427 jobs
Top Error:
PROVIDER_TIMEOUT
Latest Deploy:
No deployment in last 6h
Provider Status:
Degraded
Recommendation:
Provider recovery까지 Retry Backoff 확대
운영자가 판단하기 훨씬 편하다.
AI 분석은:
가능성이 높은 원인
정도로 제시해야 한다.
예:
최근 배포 이후 오류가 증가했으므로
해당 배포와의 연관 가능성이 있습니다.
정도로 본다.
단순 시간적 연관만으로:
이 배포가 원인입니다.
라고 단정하면 위험하다.
AI가 Error Code를 보고:
DATABASE_CONNECTION_EXHAUSTED
라면:
database-connection-exhausted.md
Runbook을 추천할 수 있다.
이 방식은 AI가 새 복구 방법을 임의로 만드는 것보다 안전하다.
예:
{
errorCode:
'DATABASE_CONNECTION_EXHAUSTED',
runbook:
'database-connection.md',
severity:
'P1'
}
같은 Mapping을 둘 수도 있다.
초기:
Runbook 추천
다음:
안전한 Read-Only Step 자동 실행
그 이후:
Safe Repair 자동 실행
순서가 좋다.
일부 장애는 자동 조치가 가능하다.
예:
Worker Heartbeat 없음
→ Worker Restart
Stale Job
→ Reconciliation
하지만 반드시:
재실행 안전성
Idempotency
Action 제한
Audit Log
이 있어야 한다.
자동 복구가 실패하면:
재시도 무한 반복
이 아니라:
MANUAL_REQUIRED
상태로 전환한다.
예:
Worker Restart 자동화가
10분 동안 5회 반복
되면 자체적으로 이상이다.
이 경우:
Auto Recovery Loop Detected
같은 Incident를 생성할 수 있다.
장애 상황에서 여러 Worker가 동시에 Retry하면 오히려 장애가 악화될 수 있다.
예:
Provider 장애
↓
10,000 Job 실패
↓
모두 1초 후 Retry
↓
Provider에 10,000 요청 재전송
이를 Retry Storm이라고 볼 수 있다.
0916 내용과 연결해서:
Exponential Backoff
Jitter
Retry Budget
Concurrency Limit
Circuit Breaker
등이 필요하다.
외부 서비스가 계속 실패하는데 계속 요청을 보내는 것은 비효율적이다.
Circuit Breaker는:
실패율 증가
↓
Circuit OPEN
↓
일시적으로 요청 차단
↓
일정 시간 후 일부 요청 테스트
↓
정상
Circuit CLOSED
형태로 동작한다.
Provider 장애 상황에서:
Retry Storm
을 줄일 수 있다.
예:
Kakao Provider 실패율 > 70%
→ 새 발송 일시 중단
→ Queue에 보관
→ Provider 정상화 후 처리
짧은 일시 오류 때문에 너무 쉽게 Circuit을 열면 정상 요청까지 막을 수 있다.
따라서:
Failure Threshold
Minimum Request Count
Open Duration
같은 기준이 필요하다.
완전 장애보다 일부 기능만 제한하고 핵심 기능을 유지하는 방법도 있다.
예:
알림톡 Provider 장애
라도:
주문 생성
까지 막을 필요는 없다.
주문은 정상 접수하고:
알림톡은 Queue에 보관
할 수 있다.
핵심 서비스는 유지하면서 부가 기능을 제한하는 방식이다.
예:
AI 상품 추천 장애
→ 추천 기능만 숨김
주문 기능은 유지
통계 API 장애
→ 관리자 Dashboard 일부 비활성화
주문 관리 유지
한 기능의 장애가 전체 서비스로 번지지 않게 해야 한다.
예:
알림톡 Provider Timeout
↓
HTTP Request가 Provider 응답 기다림
↓
주문 API도 느려짐
이런 구조는 좋지 않다.
주문 생성과 알림톡을 분리하면:
주문 저장
↓
Transaction 완료
↓
Queue
↓
알림톡
Provider 장애가 주문 기능까지 영향을 주지 않는다.
지금까지 다룬 Queue/Worker 구조가 이런 장애 격리에도 도움이 된다.
기능별로 Resource를 분리하는 개념이다.
예:
Notification Worker
Export Worker
AI Worker
를 나누면 Export가 폭주해도 Notification 처리 자원을 모두 빼앗지 않는다.
처음부터:
Service Mesh
Multi Region
Chaos Engineering
완전한 SRE Platform
까지 갈 필요는 없다.
현재 규모에서는:
Severity
Runbook
Incident Timeline
Rollback
Postmortem
Action Item
이 정도만 체계화해도 운영 수준이 많이 올라간다.
예:
/docs/
/runbooks/
/incidents/
/postmortems/
Incident 문서:
2026-09-23-notification-provider-timeout.md
처럼 관리할 수 있다.
현재 자동 보고서에도 Incident를 포함할 수 있다.
예:
### 운영 Incident
INC-20260923-001
알림톡 Provider 지연
Severity
P1
Duration
35분
영향
427건 지연
복구
Provider 정상화 후 Queue 재처리
Action
Retry Backoff 개선
이렇게 하면 하루 작업 성과와 운영 대응이 함께 남는다.
장애 수정 Commit에:
fix(notification): add provider timeout backoff
Incident: INC-20260923-001
같이 연결할 수도 있다.
나중에:
이 수정이 어떤 Incident 때문에 들어갔는가?
를 쉽게 찾을 수 있다.
Postmortem 작성 후 끝내지 않고:
Action Item
→ GitHub Issue
로 생성한다.
예:
[P1] Notification Provider Circuit Breaker 추가
[P1] Queue Lag Alert 추가
[P2] Incident Dashboard 개선
실제 실행 가능한 작업이 된다.
Postmortem에:
Action Item 5개
만 적어두고 끝내면 의미가 없다.
TODO
IN PROGRESS
DONE
상태를 관리한다.
예를 들어 월 1회:
이번 달 Incident
P0
0건
P1
2건
P2
7건
을 보고:
가장 많이 발생한 유형
Error Budget 소비가 큰 장애
재발한 장애
미완료 Action Item
을 확인한다.
예:
이번 달
Incidents
9
P0
0
P1
2
MTTD
3분
MTTR
18분
Repeat Incident
1
Postmortem Action Completion
80%
운영 품질이 실제로 개선되고 있는지 확인할 수 있다.
현재 NestJS + Prisma 기반 관리자 시스템에
간단한 Incident Management 구조를 추가해줘.
현재는 1인 개발자가 운영하는 서비스이므로
대형 SRE 플랫폼처럼 복잡하게 만들지 말고,
운영 장애를 기록하고 추적할 수 있는
최소한의 구조를 목표로 한다.
요구사항:
1. Incident 모델을 만든다.
필드:
- id
- title
- severity
- status
- summary
- impact
- startedAt
- detectedAt
- mitigatedAt
- resolvedAt
- rootCause
- createdAt
- updatedAt
2. severity는 다음을 지원한다.
- P0
- P1
- P2
- P3
3. status는 다음을 지원한다.
- OPEN
- INVESTIGATING
- MITIGATING
- MONITORING
- RESOLVED
4. IncidentTimeline 모델을 만든다.
필드:
- incidentId
- timestamp
- type
- message
- actorType
- actorId(optional)
5. Incident에 관련 정보를 연결할 수 있게 한다.
예:
- releaseId
- correlationId
- alertId
- jobId
단 필요하다면 별도 relation table 또는 metadata를 활용한다.
6. Incident 생성/수정/종료 Use Case를 분리한다.
7. Incident 종료 전 MONITORING 상태를 지원한다.
8. Incident에 Postmortem 정보를 추가할 수 있게 한다.
항목:
- rootCause
- contributingFactors
- whatWentWell
- whatWentPoorly
9. ActionItem 모델을 만든다.
필드:
- incidentId
- title
- priority
- status
- owner
- dueDate(optional)
10. Action Item 상태:
- TODO
- IN_PROGRESS
- DONE
11. 관리자 화면에서 다음을 제공한다.
Incident List
필터:
- severity
- status
- 기간
Incident Detail:
- Summary
- Impact
- Timeline
- Related Release
- Related Correlation
- Root Cause
- Action Items
12. Incident 생성 시
현재 최근 Release 정보를 연결할 수 있는 구조를 만든다.
13. Alert에서 Incident를 생성할 수 있도록
Alert ID 또는 Alert metadata 연결 구조를 만든다.
14. 같은 원인의 Alert 여러 개가
하나의 Incident에 연결될 수 있도록 한다.
15. Incident에 개인정보를 직접 저장하지 않는다.
16. 변경 사항은 Audit Log에 기록한다.
17. 주요 테스트를 작성한다.
- Incident 생성
- Severity 변경
- 상태 전환
- Timeline 추가
- RESOLVED 전환
- Action Item 생성
- Incident/Alert 연결
현재 프로젝트의 운영 구조를 분석해서
다음 장애 상황별 Runbook 초안을 작성해줘.
1. 주문 생성 API 장애
2. Notification Worker 장애
3. Webhook 처리 실패
4. PostgreSQL Connection 문제
5. Production 배포 실패
6. Export Worker 장애
각 Runbook은 다음 구조를 사용한다.
# 제목
## 증상
## 고객/운영 영향
## 확인 순서
## 안전한 조치
## 위험한 조치
## Rollback 방법
## 정상화 확인 기준
## 관련 로그 / Metric
## 관련 Error Code
실제 코드와 설정에서 확인 가능한 내용만 사용하고,
존재하지 않는 명령이나 Infrastructure를 추정해서 만들지 않는다.
특히 Production DB 삭제, Queue Purge,
대량 Retry 같은 위험 작업은
자동 실행 단계에 넣지 말고
MANUAL APPROVAL REQUIRED로 표시한다.
# Incident Postmortem
Incident ID:
Severity:
Date:
Duration:
## 1. Summary
## 2. Impact
- 고객 영향:
- 운영 영향:
- 데이터 영향:
## 3. Detection
- 최초 감지:
- 감지 방법:
## 4. Timeline
## 5. Root Cause
## 6. Contributing Factors
## 7. Mitigation
## 8. Resolution
## 9. What Went Well
## 10. What Went Poorly
## 11. Action Items
| Priority | Action | Status |
|---|---|---|
| P1 | | TODO |
0921에서:
Observability
를 만들고,
0922에서:
SLI
SLO
Error Budget
으로 정상 기준을 정했다.
0923에서는 그 기준을 넘었을 때 실제로:
어떻게 장애를 대응할 것인가?
를 다뤘다.
전체 Incident 흐름은:
Detect
↓
Triage
↓
Mitigate
↓
Diagnose
↓
Resolve
↓
Monitor
↓
Postmortem
으로 보면 된다.
가장 중요한 것은 장애가 발생했을 때 곧바로:
Root Cause 찾기
에만 몰두하지 않는 것이다.
먼저:
고객 영향 줄이기
가 우선이다.
즉:
Mitigation
→ Resolution
순서가 될 수 있다.
Severity 역시:
CPU가 몇 %인가
보다:
고객이 신청 가능한가?
주문이 저장되는가?
데이터가 손실되는가?
매출에 영향이 있는가?
를 중심으로 판단해야 한다.
그리고 반복되는 장애 대응을 기억에 의존하지 않도록:
Runbook
으로 만든다.
Incident 종료 후에는:
누가 잘못했는가?
가 아니라:
왜 이 문제가 실제 장애까지 이어질 수 있었는가?
를 분석한다.
이를 위해:
Postmortem
을 작성하고 반드시:
Action Item
으로 연결한다.
AI 자동화는 장애 대응에서도 처음부터 복구 권한을 주는 것이 아니라:
로그 분석
↓
Timeline 생성
↓
원인 후보
↓
Runbook 추천
↓
Human Approval
↓
실행
순서로 접근하는 것이 안전하다.
지금까지의 운영 자동화 흐름을 연결하면:
Observe
↓
Measure
↓
SLO
↓
Alert
↓
Incident
↓
Mitigate
↓
Reconcile
↓
Recover
↓
Postmortem
↓
Improve
가 된다.
결국 Incident Management의 핵심은
장애를 없애는 것이 아니라, 장애가 발생해도 당황하지 않고 같은 절차로 빠르게 영향 범위를 줄이고, 복구하고, 다음에는 같은 문제가 덜 발생하도록 시스템을 개선하는 것
이다.