IL-0352 Heroku · 2025-07-18networking
Router 2.0 을 쓰는 앱에서 HTTP 요청이 web dyno 에 고르지 않게 나뉘어 지연과 타임아웃이 늘었다
Heroku Common Runtime 의 기본 라우터인 Router 2.0 은 엔트로피 메타데이터로 요청을 받을 dyno 를 고른다. 2025-07-18 22:00 UTC 무렵부터 라우터 인스턴스가 어떤 코드 조건에 닿기 시작했고, 이 조건에서는 메타데이터와 그 로직이 dyno 선택의 폭을 줄였다. 한 번 이 조건에 닿은 인스턴스는 그 뒤 모든 HTTP 요청에서 부하 분산이 깨진 채로 남았다. 요청 처리 자체는 계속됐지만 앱의 web dyno 들에 요청이 고르게 가지 않았고, 조건에 닿는 인스턴스가 늘수록 증상이 천천히 나빠졌다. 이 코드 조건은 Router 2.0 베타 때부터 코드에 있었다. Common Runtime 앱의 94% 남짓이 Router 2.0 으로 옮겨 오면서 새 라우터가 처리하는 요청이 크게 늘었고, 그만큼 조건에 닿을 가능성도 커졌다.
Heroku Support 는 07-20 16:46 UTC 에 첫 고객 신고를 받았다. 07-22 14:35 UTC 에 기술 팀이 내부 조사를 열었고, 지원 팀은 영향을 받은 고객에게 Router 2.0 을 끄고 legacy router 로 돌아가라고 안내했다. 기술 팀은 라우터 dyno 상태가 불완전하다는 가설을 17:01 UTC 에 버렸고, 17:48 UTC 에 정식 사고를 선언했다. 17:53 UTC 에 스테이징의 지속 부하 테스트 로그에도 같은 불균형이 있음을 확인하고 부하 분산 메타데이터를 살피기 시작했다. 19:42 UTC 에는 스테이징에서 라우터 인스턴스를 차례로 새로 띄우면 분산이 나아지는 것을 보고 운영 라우터 인스턴스도 차례로 새로 띄웠다. 20:05 UTC 에 깨진 엔트로피 메타데이터를 근본 원인으로 찾았고, 21:01 UTC 에 새 부하 분산 벤치마크 테스트로 문제를 재현하고 이 테스트를 통과하는 코드 변경을 준비했다.
21:13 UTC 에 변경을 스테이징에 배포해 21:30 UTC 에 안전하다고 판단했고, 21:38 UTC 에 운영 배포를 서둘러 시작했다. 07-23 00:12 UTC 에 마지막 파티션까지 배포를 마쳐 부하 분산이 정상으로 돌아왔다. 스테이징 부하 테스트는 성능이 나쁘면 알림을 울리고 배포를 막지만, 성능은 라우팅 가용성과 HTTP 요청 지연으로만 쟀고 요청 분배는 알림 신호가 아니었다. 스테이징의 테스트 앱은 가용성이나 지연에 드러날 만큼 부하를 받지 않아 알림이 울리지 않았고, 기술 팀은 고객이 영향을 받기 전까지 문제를 몰랐다.
- 심각도
- –
- 영향 범위
- HTTP request distribution across web dynos for apps using Router 2.0 on the Common Runtime, with higher latency, timeouts, reduced availability and Heroku error codes
- 영향 사용자
- Some customer applications using Router 2.0 on Heroku's Common Runtime
- 지역
- –
- 감지까지
- 42h 46m
- 복구까지
- 98h 12m
증상
Heroku Common Runtime 에서 Router 2.0 을 쓰는 일부 앱의 HTTP 요청이 web dyno 사이에 고르게 나뉘지 않았다. 요청이 몰린 dyno 가 과부하에 빠지면서 HTTP 요청 지연과 타임아웃이 늘었다.
앱에서는 가용성 저하와 서비스 품질 저하, HTTP 요청 지연 증가가 나타났고, 애플리케이션 로그와 대시보드에 여러 가지 Heroku 오류 코드가 찍혔다.
dyno 당 HTTP 요청 수의 백분율 편차로 잰 불균형은 2025-07-18 22:00 UTC 무렵부터 꾸준히 커졌다. 문제의 코드 조건에 닿는 라우터 인스턴스가 늘수록 증상이 천천히 나빠졌다.
Heroku Support 는 07-20 16:46 UTC 에 요청이 dyno 에 고르지 않게 가서 지연과 타임아웃이 늘었다는 첫 고객 신고를 받았다. 07-22 14:35 UTC 에 내부 조사가 열렸고, 기술 팀은 라우터 dyno 상태가 불완전한 것이 원인이라고 보고 살폈지만 17:01 UTC 에 이 가설을 버렸다.
스테이징의 지속 부하 테스트 로그에도 같은 불균형이 있었지만 알림은 울리지 않았다. 알림은 라우팅 가용성과 HTTP 요청 지연만 봤고 요청 분배는 보지 않았다.
원인
원인 소프트웨어 결함
- 촉발
- 2025-07-18 22:00 UTC 무렵부터 Router 2.0 인스턴스가 어떤 코드 조건에 닿기 시작했다. 이 조건에 닿으면 부하 분산용 엔트로피 메타데이터와 그 로직이 dyno 선택의 폭을 줄였다.
감지
07-20 16:46 UTC 에 Heroku Support 가 요청이 dyno 에 고르지 않게 가서 지연과 타임아웃이 늘었다는 첫 고객 신고를 받았다. 스테이징 부하 테스트에도 같은 불균형이 있었지만, 알림은 라우팅 가용성과 HTTP 요청 지연만 보고 요청 분배는 보지 않아 울리지 않았다.
조치
- 지원 팀이 영향을 받은 고객에게 Router 2.0 을 끄고 legacy router 로 돌아가라고 안내했다.
- 운영 라우터 인스턴스를 차례로 새로 띄워 영향을 받은 앱의 부하 분산을 나아지게 했다.
- 부하 분산을 고친 라우터 코드를 스테이징에 먼저 배포한 뒤 운영에 단계적으로 배포해 07-23 00:12 UTC 에 마지막 파티션까지 마쳤다.
후속 조치
- 부하 분산 동작이 다시 망가지지 않도록 막는 게이트와 알림을 넣었다.
- 자동 이전을 다시 시작하기 전에, 아직 legacy router 를 쓰는 앱의 고객에게 일정과 안내를 꾸준히 알린다.
교훈
–
출처
- https://status.heroku.com/incidents/2863 · official-status · 보관본
참고 문서
- https://devcenter.heroku.com/articles/http-routing#legacy-router-and-router-2-0
- https://devcenter.heroku.com/articles/http-routing#request-distribution
- https://devcenter.heroku.com/articles/error-codes
- https://www.heroku.com/blog/router-2dot0-the-road-to-beta/#load-test-continuously
- https://devcenter.heroku.com/changelog-items/2682
- https://help.salesforce.com/s/articleView?id=005123907&type=1
관련 사례
IL-0150DynamoDB DNS 자동화의 경쟁 조건이 us-east-1 리전 엔드포인트의 DNS 레코드를 비워 DynamoDB 와 EC2 인스턴스 시작이 실패했고, 그 여파로 EKS, ECS, Fargate 의 컨테이너 시작과 클러스터 스케일링이 14시간 넘게 막혔다Amazon Web Services · 2025같은 원인 · 공통 클라우드 로드 밸런서
IL-0131새로운 형태의 GenerateContent 요청이 Vertex AI 예측 API 서버에 세그폴트를 일으켰고, 동시에 재시작하는 서버가 늘자 서빙 용량이 모자라 여러 리전에서 오류가 치솟았다.Google Cloud · 2024같은 원인 · 공통 클라우드 로드 밸런서
같은 원인 · 공통 클라우드 로드 밸런서
같은 원인 · 공통 클라우드 로드 밸런서
IL-0243Google External Proxy Load Balancing 뒤의 HTTP/S 엔드포인트가 전 세계에서 Google 404 오류를 냈다Google Cloud · 2021같은 원인 · 공통 클라우드 로드 밸런서
IL-0106잘못된 IngressRoute 매니페스트가 Traefik v2 버그를 건드려 Traefik 파드가 모두 재시작된 뒤 Kubernetes 의 모든 서비스가 404 를 냈다DFDS · 2021같은 원인 · 공통 클라우드 로드 밸런서
같은 원인 · 공통 클라우드 로드 밸런서
같은 원인 · 공통 클라우드 로드 밸런서
같은 원인 · 공통 클라우드 로드 밸런서
IL-0338Google Cloud 의 HTTP(S) 로드 밸런서와 TCP/SSL Proxy 로드 밸런서가 32분 동안 요청의 33~87% 에 502 나 연결 재설정을 냈다Google Cloud · 2018같은 원인 · 공통 클라우드 로드 밸런서
IL-0395Google Cloud HTTP(S) Load Balancer 가 한참 오래된 구성으로 되돌아가 요청의 25%가 22분 동안 502 오류로 실패했다Google Cloud · 2017같은 원인 · 공통 클라우드 로드 밸런서
IL-0396새로 만들거나 라이브 마이그레이션한 GCE 인스턴스, Cloud VPN 터널, 네트워크 로드 밸런서가 2시간 8분 동안 공인 IP 주소로 연결되지 않았다Google Cloud · 2017같은 원인 · 공통 클라우드 로드 밸런서
내 클러스터에도 있는지 확인하기
AI 도구와 스크립트용
- 이 사례의 JSON: https://incidentlib-api.benchlet.com/cases/IL-0352
- 가장 비슷한 사례들: https://incidentlib-api.benchlet.com/cases/IL-0352/similar
- MCP 서버(Streamable HTTP, 키 없음):
https://incidentlib-mcp.benchlet.com/mcp
API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.