fos-blog/study
01 / 홈02 / 카테고리
01 / 홈02 / 카테고리

카테고리

  • AI 페이지로 이동
    • RAG 페이지로 이동
    • langgraph 페이지로 이동
    • agents.md
    • BMAD Method — AI 에이전트로 애자일 개발하는 방법론
    • Claude Code의 Skill 시스템 - 개발자를 위한 AI 자동화의 새로운 차원
    • Claude Code를 5주 더 쓴 결과 — 스킬·CLAUDE.md를 키워가는 방식
    • Claude Code를 11일 동안 쓴 결과 — 데이터로 본 나의 사용 패턴
    • Claude Code 멀티 에이전트 — Teams
    • AI 에이전트와 디자인의 새 컨벤션 — DESIGN.md, Google Stitch, Claude Design
    • 하네스 엔지니어링 실전 — 4인 에이전트 팀으로 코딩 파이프라인 구축하기
    • 하네스 엔지니어링 — 오래 실행되는 AI 에이전트를 위한 설계
    • 멀티모달 LLM (Multimodal Large Language Model)
    • AI 에이전트와 함께 MVP 만들기 — dooray-cli 사례
  • ai 페이지로 이동
    • agent 페이지로 이동
  • algorithm 페이지로 이동
    • live-coding 페이지로 이동
    • 분산 계산을 위한 알고리즘
  • architecture 페이지로 이동
    • [초안] 시니어 백엔드를 위한 API 설계 실전 스터디 팩 — REST · 멱등성 · 페이지네이션 · 버전 전략
    • [초안] API Versioning과 Backward Compatibility: 시니어 백엔드 관점 정리
    • 캐시 설계 전략 총정리
    • [초안] CJ푸드빌 커머스/F&B 도메인 설계 면접 대비 — 슬롯 경험을 주문·결제·쿠폰·매장 상태 설계로 번역하기
    • [초안] 커머스 Spring 서비스에 Clean/Hexagonal Architecture를 실용적으로 적용하기
    • [초안] 커머스 주문 상태와 데이터 정합성 기본기 — CJ푸드빌 면접 대비
    • [초안] 쿠폰/프로모션 동시성과 정합성 기본기 — 선착순·중복 사용 방지·발급/사용/복구
    • [초안] DDD와 도메인 모델링: 시니어 백엔드 관점의 전술/전략 패턴 실전 가이드
    • [초안] Decorator & Chain of Responsibility — 행동을 체인으로 조립하는 두 가지 방식
    • 디자인 패턴
    • [초안] 분산 아키텍처 완전 정복: Java 백엔드 시니어 인터뷰 대비 실전 가이드
    • [초안] 분산 트랜잭션과 Outbox 패턴 — 왜 2PC를 피하고 어떻게 대신할 것인가
    • 분산 트랜잭션
    • [초안] e-Commerce 주문·결제 도메인 모델링: 상태머신, 멱등성, Outbox/Saga 실전 정리
    • [초안] F&B 쿠폰·프로모션·멤버십·포인트 설계
    • [초안] F&B · e-Commerce 디지털 채널 도메인 한 장 정리 — CJ푸드빌 디지털 채널 백엔드 면접 대비
    • [초안] F&B 주문/매장/픽업 상태머신 설계 — CJ푸드빌 디지털 채널 백엔드 관점
    • [초안] F&B 이커머스 결제·환불·정산 운영 가이드
    • [초안] Hexagonal / Clean Architecture를 Spring 백엔드에 적용하기
    • [초안] 대규모 커머스 트래픽 처리 패턴 — 1,600만 고객과 올영세일을 버티는 설계
    • [초안] 레거시 JSP/jQuery 화면과 신규 API가 공존하는 백엔드 운영 전략
    • [초안] MSA 서비스 간 통신: Redis [Cache-Aside](../database/redis/cache-aside.md) × Kafka 이벤트 하이브리드 설계
    • [초안] Observability 입문: 시니어 백엔드가 장애를 탐지하고 대응하는 방식
    • [초안] Outbox / Inbox Pattern 심화 — 분산 메시징의 정합성 문제를 DB 트랜잭션으로 풀어내기
    • [초안] 결제 도메인 멱등성과 트랜잭션 재시도 기본기
    • [초안] 시니어 백엔드를 위한 Resilience 패턴 실전 가이드 — Timeout, Retry, Circuit Breaker, Bulkhead, Backpressure
    • [초안] REST API 버저닝과 모바일 앱 하위 호환성 — CJ푸드빌 디지털 채널 백엔드 관점
    • [초안] Strategy Pattern — 분기문을 없애는 설계, 시니어 백엔드 인터뷰 핵심 패턴
    • [초안] 시니어 백엔드를 위한 시스템 설계 입문 스터디 팩
    • [초안] 템플릿 메서드 패턴 - 백엔드 처리 골격을 강제하는 가장 오래되고 가장 위험한 패턴
    • [초안] 대규모 트래픽 중 무중단 마이그레이션 — Feature Flag + Shadow Mode 실전
  • database 페이지로 이동
    • mysql 페이지로 이동
    • opensearch 페이지로 이동
    • redis 페이지로 이동
    • 김영한의-실전-데이터베이스-설계 페이지로 이동
    • 커넥션 풀 크기는 얼마나 조정해야 할까?
    • 인덱스 - DB 성능 최적화의 핵심
    • [초안] JPA N+1과 커머스 조회 모델: 주문/메뉴/쿠폰 도메인에서 살아남기
    • [초안] MyBatis 기본기 — XML Mapper, resultMap, 동적 SQL, 운영 패턴 정리
    • [초안] MyBatis와 JPA/Hibernate 트레이드오프 — 레거시 백엔드를 다루는 시니어 관점
    • 역정규화 (Denormalization)
    • 데이터 베이스 정규화
  • devops 페이지로 이동
    • docker 페이지로 이동
    • k8s 페이지로 이동
    • k8s-in-action 페이지로 이동
    • observability 페이지로 이동
    • [초안] 커머스/F&B 채널 장애 첫 5분과 관측성 기본기
    • Envoy Proxy
    • [초안] F&B / e-Commerce 운영 장애 대응과 모니터링 — 백엔드 관점 정리
    • Graceful Shutdown
  • finance 페이지로 이동
    • industry-cycle 페이지로 이동
    • investing 페이지로 이동
    • stock-notes 페이지로 이동
  • http 페이지로 이동
    • HTTP Connection Pool
  • interview 페이지로 이동
    • [초안] AI 서비스 팀 경험 기반 시니어 백엔드 면접 질문 뱅크 — Spring Batch RAG / gRPC graceful shutdown / 전략 패턴 / 12일 AI 웹툰 MVP
    • [초안] CJ푸드빌 디지털 채널 Back-end 개발자 직무 분석
    • [초안] CJ푸드빌 디지털 채널 Back-end 면접 답변집 — 슬롯 도메인 경험을 커머스/F&B 설계로 번역하기
    • [초안] F&B / e-Commerce 운영 모니터링과 장애 대응 인터뷰 정리
    • Observability — 면접 답변 프레임
    • [초안] 시니어 Java 백엔드 면접 마스터 플레이북 — 김병태
    • [초안] NSC 슬롯팀 경험 기반 질문 은행 — 도메인 모델링·동시성·성능·AI 협업
  • java 페이지로 이동
    • concurrency 페이지로 이동
    • jdbc 페이지로 이동
    • opentelemetry 페이지로 이동
    • spring 페이지로 이동
    • spring-batch 페이지로 이동
    • 더_자바_코드를_조작하는_다양한_방법 페이지로 이동
    • [초안] Java 동시성 락 정리 — 커머스 메뉴/프로모션 정책 캐시 갱신 관점
    • [초안] JVM 튜닝 실전: 메모리 구조부터 Virtual Threads, GC 튜닝, 프로파일링까지
    • Java의 로깅 환경
    • MDC (Mapped Diagnostic Context)
    • Java StampedLock — 읽기 폭주에도 쓰기가 밀리지 않는 락
    • Virtual Thread와 Project Loom
  • javascript 페이지로 이동
    • typescript 페이지로 이동
    • AbortController
    • Async Iterator와 제너레이터
    • CommonJS와 ECMAScript Modules
    • 제너레이터(Generator)
    • Http Client
    • Node 백엔드 운영 패턴 — Streams 백프레셔, pipe/pipeline, 멱등성 vs 분산 락
    • Node.js
    • npm vs pnpm — 어떤 기준으로 선택했나
    • `setImmediate()`
  • kafka 페이지로 이동
    • [초안] Kafka 기본 개념 — 토픽, 파티션, 오프셋, 복제
    • Kafka를 사용하여 **데이터 정합성**은 어떻게 유지해야 할까?
    • [초안] Kafka 실전 설계: 파티션 전략, 컨슈머 그룹, 전달 보장, 재시도, 순서 보장 트레이드오프
    • 메시지 전송 신뢰성
  • linux 페이지로 이동
    • fsync — 리눅스 파일 동기화 시스템 콜
    • tmux — Terminal Multiplexer
  • network 페이지로 이동
    • L2(스위치)와 L3(라우터)의 역할 차이
    • L4와 VIP(Virtual IP Address)
    • IP Subnet
  • rabbitmq 페이지로 이동
    • [초안] RabbitMQ Basics — 실전 백엔드 관점에서 정리하는 메시지 브로커 기본기
    • [초안] RabbitMQ vs Kafka — 백엔드 메시징 선택 기준과 실전 운영 관점
  • security 페이지로 이동
    • [초안] 시니어 백엔드를 위한 보안 / 인증 스터디 팩 — Spring Security, JWT, OAuth2, OWASP Top 10
  • task 페이지로 이동
    • ai-service-team 페이지로 이동
    • nsc-slot 페이지로 이동
    • sb-dev-team 페이지로 이동
    • the-future-company 페이지로 이동
  • testing 페이지로 이동
    • [초안] 시니어 Java 백엔드를 위한 테스트 전략 완전 정리 — 피라미드부터 TestContainers, 마이크로벤치, Contract까지
  • travel 페이지로 이동
    • 오사카 3박 4일 일정표: 우메다 쇼핑, USJ, 난바·도톤보리, 오사카성
  • web 페이지로 이동
    • [초안] HTTP / Cookie / Session / Token 인증 기본기 — 레거시 JSP와 모바일 API가 공존하는 백엔드 관점
FOS-BLOG · FOOTERall systems normal·v0.1 · 2026.04.27·seoul, kr
Ffos-blog/study

개발 학습 기록을 정리하는 블로그입니다. 공부하면서 기록하고, 기록하면서 다시 배웁니다.

visitors
01site
  • Home↗
  • Posts↗
  • Categories↗
  • About↗
02policy
  • 소개/about
  • 개인정보처리방침/privacy
  • 연락처/contact
03categories
  • AI↗
  • Algorithm↗
  • DB↗
  • DevOps↗
  • Java/Spring↗
  • JS/TS↗
  • React↗
  • Next.js↗
  • System↗
04connect
  • GitHub@jon890↗
  • Source repositoryjon890/fos-study↗
  • RSS feed/rss.xml↗
  • Newsletter매주 1 회 · 한 편의 글→
© 2026 FOS Study. All posts MIT-licensed.
built with·Next.js·Tailwind v4·Geist·Pretendard·oklch
fos-blog/interview/[초안] F&B / e-Commerce 운영…
system

[초안] F&B / e-Commerce 운영 모니터링과 장애 대응 인터뷰 정리

CJ푸드빌 디지털 채널처럼 오프라인 매장과 온라인 주문이 직접 결합된 F&B 도메인은 "기능 구현"보다 "운영 안정성"이 곧 매출이다. 점심 12시, 저녁 6시, 금요일 저녁, 시즌 프로모션 오픈 5분 같은 순간에 트래픽이 평소 대비 5\20배 튀고, 같은 시점에 매장 POS, 배달 플랫폼 연동, PG, 쿠폰 발급, 알림이 동시에 부하를 받는다. 한 번의...

2026.05.09·15 min read·9 views

왜 이 주제가 중요한가

CJ푸드빌 디지털 채널처럼 오프라인 매장과 온라인 주문이 직접 결합된 F&B 도메인은 "기능 구현"보다 "운영 안정성"이 곧 매출이다. 점심 12시, 저녁 6시, 금요일 저녁, 시즌 프로모션 오픈 5분 같은 순간에 트래픽이 평소 대비 5~20배 튀고, 같은 시점에 매장 POS, 배달 플랫폼 연동, PG, 쿠폰 발급, 알림이 동시에 부하를 받는다. 한 번의 503, 한 번의 결제 중복, 한 번의 재고 불일치는 곧장 환불 처리, CS 폭주, 매장 직원의 수기 처리, 그리고 다음 분기 예약률 하락으로 이어진다.

따라서 이 도메인의 시니어 백엔드 면접에서는 "어떻게 짰는가"보다 "터졌을 때 어떻게 알아채고, 첫 5분 동안 무엇을 보며, 무엇을 끄고, 어떻게 살리는가"를 본다. 모니터링 지표, 알림 기준, traceId 기반 분산 디버깅, graceful shutdown 같은 것이 모두 이 질문의 가지다. 이 문서는 그 질문 묶음을 운영형 백엔드 관점에서 한 번에 정리한다.

F&B / e-Commerce 트래픽의 구조적 특징

일반 SaaS와 달리 F&B 디지털 채널의 트래픽에는 정해진 모양이 있다.

  • 시간대 피크: 식사 시간 직전 10~20분, 점심 11:30~12:30, 저녁 17:30~19:00. 트래픽 곡선이 가파른 산봉우리 모양이다.
  • 이벤트 피크: 쿠폰 오픈, 한정 메뉴 오픈, 카드사 제휴 시점. 분 단위로 1만~10만 RPS 급격한 스파이크.
  • 결제 집중: 장바구니 → 주문 → 결제 트랜잭션이 한 번에 몰린다. PG 응답 지연 한 번이 곧장 ALB의 백로그로 쌓인다.
  • 연동 의존성: 주문은 우리 도메인에서 끝나지 않는다. 매장 POS, 주방 KDS, 배달 라이더 콜, 쿠폰 시스템, PG, 알림(SMS/카카오), CRM 마일리지 적립까지 외부/내부 시스템 5~10개와 줄줄이 연결된다.
  • 직원 채널 동반: 매장 점주/직원이 쓰는 백오피스, 키오스크, POS도 같은 백엔드에 의존한다. 고객 채널만 죽지 않고 운영 채널이 같이 죽는다.

이 구조적 특징을 모르면 모니터링 지표 설계가 추상적이 된다. CPU 70%가 위험한 게 아니라, **"점심 피크 5분 전 PG 응답시간이 평소 평균을 넘는 것"**이 위험하다.

핵심 지표 — 무엇을 봐야 하는가

운영형 백엔드의 모니터링 지표는 RED + USE + 도메인 KPI 3계층으로 본다.

1. RED (요청 측면)

  • Rate: 초당 요청 수, 엔드포인트별. 주문/결제/조회를 분리.
  • Errors: 5xx, 4xx 분리. 4xx는 정상이지만 4xx가 평소의 5배면 클라이언트 버그/어뷰징 신호.
  • Duration: p50, p95, p99. 평균은 거의 쓸모 없다. p99가 평소 300ms → 1.5s로 뛰면 큐 백로그가 차고 있다는 뜻이다.

p50 / p95 / p99는 무엇을 말하는가

응답 시간 지표를 볼 때 평균만 보면 위험하다. 평균은 일부 매우 느린 요청을 희석하고, 반대로 일부 극단값에 과하게 끌려갈 수도 있다. 그래서 운영에서는 응답 시간의 분포를 보고, 그 분포를 대표하는 백분위 지표를 함께 본다.

  • p50: 전체 요청 중 50%가 이 시간 안에 끝난다는 뜻이다. 중앙값에 가깝다. 일반 사용자가 평소에 느끼는 체감 속도를 볼 때 쓴다. p50이 나빠졌다면 시스템 전반이 느려졌을 가능성이 크다.
  • p95: 전체 요청 중 95%가 이 시간 안에 끝난다는 뜻이다. 느린 사용자 5%의 경험을 보는 지표다. 커머스에서는 주문/결제/쿠폰 API의 p95가 튀면 일부 사용자에게 이미 불편이 발생하고 있다고 본다.
  • p99: 전체 요청 중 99%가 이 시간 안에 끝난다는 뜻이다. 가장 느린 1%에 가까운 tail latency다. p99는 장애의 전조를 잘 보여준다. DB 커넥션 대기, 외부 PG 지연, POS ack 지연, Redis hot key, GC pause처럼 일부 요청만 길게 밀리는 문제가 여기서 먼저 보인다.

예를 들어 주문 API가 다음과 같다고 하자.

text
p50 = 120ms
p95 = 450ms
p99 = 2.8s
평균 = 180ms

평균과 p50만 보면 괜찮아 보인다. 하지만 p99가 2.8초라면 일부 사용자는 결제 버튼을 누른 뒤 꽤 오래 기다리고 있고, 모바일 앱에서는 재시도 버튼을 누르거나 중복 요청을 만들 수 있다. F&B/e-Commerce에서는 이 tail latency가 곧 중복 결제, 주문 상태 불일치, POS 전달 지연, CS 증가로 이어진다.

지표 해석 순서는 보통 이렇게 잡는다.

  1. p50도 같이 나빠졌는가?
    • 그렇다면 전체 시스템 부하, DB 전반 병목, 배포 regression을 의심한다.
  2. p50은 정상인데 p95/p99만 튀는가?
    • 특정 엔드포인트, 특정 매장, 특정 PG, 특정 쿠폰 이벤트, 일부 DB 쿼리, 외부 연동 지연을 의심한다.
  3. p99가 튀면서 error rate도 같이 오르는가?
    • timeout, connection pool 포화, thread pool saturation, circuit breaker open 같은 장애 전이를 의심한다.
  4. p99만 튀고 error는 아직 정상인가?
    • 아직 장애는 아니지만 곧 실패율로 번질 수 있는 조기 신호다. 피크타임 전이면 알림 민감도를 높이고, 외부 의존성별 latency를 쪼개 본다.

면접에서는 이렇게 답변하면 좋다.

평균 응답 시간은 사용자 경험을 충분히 설명하지 못하기 때문에 p50/p95/p99를 같이 봅니다. p50은 일반 사용자 체감, p95는 느린 사용자군, p99는 tail latency와 장애 전조를 보기 위한 지표입니다. 예를 들어 주문 API의 p50은 정상인데 p99만 튄다면 전체 서버가 느린 게 아니라 특정 외부 의존성, DB 커넥션 대기, 일부 매장/POS 연동, 쿠폰 이벤트 같은 tail 원인을 먼저 의심합니다. 특히 결제나 주문에서는 p99 상승이 중복 요청과 CS로 이어질 수 있어서 error rate가 오르기 전에 먼저 봐야 합니다.

2. USE (자원 측면)

  • Utilization: CPU, 메모리, 커넥션 풀 사용률, 스레드 풀 사용률. JVM 백엔드는 GC time과 thread blocked count가 추가 핵심.
  • Saturation: 큐 깊이, DB 커넥션 대기, Redis pipeline 대기.
  • Errors: timeout, connection reset, GC overhead 경고.

3. 도메인 KPI

  • 주문 성공률 (= 결제 완료된 주문 / 결제 시도된 주문)
  • 결제 지연 분포 (PG별로 나눠서)
  • 쿠폰 발급 성공률, 재고 차감 실패율
  • 알림 발송 성공률 (카카오/SMS 분리)
  • POS 연동 ack 지연
  • CS 인입 건수 / CS 키워드 분포 (운영팀 채널과 연동)

가장 빠른 이상 신호는 보통 도메인 KPI에서 먼저 나온다. CPU가 80%로 오르기 전에 "주문 성공률이 99.7% → 98.2%로 떨어졌다"가 먼저 잡힌다. 그래서 KPI 알림을 가장 민감한 SLO로 묶어두는 것이 실전에서 효과가 크다.

알림 기준 설계 — 시끄러운 알림은 알림이 아니다

알림 정책에서 가장 흔한 실수는 "에러 1개라도 발생하면 알림"이다. 이러면 며칠 안에 모든 알림이 무시된다. 운영 가능한 알림 기준은 다음 원칙으로 설계한다.

  • SLO 기반 burn rate 알림: "최근 5분 에러율이 1시간 SLO 예산의 14배를 태우고 있음" 같은 burn rate 형식. Google SRE의 multi-window multi-burn-rate 패턴.
  • 도메인 KPI는 절대값 + 비율: "주문 성공률 99% 미만 5분 지속" + "분당 실패 건수 100건 초과".
  • 외부 의존성은 분리: PG 응답 5초 초과율, POS ack 지연율은 시스템 자체 알림과 별도 채널로 보낸다.
  • 노이즈 차단: 단일 인스턴스 장애는 P3, 전체 클러스터 영향은 P1. 호출 채널을 SMS/슬랙/PagerDuty로 분리.
  • "의미 있는 회복"까지 알림 유지: 단발 spike로 자동 해제되지 않게 hysteresis(예: 회복 5분 지속 시 close).

피크타임 직전 30분은 보통 민감도를 임시로 높이는 alerting window를 두는 곳도 있다. 푸드 도메인은 11:00~12:30 윈도우에 결제 지연 알림 임계치를 평소의 절반으로 내리는 식이다.

대시보드 구성 — 한 화면에서 결정 가능해야 한다

장애 대응 대시보드는 "예쁜 그래프"가 아니라 "5분 안에 어디를 끌지를 결정"하는 도구다. 권장 레이아웃은 다음과 같다.

상단 한 줄에 "오늘의 비즈니스 신호": 주문 성공률, 결제 성공률, 분당 매출, CS 인입 수. 바로 아래에 트래픽 RED: 엔드포인트별 RPS / 5xx / p99. 그 아래에 외부 의존성: PG 응답시간/실패율, POS ack 지연, 알림 발송 성공률, 쿠폰 시스템 응답. 그 아래에 자원: 인스턴스 CPU/메모리, JVM heap/GC, DB 커넥션 풀, Redis latency. 좌측에는 배포/플래그/스위치 상태 보드: 최근 배포 시각, 활성 feature flag, kill switch 상태.

이 레이아웃을 지키면 알림 슬랙 메시지를 클릭한 사람이 30초 안에 "PG가 흔들리는지, 우리 서버가 흔들리는지, 트래픽이 돈 건지"를 분리할 수 있다.

로그와 traceId — 분산 디버깅의 뼈대

운영형 백엔드는 로그 자체보다 "한 요청의 흐름을 끝까지 따라갈 수 있는 능력"이 중요하다.

  • 모든 요청 진입에서 traceId 생성. 외부에서 들어온 X-Request-Id가 있으면 그것을 우선 채택해 외부 로그와도 맞춘다.
  • traceId는 MDC(또는 동등한 컨텍스트)로 모든 로그 라인에 박는다.
  • 비동기 처리, 메시지 큐, 배치로 넘어갈 때 traceId를 페이로드에 같이 실어 보낸다. traceId 재전송이 끊기는 지점이 보통 사고 분석을 가장 어렵게 한다.
  • 외부 호출(PG, POS, 쿠폰)에는 traceId를 헤더로 같이 보내고, 외부에서 받은 응답의 식별자(승인번호 등)를 traceId와 묶어 다시 로깅한다.
  • 로그 레벨 외에 이벤트 로그(주문 생성, 결제 승인, 환불, 알림 발송)는 별도 토픽 또는 별도 인덱스로 보관해 비즈니스 분석에서 다시 쓸 수 있게 한다.

후보자 본인의 경험에서 **"서비스 간 호출에서 traceId가 끊기던 것을 헤더 표준화 + 재전송으로 복구한 사례"**는 이 도메인 면접에서 매우 강한 자산이다. 매장 POS와 디지털 채널, PG, 알림으로 이어지는 다중 hop 시스템에서는 traceId 표준화 자체가 운영 도구의 절반이다.

장애 대응 첫 5분 플레이북

알림이 울렸을 때, 시니어 백엔드가 첫 5분에 해야 하는 행동은 정해져 있다. 이 순서를 외워두는 것 자체가 인터뷰 답변의 골격이 된다.

  1. 분류(0~30초): P1인지, 비즈니스에 직결되는지, 채널 단위 영향인지 빠르게 판단. CS 알림과 도메인 KPI 알림이 같이 울리면 P1로 가정.
  2. 범위 식별(30초~2분): 대시보드에서 "사용자 영향이 있는가, 어떤 채널/엔드포인트인가, 외부 의존성인가, 우리 인프라인가"를 분리.
  3. 출혈 멈추기(2~4분): 답이 명확하면 즉시 적용. 결제 PG가 흔들리면 보조 PG로 라우팅 또는 retry 정책 임시 변경. 특정 엔드포인트가 폭주하면 rate limit / circuit breaker 켜기. 캐시 불일치면 hot key invalidate. 새 배포 후 문제면 즉시 롤백.
  4. 공유(4분~): 대응 채널에 traceId 샘플, 영향 범위, 출혈 차단 조치, 다음 단계 시각을 명시. **"무엇을 모르는가"**도 명시.
  5. 근본 원인은 그 다음이다. 출혈을 멈추기 전 원인 분석에 들어가면 영향이 커진다.

후보자가 가지고 있는 graceful shutdown으로 503을 잡은 경험은 이 첫 5분 플레이북에서 "재배포가 트래픽 피크와 겹쳐 503이 튄다"라는 흔한 시나리오를 직접 막아본 경험으로 활용된다. 인터뷰 답변에서는 "배포 시 503"이라는 보편 문제를 풀기 위해 어떤 순서로 무엇을 측정하고 어떻게 종료 신호를 받아 in-flight 요청을 보호했는지를 단계로 풀어 설명한다.

시나리오별 대응 패턴

1. 피크타임 트래픽 + 503

증상: 12:00에 5xx가 튄다. p99가 평소 300ms → 3s. 의심: 커넥션 풀 포화, 외부 호출 동기 블로킹, GC pause, autoscale 지연. 대응: rate limit으로 비핵심 트래픽 차단(추천 영역, 비핵심 추천 API), 결제/주문 라인은 우선순위 큐로 보호. autoscale min replica 상향. 향후: 피크 30분 전 사전 워밍업, scheduled scaling.

2. 이벤트/쿠폰 오픈 스파이크

증상: 정시 0초에 RPS 폭증, 쿠폰 발급 실패 다수. 의심: 단일 row 갱신 경합, Redis 단일 키 hot key, DB lock 대기. 대응: 발급 카운터를 Redis INCR + Lua로 단일 atomic 처리, 사전에 발급 슬롯을 예할당, 대기열 페이지로 트래픽 평활화, "soft open" 분산. 코드 레벨에서는 비관락 대신 INCR + 한도 체크 패턴.

3. 매장 POS 연동 장애

증상: 디지털 채널은 정상이지만 매장 KDS에 주문이 안 뜬다. 의심: POS 게이트웨이 이슈, 메시지 브로커 컨슈머 lag, 매장 네트워크. 대응: 우리 측에서 outbox 패턴으로 보관되어 있어야 함. 컨슈머 lag 즉시 확인, 재처리 가능한 멱등 ack 구조 확인. 매장 측 장애라면 점주 백오피스에 수동 push 채널 제공. 핵심은 주문 상태 머신이 외부 ack 실패에도 무너지지 않게 설계되어 있어야 한다는 것.

4. PG 장애

증상: 결제 응답 시간 지연, 일부 결제 timeout. 의심: PG 한쪽 채널 이슈, 우리 timeout 설정 너무 길음, 동시 retry 폭주. 대응: 보조 PG로 라우팅 룰 변경, retry 즉시 백오프 강화, 사용자에겐 "잠시 후 다시" 안내로 회피. 가장 위험한 것은 중복 결제이므로 PG 호출은 반드시 idempotency key 기반이어야 하고, timeout이 나도 "결제 시도가 성공했을 수 있음"을 가정하는 reconcile 배치가 있어야 한다.

5. 알림 장애

증상: 카카오 알림톡 미발송, 사용자 "주문 들어갔는지 모르겠다" CS 폭증. 의심: 외부 알림 게이트웨이 장애, 우리 큐 컨슈머 정지, 템플릿 거절. 대응: SMS fallback, 인앱 푸시 fallback, 마이페이지 주문 상태 노출 강화. 알림은 best-effort라도 주문 상태 자체는 정확해야 한다는 원칙 유지.

6. 재고/품절 동기화 지연

증상: 매장 재고 0인데 주문이 들어옴. 의심: 재고 갱신 이벤트 컨슈머 lag, 캐시 TTL 너무 김, write-through 누락. 대응: 핫 SKU만 짧은 TTL 또는 즉시 invalidate, 결제 직전 재검증(double check) 단계 추가. 일정 비율 이상은 자동 환불 + 보상 쿠폰 정책으로 CS 부담을 줄인다.

7. 캐시 불일치

증상: 가격이 잘못 보임, 메뉴 노출 누락. 의심: write-back 누락, 캐시 stampede, 다중 인스턴스 invalidate 누락. 대응: 핵심 도메인은 write-through + 짧은 TTL 조합, 노출 단계에서 가격은 결제 직전 한 번 더 원본 검증. cache key versioning으로 한 번에 무효화 가능한 구조.

후보자의 캐시 정합성 관련 개선 경험은 이 시나리오에서 직접 답변 자산으로 쓰인다. "정합성 보장이 필요한 도메인에서는 캐시를 가격의 진실 소스로 두지 않는다"는 원칙을 본인 경험으로 설명할 수 있다.

8. 배치 실패

증상: 정산 배치 0% 진행, 다음 날 매장 정산 영향. 의심: 새벽 DB 유지보수와 충돌, 외부 시스템 응답 변경, 데이터 skew. 대응: 재시도 가능한 청크 단위 설계, checkpoint 기반 resume, 알림은 단순 실패가 아니라 "누락된 정산 매장 N개"처럼 비즈니스 영향으로 표현.

9. CS 인입 폭증

증상: 시스템 지표는 정상인데 CS 채널이 분당 30건씩 들어온다. 의심: 사용자 가시 영역 버그, 결제는 됐으나 안내 누락, 특정 디바이스 이슈. 대응: CS 키워드 클러스터링이 운영 대시보드에 노출되어야 한다. 시스템 지표만 보면 놓치는 P1이 여기서 자주 나온다.

Bad vs Improved 예제

Bad

java
@PostMapping("/orders")
public OrderResponse create(@RequestBody OrderRequest req) {
    Order order = orderService.create(req);
    pgClient.pay(order);
    notificationClient.send(order);
    posClient.push(order);
    return OrderResponse.from(order);
}

문제점: 외부 호출 4개를 동기로 직렬 호출. PG 1개 느려지면 전체 응답 시간 급증. 알림 실패 = 주문 실패. POS 실패 = 결제까지 롤백되거나 inconsistency. retry/timeout/idempotency 전혀 없음. traceId 재전송 없음.

Improved

java
@PostMapping("/orders")
public OrderResponse create(@RequestBody OrderRequest req,
                            @RequestHeader(value = "X-Request-Id", required = false) String reqId) {
    String traceId = traceContext.bindOrCreate(reqId);
 
    Order order = orderService.createPending(req, traceId);
    PaymentResult pay = pgClient.payWithIdempotency(order, traceId);
 
    if (!pay.isApproved()) {
        orderService.markFailed(order, pay);
        return OrderResponse.failed(order, pay);
    }
 
    orderService.markPaid(order, pay);
    outbox.enqueueOrderPaid(order, traceId);
 
    return OrderResponse.success(order);
}

핵심: 결제만 동기, 알림과 POS push는 outbox로 비동기. 결제는 idempotency key로 중복 방지. traceId를 헤더에서 채택해 모든 외부 호출에 재전송. 주문 상태는 pending → paid로 명시적 머신.

로컬 실습 환경

다음 구성을 docker-compose로 띄워 한 번 돌려보면 운영 감각이 빠르게 잡힌다.

  • Spring Boot 3 / Java 21 백엔드 1대
  • MySQL 8 (orders, payments, inventory)
  • Redis 7 (재고 카운터, 쿠폰 카운터, traceId 캐시)
  • Kafka 1대 (orders.paid 토픽)
  • Prometheus + Grafana
  • 가짜 PG 서버 (응답 지연/실패율을 환경변수로 주입 가능한 wiremock 또는 자작 mock)
  • k6 또는 gatling으로 피크타임 시뮬레이션

실행 가능한 실습 시나리오

  1. k6로 baseline 100 RPS, 1분 후 피크 1000 RPS로 램프업하면서 p99 / 5xx / 주문 성공률을 Grafana로 본다.
  2. 가짜 PG에 50% 지연(2초)을 주입한 상태에서 동일 부하를 다시 돌리고, retry 정책이 없을 때와 idempotency + 짧은 timeout일 때의 차이를 측정한다.
  3. Redis hot key(인기 메뉴 SKU 1개)를 만들고, INCR 기반 재고 차감 vs SELECT FOR UPDATE 기반 재고 차감의 처리량과 실패율을 비교한다.
  4. 배포 시뮬레이션: SIGTERM을 백엔드에 보내서 graceful shutdown 동작을 확인한다. in-flight 요청이 끊기는지, ALB/Ingress drain 시간이 충분한지, readiness probe가 먼저 fail로 빠지는지 검증한다. 503이 사용자에게 노출되는 구간을 측정하고 개선한다.
  5. Kafka 컨슈머를 일부러 멈추고 lag을 만든다. 알림 outbox가 쌓이는 동안 사용자에게 보이는 영향(주문 상태는 정상, 알림만 지연)을 확인한다.
  6. traceId가 끊기는 케이스를 의도적으로 만든다(MDC를 비동기 작업에 전달하지 않는 코드). 로그로 한 요청을 끝까지 따라갈 수 없다는 것을 직접 경험한 뒤, MDC propagation 방법으로 복구한다.

Postmortem과 재발 방지

장애 후 24~48시간 안에 postmortem을 쓴다. 항목:

  • 타임라인: traceId, 알림 시각, 인지 시각, 출혈 차단 시각, 회복 시각.
  • 사용자 영향: 영향 받은 주문 수, 결제 금액, 환불/보상 처리 건수.
  • 근본 원인: 단일 원인이 아닌 contributing factors까지 (배포 + 피크 + retry storm 같이).
  • 잘 동작한 것: 이게 빠지면 다음에 같은 보호 장치가 없어진다.
  • 재발 방지 액션: owner, 기한, 검증 방법까지 포함. 막연한 "모니터링 강화" 금지. "PG timeout 5s → 2s, 보조 PG fallback 룰 추가, k6 회귀 시나리오에 PG 장애 케이스 포함" 식으로 구체.

비난 없는(blameless) 톤을 유지하되, 시스템적 개선으로 결론 내야 한다.

면접 답변 프레이밍

이 도메인의 시니어 백엔드 면접에서 자주 나오는 질문과 답변 구조를 정리한다.

Q. 피크 시간 503이 튀는 상황을 어떻게 잡으세요?

답변 구조: (1) 먼저 503의 출처를 분리한다 — ALB/Ingress 단의 5xx와 애플리케이션 5xx, 그리고 graceful shutdown 시점의 5xx. (2) 본인이 직접 graceful shutdown 도입으로 503을 줄였던 사례를 짧게 인용 — readiness probe를 먼저 떨어뜨리고, in-flight 요청을 일정 시간 보호한 뒤 종료한 구조. (3) 그 다음 단계로 autoscale, 커넥션 풀, 외부 호출 timeout 검토 순서.

Q. 캐시 정합성을 어떻게 보장하나요?

답변 구조: (1) 캐시는 진실의 소스가 아니라 가속 계층이라는 원칙. (2) write-through + 짧은 TTL + key versioning. (3) 가격/재고처럼 정합성이 비즈니스에 직결되는 도메인은 결제 직전 원본 재검증. (4) 본인 캐시 정합성 개선 경험을 trade-off 설명과 함께 인용 — 어떤 데이터는 정합성보다 가용성을 우선했고, 어떤 데이터는 반대였다는 식으로.

Q. 분산 시스템에서 한 요청을 어떻게 추적하세요?

답변 구조: (1) traceId를 진입 시점에 생성하거나 외부 X-Request-Id를 채택. (2) MDC로 모든 동기 로그에 박고, 큐/배치/외부 호출에는 페이로드/헤더로 재전송. (3) 본인이 traceId 끊김을 표준화/재전송으로 복구한 사례 인용. (4) 모니터링 단계에서 traceId 기반 샘플 trace를 알림 메시지에 자동 첨부.

Q. 결제 중복을 어떻게 막나요?

답변 구조: (1) 클라이언트가 보낸 idempotency key 또는 서버 생성 key를 PG 호출에 사용. (2) timeout이 발생해도 "결제 미완료 = 실패"로 가정하지 않고 reconcile 배치로 PG 측 상태 재확인. (3) 주문 상태 머신을 명확히 — pending / authorizing / paid / failed / refunded.

Q. 한정 쿠폰 1만 장 오픈을 어떻게 받나요?

답변 구조: (1) DB row lock 기반은 같은 row 경합으로 죽는다. (2) Redis INCR + Lua로 atomic 한도 체크, 발급 성공자만 DB에 비동기 기록. (3) 대기열 페이지로 트래픽 평활화. (4) 발급 실패자에게 명확한 안내, 어뷰징 차단(IP/계정 단위 rate limit).

Q. 장애가 났을 때 첫 5분 동안 무엇을 하세요?

답변 구조: 위의 5분 플레이북을 그대로 — 분류 → 범위 식별 → 출혈 차단 → 공유 → 그 다음 근본 원인. "원인부터 보면 사용자 피해가 커진다"는 원칙을 앞에 둔다.

Q. 운영 채널과 고객 채널이 같이 영향을 받을 때 우선순위는?

답변 구조: (1) 매출에 직결되는 결제/주문이 최우선. (2) 매장 직원 채널은 서비스 지속을 위해 보호. (3) 마케팅/추천/비핵심 API는 가장 먼저 끄거나 회로 차단. (4) feature flag와 kill switch가 사전에 준비되어 있어야 한다.

체크리스트

  • RED + USE + 도메인 KPI 3계층 모니터링이 있다.
  • 알림은 SLO burn rate 기반이며 단발 spike에 자동 close 되지 않는다.
  • 피크 시간대 임시 sensitivity window가 있다.
  • traceId가 외부 호출, 큐, 배치 끝까지 propagate 된다.
  • 결제는 idempotency key 기반이며 reconcile 배치가 있다.
  • PG/POS/알림은 fallback 또는 outbox로 보호된다.
  • graceful shutdown이 readiness probe + in-flight 보호 + drain 시간으로 구성되어 있다.
  • 캐시는 짧은 TTL + 핵심 도메인 결제 직전 재검증을 한다.
  • 한정 쿠폰/한정 메뉴는 INCR 기반 atomic 발급으로 처리한다.
  • 대시보드 한 화면에서 비즈니스 신호 → RED → 외부 의존성 → 자원 → 배포 상태 순으로 보인다.
  • postmortem은 blameless이고 액션 항목에 owner/기한/검증 방법이 있다.
  • feature flag와 kill switch가 비핵심 기능에 깔려 있다.
  • 배포는 피크 시간을 피하거나, 피해야 한다면 카나리 + 빠른 롤백이 준비되어 있다.
  • CS 인입 키워드가 운영 대시보드에 함께 보인다.
on this page
  • 01왜 이 주제가 중요한가
  • 02F&B / e-Commerce 트래픽의 구조적 특징
  • 03핵심 지표 — 무엇을 봐야 하는가
  • 1. RED (요청 측면)
  • 2. USE (자원 측면)
  • 3. 도메인 KPI
  • 04알림 기준 설계 — 시끄러운 알림은 알림이 아니다
  • 05대시보드 구성 — 한 화면에서 결정 가능해야 한다
  • 06로그와 traceId — 분산 디버깅의 뼈대
  • 07장애 대응 첫 5분 플레이북
  • 08시나리오별 대응 패턴
  • 1. 피크타임 트래픽 + 503
  • 2. 이벤트/쿠폰 오픈 스파이크
  • 3. 매장 POS 연동 장애
  • 4. PG 장애
  • 5. 알림 장애
  • 6. 재고/품절 동기화 지연
  • 7. 캐시 불일치
  • 8. 배치 실패
  • 9. CS 인입 폭증
  • 09Bad vs Improved 예제
  • Bad
  • Improved
  • 10로컬 실습 환경
  • 11실행 가능한 실습 시나리오
  • 12Postmortem과 재발 방지
  • 13면접 답변 프레이밍
  • Q. 피크 시간 503이 튀는 상황을 어떻게 잡으세요?
  • Q. 캐시 정합성을 어떻게 보장하나요?
  • Q. 분산 시스템에서 한 요청을 어떻게 추적하세요?
  • Q. 결제 중복을 어떻게 막나요?
  • Q. 한정 쿠폰 1만 장 오픈을 어떻게 받나요?
  • Q. 장애가 났을 때 첫 5분 동안 무엇을 하세요?
  • Q. 운영 채널과 고객 채널이 같이 영향을 받을 때 우선순위는?
  • 14체크리스트

댓글 (0)