이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.
- 장애 초기에 DNS, TCP, TLS, HTTP, Edge, LB, App, DB 중 어디부터 확인해야 하는가?
- App log에 요청이 없을 때 “정상”이 아니라 “미도달”로 판단하려면 어떤 증거가 필요한가?
- 인프라 담당자에게 추측이 아니라 확인 요청으로 전달하려면 어떤 형식이 좋은가?
개요
네트워크 장애 대응의 핵심은 원인을 맞히는 것이 아니라 가능한 원인을 빠르게 줄이는 것이다. 이를 위해 요청 경로를 계층으로 나누고, 각 계층에서 “정상이라는 증거”와 “실패했다는 증거”를 모은다.
좋은 대응은 “네트워크 문제 같습니다”라고 말하지 않는다. 대신 “DNS와 공개 TLS는 정상이고, Gateway가 0.05초 안에 502를 반환하며, app access log에는 request id가 없습니다. Gateway backend health와 probe 설정을 확인해야 합니다”처럼 말한다.
왜 백엔드 개발자가 알아야 하는가
백엔드 개발자는 애플리케이션 로그만 보는 사람이 아니다. 운영 장애에서는 요청이 앱에 도달하지 못한 경우도 많고, 앱이 받은 뒤 DB/캐시/외부 API에서 지연되는 경우도 많다.
- WAF가 막은 403은 app controller까지 오지 않는다.
- CDN cache HIT은 origin app log를 남기지 않을 수 있다.
- LB가 no healthy target으로 503을 만들면 앱 코드는 실행되지 않는다.
- proxy가 upstream timeout으로 504를 만들면 앱은 계속 처리 중일 수 있다.
- app log에는 성공이지만 브라우저는 CORS나 cookie 정책으로 실패할 수 있다.
계층별 사고가 없으면 팀 간 대화가 방어적으로 흐른다. “우리 로그에는 없어요”보다 “어느 계층 로그까지 있는지 같이 좁혀야 합니다”가 훨씬 낫다.
요청 흐름에서의 위치
장애 진단은 전체 요청 경로를 따라 진행한다.
Client
→ DNS
→ TCP
→ TLS
→ HTTP
→ CDN / WAF
→ Load Balancer / Gateway
→ Reverse Proxy
→ Application
→ DB / Cache / Queue / External API항상 아래에서 위로만 확인해야 하는 것은 아니다. 다만 어떤 계층을 확인했고 어떤 계층은 아직 모르는지 명확히 표시해야 한다.
원리
각 계층은 확인 도구와 증거가 다르다.
| 계층 | 외부에서 볼 증거 | 내부에서 볼 증거 | 자주 틀리는 판단 |
|---|---|---|---|
| DNS | dig, nslookup, TTL | authoritative DNS, private DNS | 예전 IP cache를 무시 |
| TCP | nc, curl connect time | firewall, security group, listener | ping 성공을 TCP 성공으로 착각 |
| TLS | openssl s_client, browser cert | cert chain, SNI, backend TLS | public TLS만 보고 backend TLS를 놓침 |
| HTTP | status, header, body, redirect | access log, route log | status code를 원인으로 확정 |
| CDN/WAF | Server, X-Cache, WAF page | edge log, rule id, cache key | app 권한 오류와 WAF 차단 혼동 |
| LB/Gateway | 502/503/504, target hint | target health, listener rule | cloud provider 전체 장애로 단정 |
| Proxy | NGINX/Envoy status hint | upstream status/time, error log | proxy 502를 app 500으로 오해 |
| App | request id, app error body | app access/error log, trace | app log 없음이면 문제 없음으로 봄 |
| DB/API | first byte 지연 | slow query, pool, external span | 네트워크 지연과 후단 처리 지연 혼동 |
진단은 “가장 가까운 단서”에서 시작한다. 사용자에게 보이는 status와 header를 보고 응답 주체를 추정한 뒤, 그 주체의 앞뒤 계층을 확인한다.
장애 초반 10분 절차
장애 초반에는 깊은 원인 분석보다 영향 범위와 응답 주체가 먼저다.
1. 발생 시각과 영향 범위 수집
2. URL, method, status, response header, request id 확보
3. 외부에서 DNS/TCP/TLS/HTTP 확인
4. 응답 주체와 마지막 관찰 계층 확인
5. 같은 시간대 CDN/LB/proxy/app log 존재 여부 확인
6. 최근 변경을 배포, DNS, TLS, WAF, LB, config, dependency로 나누어 정렬
7. 완화 후보와 추가 확인 항목 분리이 절차는 빠른 책임 분배가 아니라 빠른 증거 수집을 위한 것이다.
실무에서 자주 만나는 문제
- App log가 없는데 앱 예외부터 찾는다.
- 요청이 app에 도달하지 못했거나 app 앞단에서 응답이 끝났을 수 있다.
- CDN/WAF/LB/proxy 로그에서 request id나 client IP를 먼저 찾는다.
- 최근 코드 배포만 변경으로 본다.
- DNS, 인증서, WAF rule, LB listener, target health check, secret rotation도 변경이다.
- 장애 시작 시각과 모든 변경을 한 timeline에 둔다.
- 한 번 성공한 curl로 간헐 장애를 배제한다.
- stale connection, 일부 target 장애, pool 고갈, 특정 region 장애는 간헐적으로 보인다.
- 여러 번, 여러 region, 여러 endpoint, 여러 target 기준으로 확인한다.
- client가 제공한 screenshot만으로 판단한다.
- screenshot에는 URL, request id, header, timing이 없을 수 있다.
- DevTools HAR, response header, 발생 시각을 요청한다.
디버깅 방법
기본 CLI 확인은 아래 순서로 한다.
dig example.com A
dig example.com AAAA
nc -vz example.com 443
openssl s_client -connect example.com:443 -servername example.com </dev/null
curl -vI https://example.com/api/health
curl -sS -o /dev/null \
-w "code=%{http_code}\nremote_ip=%{remote_ip}\ndns=%{time_namelookup}\nconnect=%{time_connect}\ntls=%{time_appconnect}\nfirst_byte=%{time_starttransfer}\ntotal=%{time_total}\n" \
https://example.com/api/health이 결과를 내부 로그와 연결한다.
CDN/WAF log
→ LB/Gateway access log
→ Proxy access/error log
→ Application access/error log
→ APM trace
→ DB/API dependency metric어느 계층에서 request id가 사라지는지 찾으면 다음 확인 대상이 줄어든다.
코드로 확인하기
장애 보고 템플릿은 추측보다 증거를 먼저 두어야 한다.
증상:
발생 시각:
영향 범위:
URL / Method:
Status / Response Header:
Request ID / Trace ID:
curl timing:
브라우저 DevTools:
외부 네트워크 재현:
마지막으로 관찰된 계층:
확인한 정상 계층:
아직 확인하지 못한 계층:
최근 변경:
완화 후보:이 템플릿이 있으면 인프라 팀에 “LB 문제 같습니다”가 아니라 “LB 로그에서 target status와 health reason을 확인해야 합니다”라고 요청할 수 있다.
주니어가 자주 하는 오해
- status code를 원인으로 확정한다.
- status code는 라우팅 정보다. 응답 주체와 로그 위치가 필요하다.
- App log에 없으면 백엔드 책임이 아니라고 생각한다.
- 백엔드 서비스 경계에는 proxy, LB, health check, TLS, WAF 협업이 포함된다.
- ping과 브라우저 접속을 같은 확인으로 본다.
- ping은 HTTP/TLS/proxy/app 상태를 보여 주지 않는다.
- 장애 중에 원인을 빨리 말하는 것이 좋다고 생각한다.
- 확인한 사실과 가설을 분리하는 것이 더 중요하다.
시니어의 설계 판단 기준
- 장애 전에 계층별 로그 접근 권한과 request id 전파를 준비한다.
- 모든 ingress 경로에 응답 주체, upstream status, request time을 남긴다.
- 장애 초반에는 영향 범위와 완화 가능성을 root cause보다 먼저 본다.
- rare case를 없애려 하기보다 감지, 격리, 완화, 회고 루프를 만든다.
- runbook에는 정상 예시와 실패 예시를 같이 둔다.
인프라 협업 포인트
- DNS 변경은 record, TTL, propagation, rollback 값을 함께 이야기한다.
- LB/Gateway 확인에는 listener, rule, target group, target health reason, backend port/protocol이 필요하다.
- WAF 확인에는 source IP, path, method, request id, rule id, 차단 시각이 필요하다.
- Proxy 확인에는 upstream host, upstream status, upstream response time, rewrite 후 path가 필요하다.
- 인프라 담당자는 모든 계층 로그를 즉시 볼 수 있는 것이 아니다. 필요한 시간 범위와 식별자를 정확히 주는 것이 큰 도움이다.
실전 팁
- 장애방 첫 메시지는 “영향 범위, 응답 주체, request id, 최근 변경” 네 가지를 포함한다.
- 모르는 것은 모른다고 표시한다. “App log 확인 전”과 “App log 없음 확인”은 다르다.
- 개인 프로젝트에서도 NGINX access log와 app log에 같은 request id를 남겨 두면 장애 대응 품질이 달라진다.
- 장애 종료 후에는 틀린 가설도 기록한다. 다음 장애에서 같은 경로를 줄일 수 있다.
위험 신호!
- 장애 보고가 screenshot 하나로 시작하고 request id가 없다.
- CDN/LB/proxy 로그를 볼 권한이나 요청 절차가 없다.
- “네트워크 문제”라는 말만 있고 확인한 계층이 없다.
- 최근 변경 목록에 코드 배포만 있고 DNS/TLS/WAF/LB/config가 없다.
- app log와 proxy log의 시간대가 달라 timeline을 만들 수 없다.
확인 질문
확인 질문
- App log에 요청이 없으면 어떤 계층을 먼저 확인해야 하는가?
- CDN/WAF, LB/Gateway, Reverse Proxy 로그에서 request id, client IP, path가 있는지 확인해야 한다.
- 장애 초반에 root cause보다 먼저 확인할 것은 무엇인가?
- 영향 범위, 응답 주체, 마지막으로 관찰된 계층, 완화 가능성이다.
- 인프라 팀에 좋은 확인 요청을 하려면 무엇을 포함해야 하는가?
- 발생 시각, URL, method, status, response header, request id, client IP, 확인한 정상 계층, 확인이 필요한 계층을 포함해야 한다.