이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.
- 장애 상황에서 좋은 가설은 어떤 형식을 가져야 하는가?
- 최근 배포, DNS, TLS, WAF, 외부 API 중 무엇을 먼저 의심할지 어떻게 정하는가?
- “네트워크 문제”라는 모호한 말을 검증 가능한 문장으로 어떻게 바꾸는가?
개요
장애 대응은 원인을 맞히는 퀴즈가 아니다. 틀린 가설을 빠르게 제거해서 남은 가능성을 좁히는 과정이다. 좋은 가설은 “어디가 문제 같다”에서 끝나지 않고, 어떤 증거로 확인할지와 결과에 따라 무엇을 할지를 포함한다.
나쁜 가설은 넓고 검증하기 어렵다.
네트워크 문제 같습니다.
서버가 느린 것 같습니다.
Azure 문제 같습니다.
프론트 문제 같습니다.좋은 가설은 계층과 증거를 가진다.
Gateway가 backend target을 unhealthy로 보고 즉시 502를 반환하는 것 같다.
curl timing에서 first byte가 0.1초 이내이고 app access log가 없으므로 Gateway backend health와 probe 설정을 확인한다.왜 백엔드 개발자가 알아야 하는가
백엔드 개발자는 장애 상황에서 앱 코드만 보는 사람이 아니다. 요청이 앱까지 오지 않았는지, 앱 안에서 실패했는지, 앱이 호출한 후단 의존성에서 실패했는지 좁히는 사람이다.
가설을 제대로 세우면 인프라팀, 프론트엔드팀, 보안팀, 외부 API 담당자와의 대화가 빨라진다. 반대로 모호한 가설은 각 팀이 자기 영역을 따로 뒤지게 만들고 시간을 잃게 한다.
요청 흐름에서의 위치
장애 가설은 모든 계층을 대상으로 한다.
증상 수집
→ 영향 범위 분리
→ 요청이 도달한 마지막 계층 확인
→ 최근 변경과 시간대 비교
→ 가장 가능성 높은 가설부터 검증
→ 완화와 근본 수정 분리이 문서는 개별 프로토콜 지식보다 “어떤 순서로 생각할지”를 다룬다.
원리
좋은 장애 가설은 다섯 요소를 가진다.
| 요소 | 질문 | 예시 |
|---|---|---|
| 계층 | 어디에서 실패한다고 보는가? | LB to backend |
| 증상 | 사용자는 무엇을 보는가? | 502가 0.1초 이내 반환 |
| 증거 | 무엇을 확인했는가? | DNS/TLS 정상, app log 없음 |
| 검증 | 무엇을 보면 맞거나 틀린가? | target health reason, probe log |
| 다음 행동 | 맞으면 무엇을 할 것인가? | backend port/protocol/probe rollback |
이 형식으로 쓰면 “누가 맞다/틀리다”가 아니라 “어떤 증거를 더 볼 것인가”로 대화가 바뀐다.
영향 범위부터 나누기
원인 후보는 영향 범위에 따라 크게 달라진다.
| 영향 범위 | 먼저 의심할 것 |
|---|---|
| 모든 사용자, 모든 API | DNS, CDN, LB, 배포, DB 공통 장애 |
| 특정 API만 | route, controller, DB query, 외부 API, proxy path rewrite |
| 특정 사용자만 | 권한, 계정 상태, 쿠키, 세션, WAF/IP 정책 |
| 특정 지역만 | CDN edge, DNS resolver, regional LB, cloud region |
| 브라우저만 | CORS, Cookie, SameSite, cache, CSP |
| 모바일 앱만 | 네트워크 전환, 앱 retry, 버전 호환, DNS cache |
| 배포 직후 | readiness, migration, config, target draining |
영향 범위를 나누지 않으면 모든 계층을 동시에 의심하게 된다.
실무에서 자주 만나는 문제
- 가장 최근 배포만 보고 다른 변경을 놓친다.
- DNS, 인증서, WAF rule, LB listener, secret rotation도 배포만큼 강한 변경이다.
- 장애 시작 시각과 모든 변경 이력을 한 timeline에 둔다.
- 한 번 성공한 요청으로 간헐적 장애를 배제한다.
- pool 고갈, stale connection, 특정 target 장애는 간헐적으로 나타난다.
- 여러 번, 여러 region, 여러 target 기준으로 확인한다.
- 5xx만 보고 서버 코드를 먼저 본다.
- Gateway나 proxy가 만든 5xx는 app log가 없을 수 있다.
- 응답 주체와 app log 도달 여부를 먼저 확인한다.
- 장애 완화와 근본 수정을 섞는다.
- scale out, rollback, WAF rule disable은 완화일 수 있다.
- root cause와 재발 방지는 별도 action item으로 남긴다.
디버깅 방법
가설을 세울 때는 아래 템플릿을 사용한다.
가설:
영향 범위:
요청 경로에서 의심 계층:
이미 확인한 정상 계층:
아직 확인하지 못한 계층:
검증 명령 또는 로그:
맞을 때의 다음 행동:
틀릴 때의 다음 가설:예시:
가설:
WAF가 특정 요청 body를 차단해 403을 반환한다.
영향 범위:
로그인은 정상, 주문 생성 POST만 실패.
의심 계층:
CDN/WAF.
이미 확인:
DNS, TCP, TLS 정상. GET /orders는 200.
검증:
같은 request id와 source IP로 WAF deny log를 조회한다.
맞을 때:
rule id 확인 후 예외 조건 또는 payload 수정 검토.
틀릴 때:
API Gateway route와 application authz log 확인.코드로 확인하기
장애 보고나 회고에 바로 붙일 수 있는 최소 timeline 형식은 다음과 같다.
09:58 배포 시작
10:03 first 502 alert
10:05 user report: POST /api/orders only
10:08 curl -w: dns/connect/tls 정상, first_byte 0.05s
10:10 LB log: target_status_code="-", elb_status_code=502
10:12 target health: unhealthy, reason=Health checks failed
10:15 rollback health check path
10:18 5xx 정상화이 timeline에서 핵심은 “증상 → 외부 확인 → 내부 로그 → 조치 → 회복”의 연결이다. 단순히 “10:15 조치함”만 남기면 다음 장애에서 재사용할 수 없다.
주니어가 자주 하는 오해
- 원인을 빨리 말하는 것이 좋은 대응이라고 생각한다.
- 좋은 대응은 확인한 사실과 아직 모르는 것을 분리하는 것이다.
- 전체 장애와 일부 장애를 나누지 않는다.
- 영향 범위를 나누지 않으면 불필요한 계층까지 모두 확인하게 된다.
- “최근에 바꾼 게 없다”는 말을 믿고 변경 이력을 보지 않는다.
- 인증서 자동 갱신, DNS 변경, 보안 정책, 외부 API 변경은 코드 배포가 아니어도 장애 원인이다.
- 완화 조치가 끝나면 장애가 끝났다고 생각한다.
- 사용자 영향은 끝났어도 재발 방지와 관측 개선이 남아 있다.
시니어의 설계 판단 기준
- 장애 초기에 추측보다 영향 범위, 응답 주체, request id, 최근 변경을 먼저 모은다.
- 가설은 검증 비용이 낮고 영향 범위를 크게 줄이는 순서로 세운다.
- rollback 가능한 변경과 즉시 rollback이 어려운 변경을 구분한다.
- 완화 조치가 downstream에 추가 부하를 주지 않는지 확인한다.
- 회고에는 틀린 가설도 남긴다. 다음 장애에서 같은 길을 다시 걷지 않기 위해서다.
인프라 협업 포인트
- 인프라팀에 요청할 때는 가설과 확인 요청을 분리한다.
- 나쁜 예: “LB 문제 같은데 봐주세요.”
- 좋은 예: “App log에 요청이 없고 ALB 502가 0.05초에 반환됩니다. target health reason과 listener rule 변경 이력을 확인 부탁드립니다.”
- WAF, DNS, TLS, LB 변경은 보안과 전파 시간 때문에 즉시 토글처럼 처리되지 않을 수 있다.
- 장애 중에는 증거 수집과 완화 조치를 병행하되, 모든 임시 변경은 나중에 되돌릴 수 있게 기록한다.
실전 팁
- “어디까지 정상인가”를 먼저 말하면 팀 간 방어적 대화가 줄어든다.
- 장애 가설은 2-3개를 동시에 열어두되, 검증 순서는 정한다.
- 가설이 틀렸다면 부끄러운 것이 아니라 후보가 줄어든 것이다.
- 사용자 영향이 큰 장애에서는 원인 분석보다 완화가 먼저일 수 있다.
- 개인 프로젝트에서도 장애 노트를 timeline 형식으로 남기면 운영 감각이 빨리 쌓인다.
위험 신호!
- 장애방에 “아마”와 “같아요”만 있고 확인 명령이 없다.
- 영향 범위가 정리되기 전에 모든 팀을 호출한다.
- rollback 후보와 검증 방법이 없다.
- 한 번 성공한 curl로 장애 해소를 선언한다.
- 회고에서 “네트워크 이슈”라고만 적고 계층과 증거를 남기지 않는다.
확인 질문
확인 질문
- 좋은 장애 가설에 포함되어야 하는 다섯 요소는 무엇인가?
- 계층, 증상, 증거, 검증 방법, 다음 행동이다.
- 영향 범위를 먼저 나누는 이유는 무엇인가?
- 전체 장애인지 일부 사용자/일부 API/특정 환경 문제인지에 따라 의심 계층이 크게 달라지기 때문이다.
- 완화와 근본 수정을 분리해야 하는 이유는 무엇인가?
- 완화는 사용자 영향을 줄이는 조치이고, 근본 수정은 같은 장애가 다시 나지 않게 하는 조치이기 때문이다.