IL-0257 Canva · 2024-11-12networkingaws
한꺼번에 몰린 요청에 API Gateway 태스크가 모두 OOM 으로 종료돼 canva.com 이 약 50분 동안 열리지 않았다
Canva 편집기는 하루에 여러 번 배포되는 단일 페이지 애플리케이션이다. 배포 때마다 JavaScript 파일을 비롯한 정적 자산 100개 이상이 AWS S3 버킷에 올라가고, 클라이언트는 이 자산을 CDN 인 Cloudflare 의 계층형 캐시로 받는다. 편집기는 자산을 받은 뒤 API Gateway 를 호출해 나머지를 불러온다. API Gateway 는 모든 API 요청의 입구이고 인증, 권한, 속도 제한을 처리한다. API Gateway 는 Netty 로 만들었고, Amazon ECS 에서 자동 확장되는 태스크 묶음으로 돈다.
8:47 AM UTC 에 편집기 새 버전이 배포된 같은 시각, Cloudflare 의 낡은 트래픽 관리 규칙이 사용자 IPv6 트래픽을 사설 백본 대신 애슈번과 싱가포르 사이 공용 전송 경로로 보내고 있었다. 이 규칙 때문에 Cloudflare 의 자동화가 패킷 손실을 피해 돌아가지 못했고, 이 경로의 패킷 손실은 최대 약 66% 였다. 객체 패널을 그리는 JavaScript 파일 하나를 받는 데 20분이 걸렸다. Cloudflare 의 캐시 스트림은 같은 자산을 받으려는 여러 요청을 한 요청으로 묶으므로 270,000건 이상의 요청이 같은 스트림을 기다렸다. 요청이 끝나지 않아 오류가 기록되지 않았고 카나리 시스템도 배포를 멈추지 않았다.
9:07 AM UTC 에 파일 받기가 끝나자 기다리던 기기들이 동시에 객체 패널을 불러 API Gateway 에 평소 최대의 3배인 초당 150만 건이 몰렸다. 앞서 텔레메트리 라이브러리를 바꿀 때 성능 저하가 하나 들어가 있었다. 일부 지표가 값을 기록할 때마다 서드파티 라이브러리의 잠금 안에서 다시 등록되는 문제였다. API Gateway 는 이벤트 루프 스레드에서 막히는 작업을 하면 안 되는 구조라서, 부하가 늘자 이 잠금 경합이 태스크 하나의 최대 처리량을 크게 줄였다. 수정은 이미 릴리스 과정에 들어가 있었지만 영향을 작게 보고 서둘러 배포하지 않았다. 요청이 쌓이고 로드 밸런서가 새 연결을 더 열면서 오프힙 메모리가 늘었고, 처음 2분 안에 Linux Out Of Memory Killer 가 모든 컨테이너를 종료했다.
태스크 수를 손으로 늘려도 새 태스크가 곧바로 종료되자, 팀은 9:29 AM UTC 에 Cloudflare 방화벽 규칙으로 CDN 에서 모든 트래픽을 막았다. 새 태스크가 요청을 받지 않은 상태에서 뜨게 하려는 조치였다. 이어서 canva.com 을 상태 페이지로 돌렸다. 정상 태스크 수가 안정되자 엄격한 속도 제한을 건 오스트레일리아 사용자부터 트래픽을 조금씩 되살렸고, canva.com 은 10:00 AM UTC 무렵 복구됐다. Cloudflare 는 문제의 트래픽 관리 규칙을 지웠다.
- 심각도
- –
- 영향 범위
- canva.com was unavailable from 9:08 AM UTC to about 10:00 AM UTC; before that the editor's object panel did not load for many users
- 영향 사용자
- –
- 지역
- The object panel failure hit many users in Asia, and requests backed up from users in Southeast Asia
- 감지까지
- –
- 복구까지
- 52m
증상
2024년 11월 12일 8:47 AM UTC 에 편집기 새 버전을 배포한 뒤, 아시아의 많은 사용자에게 편집기의 객체 패널이 끝없이 로딩 상태로 남았다. 9:08 AM UTC 부터는 canva.com 자체가 열리지 않았다.
같은 시각 Cloudflare 의 싱가포르 SIN 과 애슈번 IAD 사이 네트워크 경로에 지연이 생겨 첫 바이트까지 걸리는 시간의 90번째 백분위수가 1700% 넘게 늘었다. 객체 패널을 그리는 JavaScript 파일 하나는 받는 데 20분이 걸렸다.
요청이 끝나지 않았기 때문에 오류가 기록되지 않았고, 오류가 늘면 배포를 멈추는 카나리 시스템도 배포를 멈추지 않았다. 이 JavaScript 파일을 기다리는 사용자 요청 270,000건 이상이 같은 캐시 스트림에 묶였고, 그래서 동남아시아 사용자의 요청이 쌓였다.
9:07 AM UTC 에 파일 받기가 끝나자 대기 중이던 요청 270,000건 이상이 한꺼번에 완료됐다. 기다리던 모든 기기가 동시에 객체 패널을 불러 API Gateway 에 초당 150만 건의 요청이 몰렸다. 평소 최대 부하의 3배였다.
API Gateway 태스크가 요청을 제때 처리하지 못하자 로드 밸런서가 이미 과부하인 태스크에 새 연결을 더 열어 메모리 압박이 커졌다. 오프힙 메모리가 늘면서 처음 2분 안에 Linux Out Of Memory Killer 가 실행 중인 컨테이너를 모두 종료했다. 자동 확장이 이 속도를 따라가지 못해 canva.com 으로 가는 모든 요청이 실패했다.
자동 확장이 띄운 새 태스크는 정상으로 표시되자마자 몰려드는 트래픽을 감당하지 못하고 곧바로 종료됐다. 원하는 태스크 수를 손으로 크게 늘려 봤지만 태스크가 금방 종료되는 문제는 그대로였다.
원인
- 촉발
- 2024년 11월 12일 8:47 AM UTC 에 Canva 편집기 새 버전이 배포돼 클라이언트들이 새 정적 자산을 받기 시작했다. 같은 시각 Cloudflare 의 싱가포르와 애슈번 사이 경로에서 패킷이 손실돼 JavaScript 파일 하나의 전송이 20분 동안 끝나지 않았다.
감지
–
조치
- 임시 Cloudflare 방화벽 규칙을 넣어 CDN 에서 모든 트래픽을 막고, 새 API Gateway 태스크가 요청을 받지 않은 상태에서 뜨게 했다.
- canva.com 을 상태 페이지로 돌려 사용자에게 장애 중임을 알렸다.
- 엄격한 속도 제한을 건 오스트레일리아 사용자부터 시작해 canva.com 트래픽을 조금씩 되살렸다.
후속 조치
- 트래픽을 세밀하게 돌리고 막은 뒤 단계적으로 다시 늘리는 내부 런북을 만든다.
- canva.com 을 쓸 수 없을 때 사용자에게 더 자세한 오류 페이지를 보여 준다.
- API Gateway 의 기본 태스크 수와 태스크 하나에 주는 메모리를 늘린다.
- 비슷한 트래픽 패턴에서 실패할 위험을 줄이는 부하 차단 규칙을 API Gateway 에 더한다.
- API Gateway 에 정기 부하 테스트를 들인다.
- 텔레메트리 라이브러리의 스레드 잠금 버그를 고치는 패치를 배포한다.
- 텔레메트리 라이브러리의 마이크로벤치마크 테스트에 스레드 경합을 일으킨 코드 경로의 멀티스레드 테스트를 더한다.
- 페이지 자산 카나리 릴리스에서 JavaScript 오류율에 더해 페이지 로드 완료 이벤트를 보조 지표로 본다.
- 카나리에 롤아웃 단계를 하나 더 두어 단계적 배포 중 문제를 찾을 시간을 늘리는 실험을 한다.
- 사용자 요청이 자산을 너무 오래 기다리지 않도록 자산 받기에 타임아웃을 둔다.
- Cloudflare 와 함께 이번 사고에서 여러 시스템이 어떻게 얽혀 작용했는지 자세히 파악한다.
교훈
–
출처
관련 사례
IL-0515files.pythonhosted.org 에서 파일을 받을 때 2주 가까이 502 와 503 이 간헐적으로 나서 PyPI 설치가 실패했다Python Software Foundation · 2026같은 원인 · 공통 CDN 과 엣지 네트워크
IL-0267싱가포르 캐시 거점 eqsin 의 전송 회선 두 개가 함께 끊겨 BGP 가 내려가고 eqsin 의 호스트에 닿을 수 없게 됐다Wikimedia Foundation · 2023같은 원인 · 공통 CDN 과 엣지 네트워크
IL-0398GOV.UK 가 쓰는 주 CDN 에 전 세계 장애가 나서, 1시간이 안 되는 동안 GOV.UK 방문자가 오류 페이지만 봤다Government Digital Service · 2021같은 원인 · 공통 CDN 과 엣지 네트워크
내 클러스터에도 있는지 확인하기
AI 도구와 스크립트용
- 이 사례의 JSON: https://incidentlib-api.benchlet.com/cases/IL-0257
- 가장 비슷한 사례들: https://incidentlib-api.benchlet.com/cases/IL-0257/similar
- MCP 서버(Streamable HTTP, 키 없음):
https://incidentlib-mcp.benchlet.com/mcp
API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.