#장애·확장
「장애·확장」 태그가 붙은 글 22편이다.
글 목록
22편 중 1–22
우리를 무너뜨린 건 트래픽이 아니었다
실제로 겪은 장애를 돌아보니 트래픽 때문에 무너진 건 거의 없었다. 결제사 지연, 인증서 만료, 설정 실수 같은 것들이었다. 대비는 엉뚱한 데 가 있었다.
장애도 없는데 클라우드 청구서가 세 배로 나왔다
장애도 없고 트래픽도 계획대로였는데 월말 클라우드 청구서가 예상의 세 배로 나왔다. 알림 하나 울리지 않았고, 한 달치 돈은 이미 다 나간 뒤였다.
부하 테스트는 통과했는데 출시 날 무너졌다
출시 전 부하 테스트에서 목표의 세 배를 버텼는데, 실제로는 목표치에서 무너졌다. 테스트가 틀린 게 아니었다. 시험한 조건이 실제와 달랐다.
앱 서버를 두 배로 늘렸는데 왜 그대로일까
트래픽이 늘어 앱 서버를 두 배로 늘렸는데 처리량은 그대로였고 응답은 오히려 나빠졌다. 앱 서버는 놀고 있었고, DB 만 CPU 100% 였다.
서버를 5대로 늘렸더니 레이트 리밋이 다섯 배로 샜다
초당 100회로 걸어 둔 제한이 서버를 다섯 대로 늘리자 500회가 됐다. 한곳에 모아 세니 이번엔 그 카운터가 병목이 됐다.
큐에 쌓아 두면 된다더니 서버가 메모리로 죽었다
큐에 쌓아 두면 언젠가 다 처리될 줄 알았다. 유입이 넘친 날 서버는 메모리 부족으로 줄줄이 죽었고, 쌓여 있던 것도 전부 날아갔다.
샤드는 고르게 나눴는데 한 샤드만 CPU 100%
샤드를 고르게 나눴는데 프로모션 상품 하나 때문에 한 샤드만 CPU 100% 가 됐다. 나머지는 20% 인데. 샤드를 더 늘리면 풀릴까? 안 풀린다. 키 하나는 여전히 한 샤드에 있다.
오토스케일을 켜 뒀는데도 몇 분간 서비스가 죽었다
방송에 소개된 날 트래픽이 1분 만에 열 배가 됐다. 오토스케일은 제대로 움직였는데, 서버가 늘기까지 몇 분 동안 서비스는 죽어 있었다. 설정이 틀린 게 아니었다.
DB 페일오버는 끝났는데 앱은 왜 옛 주소로 붙을까
주 DB 가 죽고 대기 서버가 몇 초 만에 승격됐는데도 서비스는 계속 죽어 있었다. 앱이 아직 옛 주소로 붙고 있었다. 전환은 성공했는데 그 소식이 앱까지 안 닿았다.
트래픽이 세 배로 몰리면 일부는 빨리 거절해야 한다
트래픽이 세 배로 몰리자 서버는 살아 있는데 응답이 30초를 넘었다. 사용자는 이미 떠났는데 서버는 그 요청을 성실히 처리하고 있었다. 아무도 기다리지 않는 응답을 만드는 중이었다.
DB 엔 있는 주문이 검색엔 없다, 아웃박스 패턴
DB 에는 있는 주문이 검색에는 안 나오는데 에러 로그는 깨끗했다. 두 곳에 따로 쓰면 언젠가 어긋난다. 그리고 그 어긋남은 아무 신호 없이 쌓인다.
정규식 한 줄에 CPU 가 100% 로 붙었다
이메일 형식을 확인하는 평범한 정규식 하나에 서버 CPU 가 100% 로 붙었다. 문자열 하나 검사하는 데 몇 분이 걸렸다. 정규식이 느린 게 아니라 패턴과 입력이 잘못 만난 거였다.
AWS 2017년 스토리지 장애, 명령 하나가 4시간이 됐다
2017년 AWS 스토리지 서비스가 약 4시간 멈추자 인터넷의 상당 부분이 함께 멈췄다. 시작은 잘못 입력한 명령 하나였다. 그런데 진짜 문제는 사람보다 구조 쪽에 있었다.
GitHub 의 43초 네트워크 단절은 왜 24시간 장애가 됐나
2018년 GitHub 은 데이터센터 사이 네트워크가 43초 끊긴 일로 24시간 넘게 정상이 아니었다. 원인은 1분도 안 돼 사라졌다. 나머지 시간은 판단과 검증에 들어갔다.
타임아웃을 걸었는데도 서비스 전체가 느려진다면
타임아웃을 걸어 뒀는데도 의존 서비스 하나가 느려지자 서비스 전체가 느려졌다. 실패할 걸 알면서 계속 기다리고 있었으니까. 그 고리를 끊는 게 서킷 브레이커다.
CDN 을 붙였더니 남의 이름이 보인다
CDN 을 붙였더니 내 계정에 다른 사람 이름이 보인다는 문의가 들어왔다. 에러는 한 줄도 없고 지표는 오히려 좋아졌다. 캐시는 주소만 보고 사람은 안 본다.
카프카 컨슈머가 리밸런싱만 반복한다, max.poll.interval.ms
카프카 컨슈머가 일하는 시간보다 파티션을 다시 나누는 시간이 더 길어질 때가 있다. 컨슈머를 늘려도 그대로다. 살아 있는 컨슈머가 처리 시간 때문에 죽은 걸로 판정받고 있어서다.
타임아웃을 안 걸었다면 무한대로 건 것이다
외부 API 가 에러도 없이 응답만 안 주자, 우리 서버 스레드가 하나씩 묶이더니 몇 분 만에 서비스가 멈췄다. CPU 는 한가했다. 스레드는 전부 잠들어 있었다.
DB 는 몇 초 만에 살아났는데 서비스는 왜 계속 죽어 있을까
DB 가 몇 초 느려졌을 뿐인데 서비스가 무너졌고, 원인이 사라진 뒤에도 회복이 안 됐다. 범인은 「실패하면 세 번 재시도」라는 지극히 상식적인 설정이었다.
한 번 눌렀는데 두 번 결제됐다면, 멱등성
사용자는 결제 버튼을 한 번 눌렀는데 청구는 두 번 나갔다. 응답을 못 받았다고 다시 보낸 게 원인이었다. 그런데 보낸 쪽은 처리가 됐는지 안 됐는지 알 길이 없다.
keep-alive 를 안 쓰면 악수만 하다 끝난다
상대 서비스는 5ms 만에 처리하는데 우리 쪽에서 재면 40ms 가 나왔다. 사라진 35ms 는 요청마다 연결을 새로 맺는 데 쓰이고 있었다. 설정은 맞았다. 쓰는 법이 틀렸다.
적중률 95% 인데 정각마다 DB 가 튄다, 캐시 스탬피드
캐시 적중률은 95% 인데 정각마다 DB 부하가 순간적으로 치솟았다. 알림도 안 울릴 만큼 짧아서 더 고약했다. 같은 시각에 만든 캐시가 같은 시각에 한꺼번에 만료되고 있었다.
조건에 맞는 글이 없다. 브루니가 숨었나 보다.