장애 대응과 관측
주제 허브

느린 외부 기관 하나가 전체를 멈추지 못하게 할 수 있나

장애 대응과 관측

서킷 브레이커와 벌크헤드, 타임아웃과 재시도 예산, 장애 주입 실험, 그리고 문제를 찾아 준 로그와 추적. 장애를 겪은 뒤 쓴 글과 장애를 막기 위해 설계한 글을 함께 둔다.

84편 직접 만들고 재 본 것 68 기술 블로그 리뷰 7 컨퍼런스 발표 리뷰 9 최근 글

직접 만들고 재 본 것

68편
  1. ParityPay로 검증하는 결제 정합성 9 - 느린 기관 앞에서 결제 서버를 지키기: 타임아웃, 재시도, 차단기, 리미터, 벌크헤드가 각각 무엇을 막는가
  2. Circuit Breaker로 외부 API 장애 격리 — Resilience4j + KIS·Yahoo 폴백 체인
  3. OpenTelemetry + Jaeger로 분산 추적 — 시세 파이프라인 지연 측정
  4. 무너지는 Spring 서버 1 - CPU는 놀고 있는데 API가 느리다: 업스트림 하나가 무관한 엔드포인트를 죽이는 과정을 thread dump 세 장으로 읽기
  5. TLS 핸드셰이크의 비용 - 세션 재개와 0-RTT의 대가
  6. 타임아웃, 재시도, 백오프 - 증폭과 지터, 그리고 데드라인 전파
  7. 커넥션과 세션 - 커넥션 풀이 실제로 아끼는 것
  8. HTTP/1.1, 2, 3 - HOL 블로킹은 어디로 옮겨갔는가
  9. 큐잉 이론 한 조각 - 도착률과 서비스율로 파라미터를 정하기
  10. 혼잡 제어와 지연 - BDP, 버퍼블로트, 처리량과 지연의 교환
  11. JIT 컴파일 - 계층 컴파일, 인라이닝, 역최적화
  12. WebSocket push와 REST polling을 클라이언트 1만 개에서 재다 — 지연과 서버 비용, Kafka 정지 45초, 느린 소비자 25개
  13. 가상 스레드를 켜서 37배 느려진 엔드포인트 - 핀닝과 상한 없는 admission을 재다
  14. 트레이스 샘플링 - 헤드와 테일 샘플링의 선택 기준
  15. TCP 연결 수립과 큐 - SYN 백로그, accept 큐, TIME_WAIT
  16. G1과 ZGC가 p99에 남기는 차이 - 300배 짧은 pause가 꼬리의 11%를 가져갔다
  17. GC 알고리즘 비교 - G1, ZGC, Shenandoah가 각자 무엇을 포기하는가
  18. 멱등성 설계 - 키의 단위와 저장 위치, 만료와 재시도 계약
  19. 토스증권 Kafka 데이터센터 이중화 리뷰: 미러링보다 오프셋이 어렵고, 재난과 작업의 기준이 다르다
  20. RED와 USE - 어디에 무엇을 붙이는가
  21. 토스증권 공개 자료로 읽는 시세·주문 아키텍처: 무엇을 잃어도 되는지 먼저 정한다
  22. epoll - select, poll과의 차이와 edge, level 트리거
  23. Spring Batch의 구조 - 청크, 파티셔닝, 재시작과 메타데이터
  24. 가상 스레드의 내부 - 스케줄러와 캐리어, 핀닝, 그리고 쓰지 않아야 할 때
  25. Redis 단일 스레드가 멈추는 순간 - SCAN이 3.7배 오래 걸리면서 아무도 막지 않고, 120ms 멈춤이 p99에 안 잡히는 이유
  26. ParityPay로 검증하는 결제 정합성 10 - 락 lease가 트랜잭션보다 먼저 끝나면 정말 정합성이 깨지는가: SETNX 락, Watchdog, fencing token, 그리고 락 없는 구조의 실측
  27. ParityPay로 검증하는 결제 정합성 8 - Kafka에서 중복·유실·순서 역전을 직접 만들어 보기: 멱등 소비자와 Outbox가 막는 것과 못 막는 것
  28. 캐시 스탬피드와 single flight - 200명 중 125명이 원본까지 갔고, 예외를 삼키자 실패가 가장 빠른 요청이 됐다
  29. 백분위 통계 - 평균이 거짓말하는 이유와 히스토그램의 집계 오류
  30. ParityPay로 검증하는 결제 정합성 6 - 대사: "기관에 물어보지 못했다"와 "기관에 기록이 없다"는 다른 상태다
  31. 키 생성 병목을 추적해 구조를 바꾼 기록: Part 2 - SELECT 안에서 UPDATE가 일어나고 있었다
  32. 페이지 캐시와 파일 IO - buffered와 direct, fsync가 실제로 하는 일
  33. ParityPay로 검증하는 결제 정합성 5 - DB 커밋과 Kafka 발행 사이: Transactional Outbox와 at-least-once 소비자
  34. 동시성 도구의 비용 - synchronized, ReentrantLock, CAS가 경쟁에서 갈리는 지점
  35. ParityPay로 검증하는 결제 정합성 4 - 실험 27종이 찾아낸 결함 12건: 문서와 코드를 읽어서 나온 것은 하나도 없었다
  36. Postgres 커넥션 하나의 비용 - 풀을 키우면 대기가 사라지는 게 아니라 볼 수 없는 곳으로 옮겨간다
  37. ParityPay로 검증하는 결제 정합성 3 - 외부 승인 응답이 사라졌을 때: 타임아웃은 실패가 아니다
  38. ParityPay로 검증하는 결제 정합성 2 - 잠금을 필요 이상으로 오래 쥐고 있었다: 추론을 측정으로 바꾼 기록
  39. 멱등한 API 설계 - HTTP 메서드의 의미와 재시도 계약
  40. 2021년의 결제대행 API 연동을 2026년의 질문으로 다시 보기
  41. 메트릭, 로그, 트레이스 - 무엇을 어디에 남기고 카디널리티는 어디서 터지는가
  42. 컨텍스트 스위칭과 스케줄링 - CFS, cgroup CPU 제한, 그리고 스로틀링
  43. 키 생성 병목을 추적해 구조를 바꾼 기록: Part 3 - 채번을 INSERT 시점으로 옮기고 범위 단위로 받기
  44. Kafka의 저장 구조 - 세그먼트와 오프셋, 페이지 캐시와 zero-copy
  45. 대량 배치 안정성을 높이기 위한 구조 개선: Part 1 - 시스템을 압박하기 시작한 배치
  46. 대량 배치 안정성을 높이기 위한 구조 개선: Part 2 - 전체 삭제 후 전체 등록 구조의 위험성
  47. 대량 배치 안정성을 높이기 위한 구조 개선: Part 3 - 청크 분할과 병렬 처리로 재설계하기
  48. 대량 배치 안정성을 높이기 위한 구조 개선: Part 4 - 분산 락이 있어도 레이스가 발생한 이유
  49. 대량 배치 안정성을 높이기 위한 구조 개선: Part 5 - 배타적 락과 조건부 해제로 순서를 보장하기
  50. 키 생성 병목을 추적해 구조를 바꾼 기록: Part 1 - INSERT가 느린 줄 알았다
  51. 대량 배치 안정성을 높이기 위한 구조 개선: Part 0 - 왜 이 배치는 가끔 터질까?
  52. Heap Dump가 가리킨 곳은 데이터가 아니라 영속성 컨텍스트였다: Tasklet에서 Chunk로, XSSF에서 SXSSF로
  53. Bulkhead Pattern
  54. 폴링 배치를 SQS 이벤트 파이프라인으로 바꾼 이유: 재시도, DLQ, 메시지 ID 멱등
  55. 대용량 지분율 데이터 처리 성능 개선과 동시성 제어 전략
  56. 조건 기반 예측 캐싱: 고속 엑셀 다운로드 처리 구조 설계
  57. 백엔드 시스템 로깅 베스트 프랙티스
  58. ISMS 대응을 위한 로그 수집 체계 개선
  59. 대량 엑셀 다운로드를 메시지 큐와 S3 사전 생성으로 개선한 이야기
  60. 대용량 엑셀 다운로드 요청을 안정적으로 처리하는 방법
  61. 무거운 엑셀 다운로드 요청을 사전에 판별하는 방법
  62. Keep-Alive
  63. Network Load Balancers(NLB)
  64. Large List Rendering Issue
  65. Log Level
  66. Log4j vs Logback vs Log4j2
  67. Increasing System Performance in MultiProcessing
  68. Circuit Braker

기술 블로그 리뷰

7편
  1. 카카오페이 「MSA 환경에서 네트워크 예외를 잘 다루는 방법」 리뷰 — Unknown을 타입으로 만든 글과, Unknown을 상태로 저장한 프로젝트가 갈리는 지점
  2. Airbnb 「Avoiding double payments in a distributed payments system」 리뷰 — 네트워크와 DB 트랜잭션을 섞지 않는 세 단계, 재시도 가능 여부의 분류, 그리고 복제본을 읽으면 이중 결제가 나는 이유
  3. 쿠팡 「대용량 트래픽 처리를 위한 쿠팡의 백엔드 전략」 리뷰 — 캐시 두 겹과 '분 단위 99.99% 동일'이라는 문장, 그리고 그 0.01%를 누가 어떻게 세는가
  4. 카카오 「메시징 서버의 스트레스 테스트 노하우와 AI가 덜어 준 부분」 리뷰 — 지표를 네 층으로 내려가 읽는 법, 그리고 LLM에게 맡긴 것과 맡기지 못한 것
  5. 카카오 「MySQL Json 데이터 타입의 저장 구조와 성능 비교」 리뷰 — 통째로 넣고 통째로 꺼내면 TEXT, 키로 파고들면 JSON
  6. 네이버 D2 「CDC 복제 이후 오라클이 느려졌다? child cursor 폭증이 만든 예상치 못한 문제」 리뷰 — 같은 SQL인데 바인딩 타입이 다르면 Oracle은 다른 쿼리로 본다
  7. 네이버 D2 「6개월 만에 연간 수십조를 처리하는 DB CDC 복제 도구 무중단/무장애 교체하기」 리뷰 — 복제·검증·복구를 셋으로 나누고, 옛 도구와 새 도구를 서로 모르게 같이 돌린 전환

컨퍼런스 발표 리뷰

9편
  1. SLASH 24 리뷰 - 대규모 사용자 기반의 마이데이터 서비스 안정적으로 운영하기: 클러스터 단위 서킷 코디네이터, 웹소켓 얼리 리턴, 7일 배치 분산
  2. SLASH 23 리뷰 - 프로파일러로 시스템 성능 향상시키기: Pinpoint, 힙 덤프, jemalloc, async-profiler, strace, 그리고 커널 버전
  3. TMC 25 리뷰 - '주식모으기' 서비스로 살펴보는 대용량 트래픽 처리 노하우: 200만 주문을 3,000건으로 접는 풀링 주문과 그 대가
  4. SLASH 23 리뷰 - Kafka 이중화로 다양한 장애 상황 완벽 대처하기: Active-Standby를 믿지 않고 Active-Active로 간 이유와 IDC 장애 당일의 순서
  5. SLASH 23 리뷰 - 토스는 Gateway 이렇게 씁니다: 목적별 게이트웨이, 패스포트, 요청 서명 검증, YAML 라우트와 게이트웨이 봇
  6. SLASH 23 리뷰 - 분산 추적 체계 & 로그 중심으로 Observability 확보하기: 좋은 로그의 조건, 글로벌 trace ID, TCP 전문에 문맥 심기, 헤더 라우팅 디버깅 환경
  7. SLASH 22 리뷰 - 토스뱅크의 완전히 새로운 대출 시스템: Flyway + Hibernate validate, 대외기관 파이프라인, 연동 서킷과 대기열
  8. SLASH 22 리뷰 - Java Native Memory Leak 원인을 찾아서: RSS와 NMT의 2GB 차이, jemalloc 프로파일, C2 컴파일러, Graal JIT
  9. SLASH 21 리뷰 - SRE 사례 소개: Redis 리밸런싱 ASK 에러, Memcached 재분배 실패, Prometheus가 바꾼 GC 패턴