주제 허브
느린 외부 기관 하나가 전체를 멈추지 못하게 할 수 있나
장애 대응과 관측
서킷 브레이커와 벌크헤드, 타임아웃과 재시도 예산, 장애 주입 실험, 그리고 문제를 찾아 준 로그와 추적. 장애를 겪은 뒤 쓴 글과 장애를 막기 위해 설계한 글을 함께 둔다.
먼저 읽을 글
직접 만들고 재 본 것 ParityPay로 검증하는 결제 정합성 9 - 느린 기관 앞에서 결제 서버를 지키기: 타임아웃, 재시도, 차단기, 리미터, 벌크헤드가 각각 무엇을 막는가 직접 만들고 재 본 것 Circuit Breaker로 외부 API 장애 격리 — Resilience4j + KIS·Yahoo 폴백 체인 직접 만들고 재 본 것 OpenTelemetry + Jaeger로 분산 추적 — 시세 파이프라인 지연 측정 기술 블로그 리뷰 카카오페이 「MSA 환경에서 네트워크 예외를 잘 다루는 방법」 리뷰 — Unknown을 타입으로 만든 글과, Unknown을 상태로 저장한 프로젝트가 갈리는 지점 컨퍼런스 발표 리뷰 SLASH 24 리뷰 - 대규모 사용자 기반의 마이데이터 서비스 안정적으로 운영하기: 클러스터 단위 서킷 코디네이터, 웹소켓 얼리 리턴, 7일 배치 분산 컨퍼런스 발표 리뷰 SLASH 23 리뷰 - 프로파일러로 시스템 성능 향상시키기: Pinpoint, 힙 덤프, jemalloc, async-profiler, strace, 그리고 커널 버전
직접 만들고 재 본 것
68편- ParityPay로 검증하는 결제 정합성 9 - 느린 기관 앞에서 결제 서버를 지키기: 타임아웃, 재시도, 차단기, 리미터, 벌크헤드가 각각 무엇을 막는가
- Circuit Breaker로 외부 API 장애 격리 — Resilience4j + KIS·Yahoo 폴백 체인
- OpenTelemetry + Jaeger로 분산 추적 — 시세 파이프라인 지연 측정
- 무너지는 Spring 서버 1 - CPU는 놀고 있는데 API가 느리다: 업스트림 하나가 무관한 엔드포인트를 죽이는 과정을 thread dump 세 장으로 읽기
- TLS 핸드셰이크의 비용 - 세션 재개와 0-RTT의 대가
- 타임아웃, 재시도, 백오프 - 증폭과 지터, 그리고 데드라인 전파
- 커넥션과 세션 - 커넥션 풀이 실제로 아끼는 것
- HTTP/1.1, 2, 3 - HOL 블로킹은 어디로 옮겨갔는가
- 큐잉 이론 한 조각 - 도착률과 서비스율로 파라미터를 정하기
- 혼잡 제어와 지연 - BDP, 버퍼블로트, 처리량과 지연의 교환
- JIT 컴파일 - 계층 컴파일, 인라이닝, 역최적화
- WebSocket push와 REST polling을 클라이언트 1만 개에서 재다 — 지연과 서버 비용, Kafka 정지 45초, 느린 소비자 25개
- 가상 스레드를 켜서 37배 느려진 엔드포인트 - 핀닝과 상한 없는 admission을 재다
- 트레이스 샘플링 - 헤드와 테일 샘플링의 선택 기준
- TCP 연결 수립과 큐 - SYN 백로그, accept 큐, TIME_WAIT
- G1과 ZGC가 p99에 남기는 차이 - 300배 짧은 pause가 꼬리의 11%를 가져갔다
- GC 알고리즘 비교 - G1, ZGC, Shenandoah가 각자 무엇을 포기하는가
- 멱등성 설계 - 키의 단위와 저장 위치, 만료와 재시도 계약
- 토스증권 Kafka 데이터센터 이중화 리뷰: 미러링보다 오프셋이 어렵고, 재난과 작업의 기준이 다르다
- RED와 USE - 어디에 무엇을 붙이는가
- 토스증권 공개 자료로 읽는 시세·주문 아키텍처: 무엇을 잃어도 되는지 먼저 정한다
- epoll - select, poll과의 차이와 edge, level 트리거
- Spring Batch의 구조 - 청크, 파티셔닝, 재시작과 메타데이터
- 가상 스레드의 내부 - 스케줄러와 캐리어, 핀닝, 그리고 쓰지 않아야 할 때
- Redis 단일 스레드가 멈추는 순간 - SCAN이 3.7배 오래 걸리면서 아무도 막지 않고, 120ms 멈춤이 p99에 안 잡히는 이유
- ParityPay로 검증하는 결제 정합성 10 - 락 lease가 트랜잭션보다 먼저 끝나면 정말 정합성이 깨지는가: SETNX 락, Watchdog, fencing token, 그리고 락 없는 구조의 실측
- ParityPay로 검증하는 결제 정합성 8 - Kafka에서 중복·유실·순서 역전을 직접 만들어 보기: 멱등 소비자와 Outbox가 막는 것과 못 막는 것
- 캐시 스탬피드와 single flight - 200명 중 125명이 원본까지 갔고, 예외를 삼키자 실패가 가장 빠른 요청이 됐다
- 백분위 통계 - 평균이 거짓말하는 이유와 히스토그램의 집계 오류
- ParityPay로 검증하는 결제 정합성 6 - 대사: "기관에 물어보지 못했다"와 "기관에 기록이 없다"는 다른 상태다
- 키 생성 병목을 추적해 구조를 바꾼 기록: Part 2 - SELECT 안에서 UPDATE가 일어나고 있었다
- 페이지 캐시와 파일 IO - buffered와 direct, fsync가 실제로 하는 일
- ParityPay로 검증하는 결제 정합성 5 - DB 커밋과 Kafka 발행 사이: Transactional Outbox와 at-least-once 소비자
- 동시성 도구의 비용 - synchronized, ReentrantLock, CAS가 경쟁에서 갈리는 지점
- ParityPay로 검증하는 결제 정합성 4 - 실험 27종이 찾아낸 결함 12건: 문서와 코드를 읽어서 나온 것은 하나도 없었다
- Postgres 커넥션 하나의 비용 - 풀을 키우면 대기가 사라지는 게 아니라 볼 수 없는 곳으로 옮겨간다
- ParityPay로 검증하는 결제 정합성 3 - 외부 승인 응답이 사라졌을 때: 타임아웃은 실패가 아니다
- ParityPay로 검증하는 결제 정합성 2 - 잠금을 필요 이상으로 오래 쥐고 있었다: 추론을 측정으로 바꾼 기록
- 멱등한 API 설계 - HTTP 메서드의 의미와 재시도 계약
- 2021년의 결제대행 API 연동을 2026년의 질문으로 다시 보기
- 메트릭, 로그, 트레이스 - 무엇을 어디에 남기고 카디널리티는 어디서 터지는가
- 컨텍스트 스위칭과 스케줄링 - CFS, cgroup CPU 제한, 그리고 스로틀링
- 키 생성 병목을 추적해 구조를 바꾼 기록: Part 3 - 채번을 INSERT 시점으로 옮기고 범위 단위로 받기
- Kafka의 저장 구조 - 세그먼트와 오프셋, 페이지 캐시와 zero-copy
- 대량 배치 안정성을 높이기 위한 구조 개선: Part 1 - 시스템을 압박하기 시작한 배치
- 대량 배치 안정성을 높이기 위한 구조 개선: Part 2 - 전체 삭제 후 전체 등록 구조의 위험성
- 대량 배치 안정성을 높이기 위한 구조 개선: Part 3 - 청크 분할과 병렬 처리로 재설계하기
- 대량 배치 안정성을 높이기 위한 구조 개선: Part 4 - 분산 락이 있어도 레이스가 발생한 이유
- 대량 배치 안정성을 높이기 위한 구조 개선: Part 5 - 배타적 락과 조건부 해제로 순서를 보장하기
- 키 생성 병목을 추적해 구조를 바꾼 기록: Part 1 - INSERT가 느린 줄 알았다
- 대량 배치 안정성을 높이기 위한 구조 개선: Part 0 - 왜 이 배치는 가끔 터질까?
- Heap Dump가 가리킨 곳은 데이터가 아니라 영속성 컨텍스트였다: Tasklet에서 Chunk로, XSSF에서 SXSSF로
- Bulkhead Pattern
- 폴링 배치를 SQS 이벤트 파이프라인으로 바꾼 이유: 재시도, DLQ, 메시지 ID 멱등
- 대용량 지분율 데이터 처리 성능 개선과 동시성 제어 전략
- 조건 기반 예측 캐싱: 고속 엑셀 다운로드 처리 구조 설계
- 백엔드 시스템 로깅 베스트 프랙티스
- ISMS 대응을 위한 로그 수집 체계 개선
- 대량 엑셀 다운로드를 메시지 큐와 S3 사전 생성으로 개선한 이야기
- 대용량 엑셀 다운로드 요청을 안정적으로 처리하는 방법
- 무거운 엑셀 다운로드 요청을 사전에 판별하는 방법
- Keep-Alive
- Network Load Balancers(NLB)
- Large List Rendering Issue
- Log Level
- Log4j vs Logback vs Log4j2
- Increasing System Performance in MultiProcessing
- Circuit Braker
기술 블로그 리뷰
7편- 카카오페이 「MSA 환경에서 네트워크 예외를 잘 다루는 방법」 리뷰 — Unknown을 타입으로 만든 글과, Unknown을 상태로 저장한 프로젝트가 갈리는 지점
- Airbnb 「Avoiding double payments in a distributed payments system」 리뷰 — 네트워크와 DB 트랜잭션을 섞지 않는 세 단계, 재시도 가능 여부의 분류, 그리고 복제본을 읽으면 이중 결제가 나는 이유
- 쿠팡 「대용량 트래픽 처리를 위한 쿠팡의 백엔드 전략」 리뷰 — 캐시 두 겹과 '분 단위 99.99% 동일'이라는 문장, 그리고 그 0.01%를 누가 어떻게 세는가
- 카카오 「메시징 서버의 스트레스 테스트 노하우와 AI가 덜어 준 부분」 리뷰 — 지표를 네 층으로 내려가 읽는 법, 그리고 LLM에게 맡긴 것과 맡기지 못한 것
- 카카오 「MySQL Json 데이터 타입의 저장 구조와 성능 비교」 리뷰 — 통째로 넣고 통째로 꺼내면 TEXT, 키로 파고들면 JSON
- 네이버 D2 「CDC 복제 이후 오라클이 느려졌다? child cursor 폭증이 만든 예상치 못한 문제」 리뷰 — 같은 SQL인데 바인딩 타입이 다르면 Oracle은 다른 쿼리로 본다
- 네이버 D2 「6개월 만에 연간 수십조를 처리하는 DB CDC 복제 도구 무중단/무장애 교체하기」 리뷰 — 복제·검증·복구를 셋으로 나누고, 옛 도구와 새 도구를 서로 모르게 같이 돌린 전환
컨퍼런스 발표 리뷰
9편- SLASH 24 리뷰 - 대규모 사용자 기반의 마이데이터 서비스 안정적으로 운영하기: 클러스터 단위 서킷 코디네이터, 웹소켓 얼리 리턴, 7일 배치 분산
- SLASH 23 리뷰 - 프로파일러로 시스템 성능 향상시키기: Pinpoint, 힙 덤프, jemalloc, async-profiler, strace, 그리고 커널 버전
- TMC 25 리뷰 - '주식모으기' 서비스로 살펴보는 대용량 트래픽 처리 노하우: 200만 주문을 3,000건으로 접는 풀링 주문과 그 대가
- SLASH 23 리뷰 - Kafka 이중화로 다양한 장애 상황 완벽 대처하기: Active-Standby를 믿지 않고 Active-Active로 간 이유와 IDC 장애 당일의 순서
- SLASH 23 리뷰 - 토스는 Gateway 이렇게 씁니다: 목적별 게이트웨이, 패스포트, 요청 서명 검증, YAML 라우트와 게이트웨이 봇
- SLASH 23 리뷰 - 분산 추적 체계 & 로그 중심으로 Observability 확보하기: 좋은 로그의 조건, 글로벌 trace ID, TCP 전문에 문맥 심기, 헤더 라우팅 디버깅 환경
- SLASH 22 리뷰 - 토스뱅크의 완전히 새로운 대출 시스템: Flyway + Hibernate validate, 대외기관 파이프라인, 연동 서킷과 대기열
- SLASH 22 리뷰 - Java Native Memory Leak 원인을 찾아서: RSS와 NMT의 2GB 차이, jemalloc 프로파일, C2 컴파일러, Graal JIT
- SLASH 21 리뷰 - SRE 사례 소개: Redis 리밸런싱 ASK 에러, Memcached 재분배 실패, Prometheus가 바꾼 GC 패턴