Success
이 문서는 Web-지도 문서를 읽은 뒤, 실제 상황에서 판단을 꺼내 쓰기 위한 훈련북이다.
Web-지도 실전 훈련북
이 문서는 25. Web-지도 실전 가이드북.md의 다음 단계다. 가이드북이 “이 상황에서는 어떤 지도를 펼칠까?”를 알려준다면, 이 훈련북은 Evidence를 보고 직접 판단 순서를 써보게 만든다.
정리된 개념을 다시 설명하는 문서가 아니라, 장애 대응, 설계 리뷰, 기능 개발 상황에서 손을 움직여 보는 문제집에 가깝다. 먼저 답을 써보고, 그 다음 해설과 연결 문서를 보며 판단 기준을 보정한다.
이 문서의 사용법
- 먼저
내 답안callout에 확인 순서, 원인 후보, 설계 선택, 운영 지표를 직접 적는다. - 그 다음 힌트와 해설을 보며 빠뜨린 경계를 확인한다.
연결 문서는 복습 경로다. 전부 다시 읽기보다, 내 답안이 흔들린 지도를 먼저 펼친다.- 같은 훈련을 며칠 뒤 다시 풀어본다. 처음보다 더 빨리, 더 좁게, 더 증거 중심으로 판단하면 제대로 흡수되고 있는 것이다.
훈련 방식
이 훈련북은 세 가지 방식으로 구성되어 있다.
- 실습 랩은 구조를 직접 그리거나 기준표를 만드는 훈련이다.
- 장애 대응 훈련은 제한된 시간 안에 무엇을 먼저 확인할지 정하는 훈련이다.
- 설계 리뷰 훈련은 겉보기에는 그럴듯한 설계에서 숨은 위험과 승인 조건을 찾는 훈련이다.
해설을 읽기 전에 반드시 한 번 멈춘다. Web-지도 학습의 핵심은 많은 이름을 외우는 것이 아니라, 증거를 보고 흐름의 위치를 잡는 일이다.
반복 학습 루프
- Evidence만 보고 요청 흐름 또는 운영 흐름을 그린다.
- 실패 위치를 Browser, Edge, Web Server, WAS, DB, Redis, Queue, Kubernetes, 외부 API 중 하나 이상으로 나눈다.
- 5분 안에 확인할 지표와 로그를 적는다.
- 임시 조치와 근본 수정을 분리한다.
- 연결 문서로 돌아가 판단 기준을 보정한다.
- 다음 반복에서는 더 적은 단서로도 같은 결론에 도달하는지 확인한다.
훈련 목록
| 구분 | 훈련 | 핵심 |
|---|---|---|
| Lab 1 | 전체 요청 흐름 그리기 | Browser부터 WAS, 데이터, 운영 흐름까지 위치 잡기 |
| Lab 2 | API 계약과 실패 응답 분류하기 | 400, 401, 403, 409, 429, 500을 경계별로 나누기 |
| Lab 3 | DB, Redis, Queue 선택 기준 세우기 | 정합성, 지연, 중복, freshness 기준 잡기 |
| Lab 4 | Docker/Kubernetes 배포 단위 점검하기 | Image, Pod, Service, Ingress, Probe 연결 보기 |
| Incident 1 | WAS 로그 없는 접속 실패 | 바깥쪽에서 안쪽으로 진입 경로 확인 |
| Incident 2 | CPU는 낮은데 timeout | Thread, pool, lock, 외부 API 대기 확인 |
| Incident 3 | Queue lag와 DLQ 증가 | ack, retry, DLQ, idempotency 확인 |
| Incident 4 | 로그인, CORS, 401/403 혼재 | 인증, 인가, 브라우저 정책 분리 |
| Review 1 | Redis Cache 설계 리뷰 | cache-aside, TTL, 무효화, fallback 검토 |
| Review 2 | 무중단 배포와 DB Migration 리뷰 | rollout, rollback, expand-contract 검토 |
| Review 3 | AI/LLM 기능 연동 리뷰 | 비용, 지연, 품질, 보안, Queue 검토 |
| 최종 종합 | 신규 기능 출시부터 장애 대응까지 | 요청 흐름, 지표, 복구, 설계를 한 번에 연결 |
Part 1. 실습 랩
Lab 1. 전체 요청 흐름 그리기
상황
새 팀에 합류했다. 서비스는 웹 프론트, API 서버, Redis, DB, Queue, Object Storage, 외부 결제 API, APM을 사용한다. 그런데 문서에는 기술 목록만 있고, 사용자의 요청이 실제로 어디를 거쳐 응답으로 돌아오는지 한눈에 보이지 않는다.
제공된 Evidence
- 사용자는
https://shop.example.com/orders에서 주문 목록을 조회한다. - DNS는 CDN CNAME을 가리킨다.
- 정적 JS/CSS는 CDN에서 응답한다.
- API 호출은
/api/orders이고, LB 뒤의 Web Server를 거쳐 Spring WAS로 간다. - WAS는 DB에서 주문 목록을 조회하고, Redis에서 사용자 세션을 읽는다.
- 주문 썸네일은 Object Storage URL로 내려간다.
- 주문 완료 이벤트는 Queue로 발행되고, Worker가 이메일을 보낸다.
- APM에는 API latency, DB slow query, Redis command latency, queue depth가 보인다.
해야 할 일
- 사용자 요청 1건의 동기 흐름을 적는다.
- 사용자 요청 바깥의 운영·비동기 흐름을 따로 적는다.
- WAS 로그가 없을 때 먼저 볼 구간과, WAS 로그가 있을 때 먼저 볼 구간을 나눈다.
- 이 서비스에서 반드시 있어야 할 trace id 또는 request id 위치를 적는다.
먼저 써보기
내 답안
여기에 직접 작성한다.
힌트
동기 요청 흐름과 비동기·운영 흐름을 한 줄에 섞으면 장애 대응 순서가 흐려진다. CDN에서 끝나는 정적 응답, WAS까지 들어오는 API 요청, Queue로 넘어가는 비동기 작업을 따로 표시한다.
해설
동기 요청은 Browser -> DNS -> CDN -> TLS/WAF/LB -> Web Server -> WAS -> Redis/DB -> Response로 잡을 수 있다. 정적 리소스는 CDN cache hit이면 WAS까지 오지 않을 수 있고, API 요청만 origin으로 들어간다.
Queue, Worker, APM, Backup, CI/CD는 사용자 요청 1건의 동기 경로와 구분해야 한다. 주문 완료 이메일은 사용자가 주문 목록을 조회하는 요청의 직접 응답 경로가 아니라, 이벤트 발행 이후 별도 흐름이다. 따라서 장애가 났을 때도 “사용자가 지금 실패를 보는 흐름”과 “나중에 처리되는 흐름”을 분리해야 한다.
trace id는 Browser/API Client, Edge, Web Server, WAS, DB span, Queue message metadata까지 이어지는 것이 좋다. 최소한 WAS 로그, APM trace, 외부 API 호출 로그, Worker 로그가 같은 요청 또는 업무 id로 묶여야 한다.
연결 문서
- 1. 웹 전체 지도.md - 사용자 요청, 데이터, 운영 흐름의 큰 위치를 잡는다.
- 2. Edge 진입 지도 - DNS, CDN, TLS, WAF, LB.md - 애플리케이션 앞단의 진입 경로를 확인한다.
- 3. Web Server, WAS, Spring MVC 지도.md - Web Server와 WAS 이후의 내부 흐름을 본다.
- 4. 데이터, Redis, 외부 연동 지도.md - DB, Redis, Storage, 외부 API 위치를 나눈다.
- 8. APM , Backup , 장애 대응 지도.md - 관측 신호와 장애 대응 흐름을 연결한다.
- 25. Web-지도 실전 가이드북.md - 비슷한 상황을 빠르게 찾아가는 기준으로 쓴다.
가져갈 판단 기준
처음 보는 시스템은 기술 이름보다 요청의 위치를 먼저 그린다. 동기 요청, 비동기 작업, 운영 흐름을 분리하면 장애 대응 순서가 훨씬 선명해진다.
Lab 2. API 계약과 실패 응답 분류하기
상황
프론트엔드 팀이 주문 생성 API를 붙이고 있다. API는 대체로 동작하지만 실패 응답이 뒤섞여 있어 화면 처리가 어렵다. 같은 입력 오류가 어떤 때는 400, 어떤 때는 500으로 오고, 권한 문제와 CORS 문제도 한 화면에서 같이 보인다.
제공된 Evidence
POST /api/orders에서quantity=-1이면 가끔 500이 내려온다.- 로그인하지 않은 요청은 401, 로그인했지만 다른 사용자의 주문 접근은 403이어야 한다.
- 중복 주문 요청은 409로 처리하고 싶다.
- 외부 결제사의 rate limit은 429 또는 503 후보로 논의 중이다.
- 브라우저 Network 탭에는 preflight는 204인데 실제 요청은 401인 경우가 있다.
- 일부 에러 body에는
NullPointerException문자열이 그대로 노출된다.
해야 할 일
- Validation 실패, 인증 실패, 인가 실패, 비즈니스 충돌, 외부 의존성 실패, 서버 예외를 분류한다.
- 각 분류에 맞는 HTTP status와 error response 필드를 제안한다.
- CORS 오류처럼 보이는 문제와 실제 인증 실패를 어떻게 구분할지 적는다.
- 프론트엔드가 재시도해도 되는 실패와 재시도하면 안 되는 실패를 나눈다.
먼저 써보기
내 답안
여기에 직접 작성한다.
힌트
400, 401, 403, 409, 429, 500은 숫자 암기가 아니라 경계 구분이다. 요청 형식이 잘못됐는지, 신원이 없는지, 권한이 없는지, 업무 규칙과 충돌했는지, 서버가 예상 밖으로 실패했는지를 먼저 나눈다.
해설
quantity=-1은 Request DTO 또는 Validation 경계에서 잡아 400으로 응답하는 편이 자연스럽다. 로그인 정보가 없거나 만료되었으면 401, 로그인은 되었지만 리소스 소유자나 role/scope 조건을 통과하지 못하면 403이다. 중복 주문처럼 업무 규칙 충돌은 409가 어울린다.
외부 결제사의 rate limit은 사용자가 같은 요청을 즉시 반복해도 해결되지 않을 가능성이 높다. API 계약에서는 error code, retry 가능 여부, retry-after 또는 화면 메시지 기준을 함께 정해야 한다. 서버 내부 예외는 500이 될 수 있지만, stack trace나 class name을 응답에 노출하지 않는다.
CORS는 서버 API 인증을 대신하지 않는다. preflight가 성공했는데 실제 요청이 401이면 브라우저 정책보다 인증 정보 전송, Cookie SameSite, Authorization header, Session/JWT 검증을 먼저 본다.
연결 문서
- 3. Web Server, WAS, Spring MVC 지도.md - Controller, Validation, ExceptionHandler 경계를 확인한다.
- 9. 보안 검증 위치 지도.md - 요청 흐름의 보안 검증 위치를 나눈다.
- 10. HTTP, Cookie, Session, JWT 지도.md - HTTP 상태와 인증 정보 전달 방식을 본다.
- 13. 인증과 인가 지도 - Session, OAuth, JWT, RBAC.md - 401과 403의 의미를 분리한다.
- 18. Browser, Frontend, API 호출 지도.md - 브라우저 Network 탭과 API Client 상태를 연결한다.
- 19. API Contract, Error Response, Validation 지도.md - API 계약과 실패 응답 모델을 잡는다.
- 23. Security Threat Model 지도 - Trust Boundary, Attack Surface.md - 응답 노출과 신뢰 경계를 확인한다.
가져갈 판단 기준
API 실패 응답은 “서버가 싫어했다”가 아니라 어느 경계에서 거절되었는지를 알려주는 계약이다. 프론트가 다음 행동을 정할 수 있어야 좋은 에러 응답이다.
Lab 3. DB, Redis, Queue 선택 기준 세우기
상황
상품 상세 조회가 느려지고 주문 후 알림 처리도 늦다. 팀에서는 DB 인덱스 추가, Redis 캐시, Queue 도입, Batch 보정 작업을 한꺼번에 이야기하고 있다. 선택지는 많지만 어떤 문제에 어떤 도구를 써야 하는지 기준이 필요하다.
제공된 Evidence
- 상품 상세 API p95 latency가 280ms에서 1.9s로 증가했다.
- slow query log에는
products와reviews조인에서 rows examined가 급증했다. - Redis cache hit ratio는 42 percent이고, evicted keys가 증가했다.
- 주문 생성 후 이메일 발송 때문에 API 응답이 700ms 늘어난다.
- 같은 결제 callback이 두 번 들어와 주문 상태 변경 로그가 중복으로 남았다.
- Batch 통계는 매일 03:00에 돌지만, 마지막 성공 시각이 이틀 전이다.
해야 할 일
- DB 인덱스, Redis 캐시, Queue, Batch 중 어느 문제에 어느 선택지를 적용할지 나눈다.
- 캐시를 붙이기 전에 확인해야 할 DB 지표를 적는다.
- Queue 도입 시 반드시 같이 설계해야 할 retry, DLQ, idempotency 기준을 적는다.
- 운영 중 볼 임계치 후보를 latency, saturation, freshness 축으로 나눈다.
먼저 써보기
내 답안
여기에 직접 작성한다.
힌트
Redis와 Queue는 DB 문제를 지워주는 도구가 아니다. Redis는 빠른 재조회와 짧은 상태에 강하고, Queue는 사용자가 기다릴 필요 없는 일을 뒤로 넘긴다. 정합성이 중요한 변경은 DB 트랜잭션과 멱등성을 먼저 본다.
해설
상품 상세 조회 지연은 먼저 DB 실행 계획, 인덱스, 조인 방식, connection pool wait를 확인해야 한다. 캐시는 읽기 부하가 크고 약간의 stale을 허용할 수 있을 때 후보가 된다. hit ratio가 낮고 eviction이 늘어난다면 캐시 키, TTL, maxmemory, eviction policy를 함께 점검해야 한다.
이메일 발송처럼 사용자 응답에 즉시 필요하지 않은 작업은 Queue와 Worker로 분리할 수 있다. 다만 Queue는 실패를 없애지 않는다. publish 확인, 성공 후 ack, retry backoff, DLQ, 재처리 절차, idempotency key가 같이 있어야 운영 가능한 비동기가 된다.
중복 결제 callback은 멱등성 문제다. 같은 external event id 또는 idempotency key가 두 번 들어와도 최종 상태가 한 번만 바뀌도록 DB 제약, 처리 이력, 상태 전이 검사를 둔다. Batch 실패는 freshness 지표와 last success time으로 관측해야 한다.
연결 문서
- 4. 데이터, Redis, 외부 연동 지도.md - 데이터 의존성과 외부 API 위치를 나눈다.
- 5. Redis 상세 지도 - Session, Cache, Rate Limit, Lock, Pub-Sub.md - Redis 사용 목적과 장애 fallback을 본다.
- 6. 비동기, Scheduler, Batch 지도.md - 동기와 비동기 작업 경계를 정한다.
- 11. DB 트랜잭션, 인덱스, 락 지도.md - DB 성능과 정합성 판단을 확인한다.
- 12. Queue 신뢰성 지도 - Ack, Retry, DLQ, Idempotency.md - 메시지 신뢰성 기준을 세운다.
- 17. 운영 지표와 설계 선택 지도 - SLI, SLO, 임계치, Trade-off.md - latency, saturation, freshness 지표를 연결한다.
- 21. System Design 선택 지도 - Cache, Queue, DB, Scale, Consistency.md - 설계 선택의 trade-off를 비교한다.
- 22. Data Pipeline 지도 - Event, Outbox, CDC, Kafka, Batch.md - 이벤트와 배치의 데이터 흐름을 본다.
가져갈 판단 기준
DB, Redis, Queue는 빠른 순서로 고르는 것이 아니라 데이터의 성격으로 고른다. 영속성과 정합성은 DB, 빠른 재조회와 짧은 상태는 Redis, 늦게 처리해도 되는 작업은 Queue가 후보가 된다.
Lab 4. Docker/Kubernetes 배포 단위 점검하기
상황
새 API 서버를 Docker 이미지로 만들고 Kubernetes에 배포하려 한다. 로컬 Compose에서는 잘 뜨지만, 운영 클러스터에서는 readiness가 실패하거나 Ingress로 접근이 되지 않을 수 있다. 배포 전 점검 기준이 필요하다.
제공된 Evidence
- Dockerfile은 build stage와 runtime stage가 분리되어 있지 않다.
- 운영 설정은 환경 변수
SPRING_PROFILES_ACTIVE=prod와 SecretDB_PASSWORD를 사용한다. - Kubernetes Deployment replicas는 3이다.
- readiness probe는
/health를 5초마다 호출한다. - Service
targetPort는 8080인데 container port는 8081로 열려 있다. - Ingress는
/apipath를 backend service로 라우팅한다. - 배포 후 APM에서 새 version tag별 5xx와 p95 latency를 볼 수 있어야 한다.
해야 할 일
- Docker 단계에서 확인할 항목과 Kubernetes 단계에서 확인할 항목을 나눈다.
- readiness, liveness, startup probe 중 어떤 것을 어떤 목적으로 둘지 적는다.
- Service, Pod label, port, Ingress 경로에서 깨질 수 있는 지점을 찾는다.
- 배포 후 rollback 판단에 필요한 지표를 적는다.
먼저 써보기
내 답안
여기에 직접 작성한다.
힌트
Docker는 컨테이너 실행 단위이고, Kubernetes는 그 컨테이너를 배포, 연결, 복구, 확장하는 운영 계층이다. 컨테이너가 뜨는 것과 Service endpoint로 트래픽을 받을 준비가 된 것은 다르다.
해설
Docker 단계에서는 이미지 크기, build/runtime 분리, 환경 변수 주입, 포트 노출, 로그 출력, healthcheck, volume 필요 여부를 확인한다. Kubernetes 단계에서는 Deployment rollout, Pod 상태, events, ConfigMap/Secret mount, Service selector/endpoint, Ingress host/path, probe 상태를 확인한다.
이 Evidence에서는 targetPort와 container port가 어긋날 가능성이 크다. Pod가 Running이어도 Service가 올바른 port로 보내지 않으면 사용자는 502나 timeout을 볼 수 있다. readiness probe가 실제 업무 준비 상태가 아니라 단순 프로세스 생존만 보면, 준비되지 않은 Pod로 트래픽이 갈 수도 있다.
배포 후에는 version별 5xx rate, p95/p99 latency, readiness failure, unavailable replicas, pod restart count, rollback duration을 함께 본다. DB Migration이 포함된다면 이전 버전과 새 버전이 함께 동작하는지도 별도 승인 조건이 되어야 한다.
연결 문서
- 7. CI.CD , 배포 지도.md - build, test, deploy, rollback 흐름을 본다.
- 14. Docker 지도 - Image, Container, Volume, Network, Compose.md - 이미지와 컨테이너 실행 조건을 확인한다.
- 15. Kubernetes 지도 - Pod, Deployment, Service, Ingress, ConfigMap, Secret.md - Pod, Service, Ingress 연결을 본다.
- 16. 실전 장애 점검 체크리스트 지도.md - 배포 직후 장애 조사 순서를 잡는다.
- 17. 운영 지표와 설계 선택 지도 - SLI, SLO, 임계치, Trade-off.md - 배포 후 사용자 영향 지표를 본다.
- 20. JVM, OS, Thread, Memory 지도.md - 컨테이너 자원과 JVM 실행 병목을 확인한다.
가져갈 판단 기준
컨테이너가 떠 있다는 사실은 시작점일 뿐이다. Kubernetes에서는 Pod가 준비되었는지, Service가 올바른 endpoint를 갖는지, Ingress가 원하는 backend로 보내는지까지 이어서 확인해야 한다.
Part 2. 장애 대응 훈련
Incident 1. WAS 로그가 없는 접속 실패
Incident 상황
월요일 10:05부터 고객센터에 “사이트가 열리지 않는다”는 제보가 들어왔다. 백엔드 팀은 WAS 로그를 확인했지만 해당 시간대 요청이 거의 보이지 않는다.
현재 보이는 증상
- 일부 사용자는 브라우저에서 502를 본다.
- 일부 사용자는 TLS 오류를 본다.
- 정적 이미지와 CSS는 정상처럼 보인다.
- API
/api/me는 실패하지만 CDN cache hit된/assets/app.js는 정상이다. - 장애는 전체 사용자가 아니라 특정 지역 ISP에서 더 많이 보인다.
로그/지표/SQL 단서
- CDN request count는 증가했지만 origin request count는 감소했다.
- WAF blocked count가 평소보다 6배 증가했다.
- LB healthy host count가 4에서 2로 줄었다.
- Web Server upstream log에는
connect() failed가 간헐적으로 보인다. - WAS application log에는 해당 요청 trace id가 없다.
- 09:58에 Ingress TLS secret 교체가 있었다.
5분 안에 확인할 것
- 사용자 영향 범위와 시작 시각을 기록한다.
- CDN, WAF, LB, Ingress, Web Server 중 어디에서 끊기는지 확인한다.
- TLS certificate, WAF rule 변경, LB health check, Ingress controller log를 본다.
- WAS 로그가 없는 이유가 요청 미도달인지, 로그 누락인지 구분한다.
- 최근 배포·설정 변경과 장애 시작 시각을 맞춘다.
내 답안
여기에 직접 작성한다.
원인 후보 분류
- DNS/CDN 라우팅 문제: 특정 지역에서 origin으로 제대로 전달되지 않을 수 있다.
- TLS/Ingress 설정 문제: secret 교체 이후 handshake 또는 host 매칭이 깨졌을 수 있다.
- WAF 정책 문제: 정상 API 요청이 새 rule에 걸릴 수 있다.
- LB/Web Server upstream 문제: 일부 origin이 health check에서 빠졌거나 upstream 연결이 실패할 수 있다.
- WAS 내부 문제: 가능성은 남기되, 요청 로그가 없으므로 우선순위는 뒤로 둔다.
하면 안 되는 조치
- WAS 로그가 없는데 곧바로 애플리케이션 코드를 롤백하지 않는다.
- WAF를 전체 off하기 전에 차단 rule과 영향 범위를 확인하지 않고 열지 않는다.
- TLS secret을 재교체하면서 이전 정상 secret과 차이를 기록하지 않는 행동을 피한다.
- 사용자 영향이 있는 상태에서 증거 로그를 보존하지 않고 Pod나 Web Server를 무작정 재시작하지 않는다.
복구 절차
- TLS secret 또는 Ingress 설정 변경이 원인 후보로 좁혀지면 이전 정상 설정으로 되돌리거나 canary 범위를 줄인다.
- WAF false positive가 확인되면 해당 rule만 예외 처리하고, 전체 방어선을 끄지 않는다.
- LB healthy host가 줄었다면 health check path와 origin 상태를 확인하고 정상 origin으로 traffic shift한다.
- 임시 복구 후 Web Server, LB, WAF, CDN 지표가 정상 기준선으로 돌아오는지 확인한다.
완료 검증
- CDN origin request count와 WAS request count가 정상 비율로 회복된다.
- 502, TLS error, WAF block false positive가 감소한다.
- 특정 지역 ISP의 실패율이 전체 기준선과 비슷해진다.
- 새 trace id가 Edge부터 WAS까지 이어진다.
회고 질문
- TLS secret 교체는 어떤 승인·검증 절차를 통과했는가?
- WAF rule 변경과 애플리케이션 배포가 같은 시간대에 겹치지 않았는가?
- Edge 계층 로그와 WAS trace id를 연결할 방법이 충분했는가?
- 다음에는 어떤 alert가 사용자의 제보보다 먼저 울려야 하는가?
연결 문서
- 2. Edge 진입 지도 - DNS, CDN, TLS, WAF, LB.md - WAS 앞단 장애 위치를 구분한다.
- 7. CI.CD , 배포 지도.md - 설정 변경과 배포 시간축을 확인한다.
- 8. APM , Backup , 장애 대응 지도.md - 로그, 메트릭, 트레이스를 연결한다.
- 15. Kubernetes 지도 - Pod, Deployment, Service, Ingress, ConfigMap, Secret.md - Ingress와 Secret 경계를 본다.
- 16. 실전 장애 점검 체크리스트 지도.md - 사용자 영향과 최근 변경을 먼저 본다.
- 17. 운영 지표와 설계 선택 지도 - SLI, SLO, 임계치, Trade-off.md - 사용자 영향 SLI와 alert 조건을 잡는다.
가져갈 판단 기준
WAS 로그가 없으면 먼저 애플리케이션 안쪽으로 들어가지 않는다. Browser와 Edge에서 요청이 어디까지 도달했는지 바깥쪽에서 안쪽으로 좁힌다.
Incident 2. CPU는 낮은데 요청이 timeout 된다
Incident 상황
API 서버 CPU는 35 percent 수준이다. 그런데 결제 확인 API의 p99 latency가 12초까지 튀고, 사용자 timeout이 늘고 있다. 서버는 바빠 보이지 않는데 요청 처리는 밀린다.
현재 보이는 증상
/api/payments/{id}/confirmp95는 900ms, p99는 12s다.- 5xx rate는 낮지만 client timeout이 증가한다.
- WAS active thread는 최대치에 가깝다.
- DB CPU는 높지 않지만 connection pool wait가 증가한다.
- 외부 결제 API latency가 간헐적으로 8초 이상이다.
로그/지표/SQL 단서
HikariPool - Connection is not available, request timed out after 3000ms- thread dump에는
WAITING on java.net.SocketInputStream.socketRead0가 많다. - slow query count는 평소보다 조금 증가했지만 폭증은 아니다.
- DB lock wait time이 특정 주문 테이블에서 증가했다.
- external API timeout count가 10분 동안 15배 증가했다.
- GC pause는 정상 범위다.
5분 안에 확인할 것
- active thread, thread pool queue, DB connection pool wait를 먼저 본다.
- trace에서 시간이 가장 많이 걸리는 span이 DB인지 외부 API인지 확인한다.
- 외부 API timeout과 retry가 thread를 오래 붙잡고 있는지 확인한다.
- DB lock wait와 long transaction이 connection을 오래 점유하는지 본다.
- 최근 timeout, retry, pool size 설정 변경이 있었는지 확인한다.
내 답안
여기에 직접 작성한다.
원인 후보 분류
- 외부 API 대기: CPU는 낮지만 WAS thread가 socket read에서 기다릴 수 있다.
- DB connection pool 고갈: DB CPU가 낮아도 connection을 못 얻으면 요청이 밀린다.
- lock 또는 long transaction: 일부 트랜잭션이 connection과 lock을 오래 잡을 수 있다.
- retry 폭증: 짧은 시간에 재시도가 쌓여 정상 요청까지 밀어낼 수 있다.
- JVM/OS 병목: GC, file descriptor, socket 상태도 확인하되 현재 증거상 우선순위는 thread와 pool이다.
하면 안 되는 조치
- CPU가 낮다는 이유만으로 장애가 아니라고 판단하지 않는다.
- 무작정 replica를 늘리기 전에 DB와 외부 API 병목이 같이 늘어나는지 확인한다.
- timeout을 크게 늘려 사용자 대기 시간과 thread 점유 시간을 더 키우지 않는다.
- retry 횟수를 늘려 외부 API와 내부 thread pool을 함께 압박하지 않는다.
복구 절차
- 외부 결제 API 장애가 확인되면 timeout을 짧게 조정하고 circuit breaker 또는 fallback 정책을 적용한다.
- DB lock이 원인이라면 긴 트랜잭션을 중단하거나 문제 쿼리를 우회하고, 쓰기 경로를 제한한다.
- connection pool wait가 높으면 일시적으로 traffic shedding 또는 일부 기능 제한을 검토한다.
- 사용자 영향이 크면 결제 확인을 비동기 상태 조회로 전환하거나 feature flag로 위험 경로를 줄인다.
완료 검증
- p99 latency와 client timeout count가 기준선으로 내려간다.
- active thread와 DB connection pool wait가 안정된다.
- external API timeout, retry count가 줄어든다.
- 결제 상태 정합성 검증에서 중복 승인이나 누락이 없다.
회고 질문
- 외부 API timeout과 retry 기준은 사용자 SLO와 맞았는가?
- 결제 확인을 반드시 동기로 끝내야 했는가?
- connection pool, thread pool, 외부 API 지표가 같은 dashboard에서 보였는가?
- 이번 장애를 SLO 위반과 설계 선택 개선으로 연결할 항목은 무엇인가?
연결 문서
- 3. Web Server, WAS, Spring MVC 지도.md - WAS thread와 MVC 처리 흐름을 본다.
- 4. 데이터, Redis, 외부 연동 지도.md - DB와 외부 API 대기 지점을 나눈다.
- 8. APM , Backup , 장애 대응 지도.md - trace와 metric을 연결한다.
- 11. DB 트랜잭션, 인덱스, 락 지도.md - lock, connection, long transaction을 확인한다.
- 17. 운영 지표와 설계 선택 지도 - SLI, SLO, 임계치, Trade-off.md - latency, saturation, error 축을 본다.
- 20. JVM, OS, Thread, Memory 지도.md - CPU가 낮아도 멈추는 실행 병목을 확인한다.
- 21. System Design 선택 지도 - Cache, Queue, DB, Scale, Consistency.md - 동기 처리와 장애 격리 선택을 검토한다.
가져갈 판단 기준
CPU가 낮아도 서비스는 멈출 수 있다. 요청 처리 자원이 CPU가 아니라 thread, connection, lock, socket 대기에서 막히는지 확인한다.
Incident 3. Queue lag와 DLQ가 증가한다
Incident 상황
주문 완료 이벤트를 처리하는 Worker가 지연되고 있다. 사용자는 주문 완료 화면을 보지만, 이메일과 정산 반영이 늦고 일부 메시지가 DLQ로 이동한다.
현재 보이는 증상
order.completedqueue depth가 5분 동안 1,200에서 28,000으로 증가했다.- consumer lag가 계속 증가한다.
- DLQ count가 평소 0에서 340으로 늘었다.
- Worker CPU는 높지 않지만 처리 시간이 길어졌다.
- 같은 주문의 정산 이벤트가 두 번 처리된 흔적이 있다.
로그/지표/SQL 단서
message_id=evt-8391 retry_count=5 reason=payment_status_missingack timeout로그가 증가한다.- 외부 정산 API 429 rate가 증가했다.
- Worker 처리 성공 후 ack 전에 process가 재시작된 기록이 있다.
- DB
settlement_events테이블에는 unique key가 없다. - Batch 보정 작업의 last success time은 36시간 전이다.
5분 안에 확인할 것
- Producer가 같은 메시지를 중복 발행하는지, Consumer가 중복 처리하는지 나눈다.
- queue depth, unacked, consumer count, processing latency를 본다.
- retry backoff가 있는지, retry가 외부 API 429를 증폭시키는지 확인한다.
- DLQ로 간 메시지의 공통 error code와 event type을 묶는다.
- idempotency key 또는 처리 이력 테이블이 있는지 확인한다.
내 답안
여기에 직접 작성한다.
원인 후보 분류
- 외부 API rate limit: Worker가 계속 재시도하며 lag와 DLQ를 키울 수 있다.
- ack 처리 위치 문제: 성공 후 ack 전에 재시작되면 같은 메시지가 다시 처리될 수 있다.
- 멱등성 부재: 중복 메시지 또는 중복 소비가 DB 결과 중복으로 이어질 수 있다.
- Batch 보정 실패: 비동기 누락을 보정하는 마지막 방어선이 함께 실패했을 수 있다.
- Consumer capacity 부족: 처리량 자체가 발행량을 못 따라갈 수 있다.
하면 안 되는 조치
- DLQ 메시지를 원인 분류 없이 전체 재처리하지 않는다.
- retry 간격을 더 짧게 만들어 외부 API 429를 키우지 않는다.
- 중복 처리 방지 없이 consumer 수만 늘리지 않는다.
- 사용자에게 완료된 업무의 정산 상태를 검증하지 않고 성공으로 확정하지 않는다.
복구 절차
- 외부 API 429가 원인이라면 retry backoff를 늘리고 circuit breaker 또는 rate limit을 적용한다.
- DLQ 메시지를 error code별로 분류하고, 안전한 재처리 조건을 먼저 만든다.
- idempotency key, unique constraint, 처리 이력을 임시 방어선으로 추가한다.
- Consumer를 늘리기 전 DB와 외부 API가 감당 가능한 처리량을 확인한다.
- Batch 보정 작업을 복구해 누락 이벤트를 재검증한다.
완료 검증
- queue depth와 consumer lag가 감소 추세로 돌아선다.
- DLQ 증가가 멈추고, 재처리 성공률이 확인된다.
- duplicate detected count가 관측되고, 중복 정산이 더 이상 발생하지 않는다.
- Batch last success time이 정상 주기로 회복된다.
회고 질문
- 이 메시지는 최소 한 번 처리 모델을 전제로 설계되었는가?
- ack, retry, DLQ, idempotency가 기능 출시 때 함께 정의되었는가?
- DLQ를 누가 보고 어떤 순서로 재처리하는지 runbook이 있었는가?
- Queue lag alert는 사용자 영향보다 충분히 빨리 울렸는가?
연결 문서
- 4. 데이터, Redis, 외부 연동 지도.md - 외부 API와 Queue 의존성을 확인한다.
- 6. 비동기, Scheduler, Batch 지도.md - 비동기 작업과 Batch 보정 흐름을 본다.
- 8. APM , Backup , 장애 대응 지도.md - 관측과 Incident 대응 흐름을 연결한다.
- 12. Queue 신뢰성 지도 - Ack, Retry, DLQ, Idempotency.md - 메시지 신뢰성의 핵심 기준을 확인한다.
- 17. 운영 지표와 설계 선택 지도 - SLI, SLO, 임계치, Trade-off.md - lag와 freshness를 운영 지표로 본다.
- 21. System Design 선택 지도 - Cache, Queue, DB, Scale, Consistency.md - 비동기 선택의 trade-off를 검토한다.
- 22. Data Pipeline 지도 - Event, Outbox, CDC, Kafka, Batch.md - 이벤트 발행과 파이프라인 보정 흐름을 본다.
가져갈 판단 기준
Queue 장애는 “작업이 늦다”에서 끝나지 않는다. 유실, 중복, 순서, 재처리, freshness를 함께 확인해야 운영 가능한 비동기가 된다.
Incident 4. 로그인, CORS, 401/403이 섞여 보인다
Incident 상황
프론트엔드 배포 후 일부 사용자가 로그인은 된 것처럼 보이지만 API 호출에 실패한다. 브라우저 콘솔에는 CORS 오류가 보이고, 서버 로그에는 401과 403이 섞여 있다.
현재 보이는 증상
- Chrome에서는
/api/me가 401, Safari에서는 간헐적으로 CORS 오류처럼 보인다. - Admin API는 로그인한 일반 사용자에게 403을 반환한다.
- 일부 요청에는 Cookie가 없고, 일부 요청에는 Cookie는 있지만 Session 조회가 실패한다.
- preflight 요청은 204로 성공한다.
- 프론트 화면은 error UI 대신 loading 상태에 오래 머문다.
로그/지표/SQL 단서
Set-Cookie: SID=...; HttpOnly; Secure; SameSite=Lax- API Client는
credentials: include가 빠진 화면이 일부 있다. - Redis session lookup latency가 증가했고, session missing count가 늘었다.
Access-Control-Allow-Origin이 staging origin으로 내려간 요청이 있다.- SecurityFilter 로그에는
ROLE_ADMIN required가 보인다. - WAF blocked count는 평소 수준이다.
5분 안에 확인할 것
- Network 탭에서 실제 요청과 preflight를 분리해 본다.
- Cookie가 저장되었는지와 실제 API 요청에 포함되었는지 확인한다.
- 401과 403을 로그와 응답 code에서 분리한다.
- CORS header가 요청 Origin과 credentials 정책에 맞는지 확인한다.
- Session Store, Redis TTL, key prefix, 배포 환경 설정 차이를 확인한다.
내 답안
여기에 직접 작성한다.
원인 후보 분류
- Cookie 전송 문제: SameSite, domain, path, credentials 설정이 맞지 않을 수 있다.
- Session Store 문제: Redis 지연, TTL 만료, key prefix 변경으로 세션 조회가 실패할 수 있다.
- CORS 설정 문제: 응답 노출 정책이 origin과 credentials에 맞지 않을 수 있다.
- 인가 실패: Admin API는 인증 성공 후 role 조건에서 403이 나는 정상 방어일 수 있다.
- 프론트 상태 처리 문제: loading, error, retry UI가 실패를 가릴 수 있다.
하면 안 되는 조치
- CORS를
*로 열어 인증 문제를 덮지 않는다. - 401과 403을 모두 같은 로그인 실패로 처리하지 않는다.
- Redis 세션 장애를 확인하지 않고 JWT로 급히 바꾸는 식의 구조 변경을 하지 않는다.
- Admin API 403을 사용자 불편만 보고 권한 검사를 완화하지 않는다.
복구 절차
- API Client의 credentials 설정 누락을 수정하고, Cookie 전송 조건을 환경별로 검증한다.
- CORS allowed origin과 credentials header를 운영 origin 기준으로 되돌린다.
- Redis session lookup 지연이 원인이라면 session fallback, TTL, key prefix, Redis 상태를 점검한다.
- 403은 role/scope/resource owner 기준이 맞는지 확인하고, 정상 차단이면 화면 메시지를 개선한다.
- 프론트 error state를 명시적으로 전환해 무한 loading을 줄인다.
완료 검증
/api/me의 401 rate가 기준선으로 내려간다.- CORS failure 후보와 cookie missing count가 감소한다.
- Admin API 403은 권한 없는 사용자에게만 유지된다.
- 브라우저별 로그인 유지와 API 호출이 같은 기준으로 통과한다.
- 프론트 화면이 실패를 loading으로 숨기지 않는다.
회고 질문
- 인증, 인가, CORS가 로그와 대시보드에서 분리되어 보였는가?
- 프론트 배포 전 운영 origin과 credentials 설정을 검증했는가?
- Session Store 장애가 로그인 장애로 번질 때 degrade 기준이 있었는가?
- 401/403/error response 계약을 프론트와 백엔드가 공유했는가?
연결 문서
- 2. Edge 진입 지도 - DNS, CDN, TLS, WAF, LB.md - Edge 차단과 애플리케이션 실패를 구분한다.
- 9. 보안 검증 위치 지도.md - CORS와 보안 검증 위치를 나눈다.
- 10. HTTP, Cookie, Session, JWT 지도.md - Cookie, Session, JWT 상태 전달을 확인한다.
- 13. 인증과 인가 지도 - Session, OAuth, JWT, RBAC.md - 인증과 인가 실패를 분리한다.
- 18. Browser, Frontend, API 호출 지도.md - 브라우저와 API Client 상태를 본다.
- 19. API Contract, Error Response, Validation 지도.md - 실패 응답 계약을 맞춘다.
- 23. Security Threat Model 지도 - Trust Boundary, Attack Surface.md - 신뢰 경계와 공격 표면을 확인한다.
가져갈 판단 기준
401, 403, CORS는 같은 화면에서 같이 보여도 같은 문제가 아니다. 인증 정보 전달, 권한 판단, 브라우저 응답 노출 정책을 반드시 분리한다.
Part 3. 설계 리뷰 훈련
Review 1. Redis Cache를 붙이는 조회 성능 개선안
제안된 설계안
상품 상세 API가 느리니 Controller 앞에 Redis Cache를 붙인다. key는 product:{id}이고 TTL은 24시간이다. Redis 장애 시에는 일단 500을 반환한다. 상품 수정 시 캐시 무효화는 다음 단계에서 고민한다.
겉보기 장점
- DB 조회 횟수를 줄일 수 있다.
- 사용자가 체감하는 조회 latency가 내려갈 수 있다.
- 구현이 비교적 빠르다.
- cache hit가 높으면 scale-out 전에 시간을 벌 수 있다.
숨은 리스크
- 원인이 인덱스나 lock이면 캐시가 근본 문제를 가린다.
- TTL 24시간은 상품 가격이나 재고 같은 freshness 요구와 충돌할 수 있다.
- Redis 장애 시 500을 반환하면 보조 저장소 장애가 곧 핵심 API 장애가 된다.
- cache stampede, eviction, stale data, 권한별 캐시 오염 가능성이 있다.
- 캐시 무효화 기준이 없으면 운영 중 데이터 불일치가 설명되지 않는다.
리뷰 질문
- 이 조회 API의 SLI는 latency뿐인가, correctness와 freshness도 포함되는가?
- 상품 데이터 중 stale을 허용할 수 있는 필드와 허용할 수 없는 필드는 무엇인가?
- 캐시 key에 사용자 권한, 지역, 언어, 가격 정책이 포함되어야 하는가?
- Redis 장애 시 DB fallback으로 버틸 수 있는가, 아니면 기능 제한이 필요한가?
- cache hit ratio, stale report, DB fallback count를 어떻게 관측할 것인가?
내 답안
여기에 직접 작성한다.
빠진 계약
- TTL과 무효화 정책
- Redis 장애 시 fallback 또는 fail-close 기준
- cache stampede 방어 기준
- 캐시 key 설계와 권한 경계
- DB 쿼리 개선 여부와 캐시 도입 전후 비교 지표
- stale data 신고 또는 정합성 검증 방법
개선된 설계 방향
먼저 slow query와 실행 계획, connection pool, lock wait를 확인한다. DB 병목을 줄인 뒤에도 읽기 부하가 크고 stale 허용 범위가 명확하면 cache-aside를 검토한다. Redis 장애 시에는 업무 중요도에 따라 DB fallback, 짧은 기능 제한, 읽기 전용 응답을 선택한다.
캐시 key에는 사용자별 권한이나 가격 정책처럼 응답을 바꾸는 조건을 포함해야 한다. TTL은 데이터 변경 빈도와 freshness SLO에 맞춰 정하고, 상품 수정 이벤트에서 무효화하거나 version 기반 key를 사용하는 방식을 검토한다.
승인 조건
- 캐시 전후 p95/p99 latency와 DB query latency 비교가 가능하다.
- cache hit ratio, eviction count, Redis command latency, DB fallback count가 관측된다.
- stale 허용 범위와 무효화 정책이 문서화되어 있다.
- Redis 장애 시 사용자 영향과 복구 절차가 정해져 있다.
- 권한별 응답이 캐시로 섞이지 않는다는 테스트가 있다.
연결 문서
- 4. 데이터, Redis, 외부 연동 지도.md - DB와 Redis 역할을 나눈다.
- 5. Redis 상세 지도 - Session, Cache, Rate Limit, Lock, Pub-Sub.md - eviction, TTL, fallback 기준을 본다.
- 11. DB 트랜잭션, 인덱스, 락 지도.md - 캐시 전 DB 원인 분석을 확인한다.
- 17. 운영 지표와 설계 선택 지도 - SLI, SLO, 임계치, Trade-off.md - latency와 freshness trade-off를 본다.
- 21. System Design 선택 지도 - Cache, Queue, DB, Scale, Consistency.md - 캐시 선택의 설계 비용을 검토한다.
가져갈 판단 기준
캐시는 성능 개선 도구이면서 정합성 비용을 만드는 설계 선택이다. 캐시를 붙이기 전에는 무엇을 늦게 봐도 되는지, Redis가 죽으면 무엇을 할지 먼저 정한다.
Review 2. 무중단 배포와 DB Migration 설계안
제안된 설계안
새 주문 상태 컬럼 delivery_status를 추가하고, 애플리케이션 새 버전에서 바로 필수값으로 사용한다. 배포는 rolling update로 진행한다. 문제가 생기면 이전 이미지로 rollback한다. readiness probe는 /health 200만 확인한다.
겉보기 장점
- rolling update라 전체 중단 없이 배포할 수 있다.
- DB 컬럼 추가는 비교적 안전해 보인다.
- 문제가 생기면 이전 이미지로 되돌릴 수 있다.
- readiness probe가 있으므로 트래픽 전환도 자동으로 보인다.
숨은 리스크
- 새 코드가 새 컬럼을 필수로 읽으면 이전 버전과 새 버전이 함께 떠 있는 동안 호환성 문제가 생길 수 있다.
- rollback해도 DB schema와 데이터는 이전 상태로 쉽게 돌아가지 않는다.
- readiness가 단순 200이면 DB, Redis, 필수 config 준비 상태를 놓칠 수 있다.
- backfill이 대량 update라면 lock, replication lag, slow query를 만들 수 있다.
- ConfigMap/Secret 변경이 rollout과 맞물리면 실패 위치가 불분명해질 수 있다.
리뷰 질문
- 이전 버전과 새 버전이 같은 DB schema에서 동시에 동작할 수 있는가?
- 컬럼 추가, 코드 배포, backfill, not null 적용, 기존 코드 제거가 나뉘어 있는가?
- readiness는 트래픽을 받아도 되는 상태를 확인하는가?
- rollback은 이미지뿐 아니라 config, migration, traffic routing을 어떻게 다루는가?
- 배포 중 version별 5xx, p95 latency, migration lock wait를 볼 수 있는가?
내 답안
여기에 직접 작성한다.
빠진 계약
- expand-contract migration 단계
- 이전 버전과 새 버전의 DB 호환성 조건
- backfill 속도, lock, 실패 재시작 기준
- readiness/smoke test 승인 조건
- rollback 가능 범위와 rollback 불가 변경 목록
- Kubernetes rollout 중단 조건과 alert 기준
개선된 설계 방향
DB 변경은 컬럼 추가 -> 새 코드가 optional로 읽고 쓰기 -> backfill -> 필수 검증 -> 이전 코드 제거 -> 제약 강화처럼 나눈다. rolling update 중에는 이전 Pod와 새 Pod가 동시에 떠 있으므로 양쪽 버전이 같은 schema를 견딜 수 있어야 한다.
readiness probe는 단순 프로세스 생존이 아니라 필수 의존성 준비 상태를 확인해야 한다. 다만 너무 무거운 check로 probe 자체가 장애를 만들지 않도록 startup/readiness/liveness의 목적을 나눈다. 배포 후에는 version별 latency, 5xx, readiness failure, unavailable replicas, migration duration, lock wait를 관측한다.
승인 조건
- expand-contract 단계가 PR 또는 배포 계획에 명시되어 있다.
- 이전 이미지 rollback 시 새 DB schema에서도 정상 동작한다.
- migration lock, duration, 실패 시 중단 기준이 있다.
- readiness와 smoke test가 핵심 사용자 여정을 검증한다.
- ConfigMap/Secret 변경과 애플리케이션 rollout 순서가 정해져 있다.
연결 문서
- 7. CI.CD , 배포 지도.md - 배포, rollback, migration 흐름을 본다.
- 14. Docker 지도 - Image, Container, Volume, Network, Compose.md - 이미지와 환경 주입을 확인한다.
- 15. Kubernetes 지도 - Pod, Deployment, Service, Ingress, ConfigMap, Secret.md - rollout, probe, service 연결을 본다.
- 16. 실전 장애 점검 체크리스트 지도.md - 배포 직후 장애 대응 순서를 잡는다.
- 17. 운영 지표와 설계 선택 지도 - SLI, SLO, 임계치, Trade-off.md - 배포 중 사용자 영향 지표를 본다.
- 22. Data Pipeline 지도 - Event, Outbox, CDC, Kafka, Batch.md - backfill과 데이터 이동 흐름을 확인한다.
가져갈 판단 기준
무중단 배포는 새 Pod를 천천히 띄우는 것만으로 완성되지 않는다. 이전 버전, 새 버전, DB schema, config, traffic routing이 동시에 견딜 수 있어야 한다.
Review 3. AI/LLM 기능을 기존 Web 서비스에 붙이는 설계안
제안된 설계안
상품 리뷰 요약 기능을 추가한다. 사용자가 버튼을 누르면 Backend API가 리뷰 목록을 읽고 LLM API를 호출한 뒤 요약을 바로 응답한다. Prompt는 코드에 문자열로 넣고, 실패하면 500을 반환한다. 비용과 품질 평가는 출시 후 본다.
겉보기 장점
- 구현이 빠르다.
- 사용자에게 즉시 요약 결과를 보여줄 수 있다.
- 기존 API 호출 흐름에 LLM API 호출만 추가하면 되어 보인다.
- 프론트엔드 상태 관리가 단순하다.
숨은 리스크
- LLM API latency가 길어지면 WAS thread가 오래 붙잡힌다.
- 429, timeout, provider 장애가 사용자 API 장애로 바로 이어진다.
- prompt version, model 설정, context source가 추적되지 않으면 품질 회귀를 설명하기 어렵다.
- 리뷰에 민감 정보가 포함될 수 있고, 권한 없는 리뷰가 context에 섞일 수 있다.
- 비용 폭증, hallucination report, policy block, tool boundary 같은 운영 지표가 빠져 있다.
- 긴 작업이면 Queue와 Worker가 더 적합할 수 있다.
리뷰 질문
- 이 요약은 사용자가 즉시 기다려야 하는 결과인가, 나중에 준비되어도 되는 결과인가?
- LLM timeout, retry, rate limit, fallback 기준은 무엇인가?
- prompt와 model 설정은 versioning, rollback, evaluation 대상인가?
- RAG나 context source에 권한 필터가 적용되는가?
- API response는 streaming, pending, failed, retryable 상태를 어떻게 표현하는가?
- 비용, 품질, 보안 이벤트를 어떤 dashboard에서 볼 수 있는가?
내 답안
여기에 직접 작성한다.
빠진 계약
- AI API contract와 error response 모델
- 동기 처리와 비동기 처리 선택 기준
- prompt/model/context versioning 기준
- LLM provider timeout, retry, rate limit, fallback 기준
- PII와 권한 필터, audit log 기준
- token cost, latency, evaluation score, policy block 지표
개선된 설계 방향
짧고 실패해도 핵심 업무가 깨지지 않는 요약은 동기 API로 시작할 수 있다. 하지만 리뷰 수가 많거나 provider latency가 긴 경우에는 요청은 job 생성으로 끝내고, Queue와 Worker가 LLM API를 호출한 뒤 결과를 저장하는 구조가 더 안정적이다.
Prompt와 model 설정은 코드 변경처럼 versioning한다. context source에는 권한 필터와 freshness 기준을 둔다. API 계약에는 pending, completed, failed, retryable 같은 상태를 명시하고, 프론트는 loading, retry, fallback UI를 갖는다. 비용과 품질도 장애 지표다. token 사용량, provider error, 429, hallucination report, human review rate를 함께 본다.
승인 조건
- 동기/비동기 선택 이유가 SLO와 비용 기준으로 설명된다.
- LLM timeout, retry, fallback, circuit breaker 기준이 있다.
- prompt, model, context source가 versioning된다.
- 권한 없는 데이터가 context에 섞이지 않는 테스트가 있다.
- 비용, 지연, 품질, 보안 이벤트가 관측된다.
- 실패 응답과 프론트 상태 처리가 API 계약에 들어 있다.
연결 문서
- 10. HTTP, Cookie, Session, JWT 지도.md - 인증 정보 전달과 API 상태를 확인한다.
- 13. 인증과 인가 지도 - Session, OAuth, JWT, RBAC.md - context 접근 권한을 검토한다.
- 18. Browser, Frontend, API 호출 지도.md - 프론트 loading/error/retry 상태를 본다.
- 19. API Contract, Error Response, Validation 지도.md - AI 응답과 실패 계약을 정한다.
- 23. Security Threat Model 지도 - Trust Boundary, Attack Surface.md - prompt attack, PII, tool boundary를 확인한다.
- 24. AI LLM 서버 연동 지도 - Prompt, Context, LLM API, Worker, Queue.md - AI/LLM 연동 흐름 전체를 본다.
가져갈 판단 기준
AI 기능은 모델 호출 한 줄이 아니라 웹 백엔드의 운영 흐름이다. 품질, 비용, 지연, 보안, API 계약을 함께 설계해야 출시 후 설명 가능한 기능이 된다.
최종 종합 훈련
상황
새 기능을 출시한다. 사용자가 상품 이미지를 업로드하면 서버가 이미지를 저장하고, 비동기 Worker가 AI 요약과 태그 추천을 만든다. 프론트엔드는 작업 상태를 polling하고, 완료되면 결과를 보여준다. 출시 후 일부 사용자는 timeout을 보고, queue lag가 증가하며, 일부 브라우저에서는 401/CORS 오류가 함께 보인다.
제공된 Evidence
POST /api/products/{id}/images는 p95 1.2s에서 5.8s로 증가했다.- Object Storage upload failure rate가 3 percent로 올랐다.
image.analysis.requestedqueue depth가 42,000까지 증가했다.- Worker DLQ에는
LLM_429,IMAGE_TOO_LARGE,CONTEXT_DENIED가 섞여 있다. - Redis session lookup latency가 평소보다 4배 증가했다.
- Safari 사용자의
/api/me401 rate가 증가했다. - AI provider token cost가 예상치의 2.7배다.
- Kubernetes rollout은 성공으로 표시되지만 새 Pod restart count가 증가한다.
- 최근 변경에는 image size limit 완화, prompt 변경, Ingress timeout 변경, DB migration이 포함되어 있다.
해야 할 일
- 전체 요청 흐름과 비동기 흐름을 분리해 그린다.
- 사용자 영향 SLI를 3개 이상 정의한다.
- 5분 안에 확인할 장애 우선순위를 적는다.
- 임시 복구와 근본 수정을 나눈다.
- 설계 리뷰 관점에서 출시 전 빠졌던 계약을 찾는다.
- 어떤 Web-지도 문서를 어떤 순서로 다시 볼지 복습 경로를 만든다.
먼저 써보기
내 답안
여기에 직접 작성한다.
힌트
이 상황은 하나의 원인으로 접으면 안 된다. 업로드 API의 동기 지연, Object Storage 실패, Queue lag, AI provider 429, Session/CORS 문제, Kubernetes restart, DB migration을 각각 다른 경계로 놓고 시간축을 맞춘다.
해설
먼저 사용자 영향부터 정한다. 예를 들어 이미지 업로드 성공률, 업로드 API p95 latency, 분석 결과 freshness, 로그인 유지 성공률, AI 분석 실패율이 SLI 후보가 된다. 이후 최근 변경과 증상 시작 시각을 맞춘다.
동기 흐름은 Browser -> Edge/Ingress -> WAS -> Object Storage/DB -> Response다. 비동기 흐름은 WAS -> Queue -> Worker -> LLM API/Context Source -> DB/Storage -> polling response다. 로그인 문제는 Cookie, Session Store, CORS, API Client 설정으로 별도 분리한다.
5분 안에는 Ingress timeout 변경, Pod restart, Object Storage failure, queue depth, Worker DLQ 분류, Redis session latency, AI provider 429를 같은 dashboard 시간축에 놓는다. 즉시 복구는 image size limit 되돌리기, prompt version rollback, AI 작업 rate limit, Worker retry backoff 조정, Ingress timeout 원복, 문제 Pod rollout 중단 등이 후보가 된다.
근본 수정은 더 길다. 업로드 크기 제한과 validation 계약, Object Storage timeout/fallback, Queue idempotency와 DLQ 재처리, AI 비용 예산과 provider rate limit, prompt evaluation, Session/CORS 회귀 테스트, Kubernetes probe와 resource limit, DB migration 호환성 검증을 출시 조건에 넣어야 한다.
연결 문서
- 1. 웹 전체 지도.md - 동기 요청, 데이터, 운영 흐름을 큰 그림으로 잡는다.
- 2. Edge 진입 지도 - DNS, CDN, TLS, WAF, LB.md - Ingress와 Edge 실패 위치를 본다.
- 3. Web Server, WAS, Spring MVC 지도.md - Controller, Service, ExceptionHandler 경계를 확인한다.
- 4. 데이터, Redis, 외부 연동 지도.md - Object Storage, Redis, 외부 API를 나눈다.
- 6. 비동기, Scheduler, Batch 지도.md - 긴 작업을 Queue/Worker로 분리한다.
- 8. APM , Backup , 장애 대응 지도.md - Logs, Metrics, Traces로 증거를 연결한다.
- 12. Queue 신뢰성 지도 - Ack, Retry, DLQ, Idempotency.md - DLQ와 retry를 검토한다.
- 15. Kubernetes 지도 - Pod, Deployment, Service, Ingress, ConfigMap, Secret.md - Pod restart와 Ingress 변경을 확인한다.
- 16. 실전 장애 점검 체크리스트 지도.md - 영향 범위와 최근 변경부터 본다.
- 17. 운영 지표와 설계 선택 지도 - SLI, SLO, 임계치, Trade-off.md - SLI/SLO와 임계치를 잡는다.
- 19. API Contract, Error Response, Validation 지도.md - 업로드와 polling API 계약을 정한다.
- 21. System Design 선택 지도 - Cache, Queue, DB, Scale, Consistency.md - 동기/비동기/scale 선택을 검토한다.
- 22. Data Pipeline 지도 - Event, Outbox, CDC, Kafka, Batch.md - 이벤트와 데이터 freshness를 본다.
- 23. Security Threat Model 지도 - Trust Boundary, Attack Surface.md - AI context 권한과 공격 표면을 확인한다.
- 24. AI LLM 서버 연동 지도 - Prompt, Context, LLM API, Worker, Queue.md - AI/LLM 운영 흐름을 본다.
- 25. Web-지도 실전 가이드북.md - 상황별 복습 경로를 다시 잡는다.
가져갈 판단 기준
복합 장애는 하나의 설명으로 빨리 접을수록 위험하다. 동기 요청, 비동기 작업, 인증 상태, 배포 변경, AI provider, 운영 지표를 분리하고 시간축으로 다시 묶는다.
커버리지 지도
| 문서 | 연결된 훈련 | 역할 |
|---|---|---|
| 1. 웹 전체 지도.md | Lab 1, 최종 종합 훈련 | 전체 요청·데이터·운영 흐름 기준점 |
| 2. Edge 진입 지도 - DNS, CDN, TLS, WAF, LB.md | Lab 1, Incident 1, Incident 4, 최종 종합 훈련 | 애플리케이션 앞단 장애 위치 구분 |
| 3. Web Server, WAS, Spring MVC 지도.md | Lab 1, Lab 2, Incident 2, 최종 종합 훈련 | Web Server, WAS, Controller 경계 |
| 4. 데이터, Redis, 외부 연동 지도.md | Lab 1, Lab 3, Incident 2, Incident 3, Review 1, 최종 종합 훈련 | DB, Redis, Storage, 외부 API 의존성 |
| 5. Redis 상세 지도 - Session, Cache, Rate Limit, Lock, Pub-Sub.md | Lab 3, Review 1 | Redis 사용 목적과 장애 fallback |
| 6. 비동기, Scheduler, Batch 지도.md | Lab 3, Incident 3, 최종 종합 훈련 | 동기/비동기 작업 분리 |
| 7. CI.CD , 배포 지도.md | Lab 4, Incident 1, Review 2 | 배포, rollback, migration 판단 |
| 8. APM , Backup , 장애 대응 지도.md | Lab 1, Incident 1, Incident 2, Incident 3, 최종 종합 훈련 | Logs, Metrics, Traces와 복구 흐름 |
| 9. 보안 검증 위치 지도.md | Lab 2, Incident 4 | CORS, Filter, Validation, Response Boundary |
| 10. HTTP, Cookie, Session, JWT 지도.md | Lab 2, Incident 4, Review 3 | HTTP 상태와 인증 정보 운반 |
| 11. DB 트랜잭션, 인덱스, 락 지도.md | Lab 3, Incident 2, Review 1 | 인덱스, 트랜잭션, lock 판단 |
| 12. Queue 신뢰성 지도 - Ack, Retry, DLQ, Idempotency.md | Lab 3, Incident 3, 최종 종합 훈련 | 메시지 신뢰성과 재처리 기준 |
| 13. 인증과 인가 지도 - Session, OAuth, JWT, RBAC.md | Lab 2, Incident 4, Review 3 | 인증과 인가 분리 |
| 14. Docker 지도 - Image, Container, Volume, Network, Compose.md | Lab 4, Review 2 | 컨테이너 실행 단위와 환경 주입 |
| 15. Kubernetes 지도 - Pod, Deployment, Service, Ingress, ConfigMap, Secret.md | Lab 4, Incident 1, Review 2, 최종 종합 훈련 | 클러스터 배포와 트래픽 연결 |
| 16. 실전 장애 점검 체크리스트 지도.md | Lab 4, Incident 1, Review 2, 최종 종합 훈련 | 영향 범위, 최근 변경, 임시 조치 |
| 17. 운영 지표와 설계 선택 지도 - SLI, SLO, 임계치, Trade-off.md | Lab 3, Lab 4, Incident 1, Incident 2, Incident 3, Review 1, Review 2, 최종 종합 훈련 | SLI/SLO, 임계치, 설계 trade-off |
| 18. Browser, Frontend, API 호출 지도.md | Lab 2, Incident 4, Review 3 | 브라우저 API 호출과 화면 상태 |
| 19. API Contract, Error Response, Validation 지도.md | Lab 2, Incident 4, Review 3, 최종 종합 훈련 | API 계약, Validation, Error Response |
| 20. JVM, OS, Thread, Memory 지도.md | Lab 4, Incident 2 | JVM, thread, memory, OS 병목 |
| 21. System Design 선택 지도 - Cache, Queue, DB, Scale, Consistency.md | Lab 3, Incident 2, Incident 3, Review 1, 최종 종합 훈련 | Cache, Queue, DB, scale 선택 기준 |
| 22. Data Pipeline 지도 - Event, Outbox, CDC, Kafka, Batch.md | Lab 3, Incident 3, Review 2, 최종 종합 훈련 | Event, Outbox, Batch, freshness |
| 23. Security Threat Model 지도 - Trust Boundary, Attack Surface.md | Lab 2, Incident 4, Review 3, 최종 종합 훈련 | Trust Boundary와 공격 표면 |
| 24. AI LLM 서버 연동 지도 - Prompt, Context, LLM API, Worker, Queue.md | Review 3, 최종 종합 훈련 | AI/LLM 백엔드 연동과 운영 지표 |
| 25. Web-지도 실전 가이드북.md | 이 문서의 사용법, Lab 1, 최종 종합 훈련 | 상황별 복습 경로와 훈련 전 단계 |
반복 기록표
| 날짜 | 훈련 | 처음 잡은 원인 후보 | 빠뜨린 Evidence | 다시 볼 문서 | 다음 반복 목표 |
|---|---|---|---|---|---|
| Lab 1 | |||||
| Lab 2 | |||||
| Lab 3 | |||||
| Lab 4 | |||||
| Incident 1 | |||||
| Incident 2 | |||||
| Incident 3 | |||||
| Incident 4 | |||||
| Review 1 | |||||
| Review 2 | |||||
| Review 3 | |||||
| 최종 종합 훈련 |