세일 시작 10분 만에 주문 이벤트가 평소의 10배로 들어온다. 뒤에서 알림·정산·집계를 처리하는 워커는 초당 200건이 한계라 큐가 계속 깊어진다. 들어오는 쪽을 늦춰서 다 받아낼지(backpressure), 덜 중요한 작업을 버려서 핵심만 지킬지(shedding) 정해야 한다.
언제: 모든 작업이 결국 다 처리돼야 할 때(주문, 결제, 정산 기록). 큐 길이에 상한을 걸고, 가득 차면 429 + Retry-After로 호출자를 늦춘다. 호출자가 내부 서비스라서 백오프 규칙을 따라줄 수 있을 때 특히 잘 먹힌다.
비용: 피크 때 호출자와 사용자가 느려짐과 429를 직접 본다. 호출자가 백오프를 안 지키면 재시도가 겹쳐 유입이 오히려 2~3배로 증폭되고, 압력이 호출 체인을 타고 위로 전파돼 최상단 UX까지 같이 느려진다.
언제: 백프레셔로 늦춰도 어차피 다 못 받는 수준의 스파이크이고, 작업에 명확한 우선순위가 있을 때. 결제·주문 상태 전이 같은 핵심은 끝까지 지키고, 추천·실시간 집계·미리보기 같은 부가 작업은 버리거나 캐시된 값으로 대체한다.
비용: '뭘 버려도 되는지' 우선순위 등급을 정의하고 비즈니스와 합의하는 비용이 코드보다 크다. 버린 작업을 나중에 재처리할지도 정해야 하고, 드롭 카운터를 안 보면 '조용히 데이터가 빠지는' 사고로 이어진다.
기본은 유한 큐 + 백프레셔다. 무한 큐는 완충이 아니라 장애를 숨기는 장치다 — 겉으론 200 OK인데 알림은 30분 뒤에 가고 있는 상태가 된다. 큐에 상한을 걸고 가득 차면 429와 Retry-After로 호출자를 늦추는 게 첫 수다. 그래도 핵심 작업의 처리 지연이 SLA를 넘기 시작하면 그때 우선순위 티어를 나눠 낮은 티어부터 버린다. 제조 데이터 수집에서도 같은 패턴이었다 — 센서 유입이 수집 서버 처리 한계를 넘으면 알람·품질 판정 데이터는 끝까지 지키고 초당 트렌드 데이터부터 샘플링으로 덜어냈다.
- 큐 깊이가 평시의 10배를 넘은 채 30분 이상 계속 증가 — 컨슈머가 영구적으로 뒤처지고 있다는 신호이고, 상한이 없다면 이미 숨은 장애다
- 큐 대기 시간(들어가서 처리 시작까지) p99가 60초를 넘어 알림·정산이 SLA를 깨기 시작할 때
- 429를 돌려줘도 호출자 재시도 폭풍으로 유입이 2배로 증폭될 때 — 백프레셔가 안 먹히니 낮은 티어부터 버려야 한다
- 상한 없는 인메모리 큐 때문에 워커 힙이 80%를 넘어 OOM으로 한꺼번에 터지기 직전일 때
🔧HTTP 429 + Retry-Afterresilience4j Bulkhead / RateLimiterKafka consumer-lag 알람 (Burrow, Grafana)Netflix concurrency-limits (adaptive)drop-counter 메트릭 + 우선순위 티어 플래그
“I default to bounded queues with backpressure, and only shed low-priority work once core latency breaks the SLA.”
checking microphone…