#백엔드
「백엔드」 태그가 붙은 글 39편이다.
글 목록
39편 중 1–39
AI 는 파이썬으로 짜는데 인프라는 왜 Rust 로 가나
요즘 AI 쪽에서 파이썬 코드 밑을 Rust 로 바꾸는 경우가 부쩍 많아졌다. 모델은 여전히 파이썬으로 짜는데도. 비싼 GPU 가 데이터를 기다리며 노는 시간이 생각보다 길어서다.
장애인지 30분째 따지고 있다면 SLO 가 없는 것이다
사용자는 느리다는데 평균 응답 시간은 평소와 같다. 그래서 30분째 장애가 맞는지부터 따지고 있다. 무엇이 정상인지 장애가 나기 전에 한 문장으로 적어 두지 않아서다.
2년 만에 기능 플래그가 200개가 됐다
기능 플래그를 2년 쓰다 보니 200개가 됐고, 뭐가 켜져 있는지 아무도 모른다. 지우자니 무섭다. 만들 땐 이득이 바로 보이는데 지울 땐 위험만 보인다.
카나리를 통과한 배포가 전체 확대 뒤에 터졌다
카나리에서 30분을 지켜보고 통과한 배포가 전체로 넓힌 뒤에 터졌다. 통과했으니 배포 탓은 아니라고 믿는 바람에 원인 찾기도 늦어졌다.
로그는 초당 수천 줄인데 요청 하나를 못 찾는다
로그는 초당 수천 줄씩 쌓이는데, 장애 때 특정 사용자의 요청 하나를 못 찾아 몇 시간을 헤맸다. 남기는 것과 찾을 수 있는 건 다르다.
분산 추적이 큐만 지나면 끊긴다
분산 추적을 붙였는데 하필 시간이 제일 오래 걸리는 큐와 워커 구간에서 추적이 끊겼다. 추적 문맥은 스레드에 묶여 있어서, 경계를 넘을 때 아무도 안 옮겨 주면 사라진다.
타임아웃 값 하나 바꿨는데 서비스가 무너졌다
콘솔에서 타임아웃 값 하나 바꿨을 뿐인데 서비스가 무너졌다. 되돌리려니 이전 값이 뭐였는지 아무도 몰랐다. 설정은 코드보다 쉽게 바뀌는데 영향은 더 클 때가 많다.
컬럼 이름 하나 바꿨는데 배포 중에 오류가 쏟아졌다
컬럼 이름 하나 바꾸고 배포했을 뿐인데 운영에서 몇 분간 오류가 쏟아졌다. 스테이징에선 멀쩡했다. 배포 중에는 옛 코드와 새 스키마가 잠깐 같이 산다.
알림이 하루 200개면 진짜 장애도 묻힌다
알림을 꼼꼼히 걸었더니 하루 200개씩 와서 아무도 안 보게 됐다. 진짜 장애 알림도 그 사이에 묻혔다. 알림이 많다는 게 안심의 근거였는데.
user_id 라벨 하나에 모니터링이 죽었다
디버깅하기 쉬우라고 지표에 사용자 ID 라벨을 붙였다. 몇 시간 뒤 모니터링 시스템이 메모리를 다 쓰고 죽었다. 서비스는 멀쩡한데 아무것도 안 보였다.
우리를 무너뜨린 건 트래픽이 아니었다
실제로 겪은 장애를 돌아보니 트래픽 때문에 무너진 건 거의 없었다. 결제사 지연, 인증서 만료, 설정 실수 같은 것들이었다. 대비는 엉뚱한 데 가 있었다.
장애도 없는데 클라우드 청구서가 세 배로 나왔다
장애도 없고 트래픽도 계획대로였는데 월말 클라우드 청구서가 예상의 세 배로 나왔다. 알림 하나 울리지 않았고, 한 달치 돈은 이미 다 나간 뒤였다.
부하 테스트는 통과했는데 출시 날 무너졌다
출시 전 부하 테스트에서 목표의 세 배를 버텼는데, 실제로는 목표치에서 무너졌다. 테스트가 틀린 게 아니었다. 시험한 조건이 실제와 달랐다.
앱 서버를 두 배로 늘렸는데 왜 그대로일까
트래픽이 늘어 앱 서버를 두 배로 늘렸는데 처리량은 그대로였고 응답은 오히려 나빠졌다. 앱 서버는 놀고 있었고, DB 만 CPU 100% 였다.
서버를 5대로 늘렸더니 레이트 리밋이 다섯 배로 샜다
초당 100회로 걸어 둔 제한이 서버를 다섯 대로 늘리자 500회가 됐다. 한곳에 모아 세니 이번엔 그 카운터가 병목이 됐다.
큐에 쌓아 두면 된다더니 서버가 메모리로 죽었다
큐에 쌓아 두면 언젠가 다 처리될 줄 알았다. 유입이 넘친 날 서버는 메모리 부족으로 줄줄이 죽었고, 쌓여 있던 것도 전부 날아갔다.
샤드는 고르게 나눴는데 한 샤드만 CPU 100%
샤드를 고르게 나눴는데 프로모션 상품 하나 때문에 한 샤드만 CPU 100% 가 됐다. 나머지는 20% 인데. 샤드를 더 늘리면 풀릴까? 안 풀린다. 키 하나는 여전히 한 샤드에 있다.
새로 띄운 인스턴스만 느리다, 늘릴수록 나빠진다
부하가 올라 서버를 늘렸는데 새로 뜬 인스턴스만 유독 느리고, 늘릴수록 상황이 나빠졌다. 같은 이미지인데도. 오래 산 인스턴스에만 쌓여 있는 게 따로 있었다.
오토스케일을 켜 뒀는데도 몇 분간 서비스가 죽었다
방송에 소개된 날 트래픽이 1분 만에 열 배가 됐다. 오토스케일은 제대로 움직였는데, 서버가 늘기까지 몇 분 동안 서비스는 죽어 있었다. 설정이 틀린 게 아니었다.
DB 페일오버는 끝났는데 앱은 왜 옛 주소로 붙을까
주 DB 가 죽고 대기 서버가 몇 초 만에 승격됐는데도 서비스는 계속 죽어 있었다. 앱이 아직 옛 주소로 붙고 있었다. 전환은 성공했는데 그 소식이 앱까지 안 닿았다.
트래픽이 세 배로 몰리면 일부는 빨리 거절해야 한다
트래픽이 세 배로 몰리자 서버는 살아 있는데 응답이 30초를 넘었다. 사용자는 이미 떠났는데 서버는 그 요청을 성실히 처리하고 있었다. 아무도 기다리지 않는 응답을 만드는 중이었다.
알림도 안 울린 장애, 범인은 로그만 찍는 catch
장애가 났는데 알림도 안 울리고 에러율 그래프도 평평했다. 몇 시간 뒤 사용자 문의로 알았다. 예외를 잡아 경고 로그만 남기는 코드 한 군데가 장애를 통째로 가리고 있었다.
DB 엔 있는 주문이 검색엔 없다, 아웃박스 패턴
DB 에는 있는 주문이 검색에는 안 나오는데 에러 로그는 깨끗했다. 두 곳에 따로 쓰면 언젠가 어긋난다. 그리고 그 어긋남은 아무 신호 없이 쌓인다.
정규식 한 줄에 CPU 가 100% 로 붙었다
이메일 형식을 확인하는 평범한 정규식 하나에 서버 CPU 가 100% 로 붙었다. 문자열 하나 검사하는 데 몇 분이 걸렸다. 정규식이 느린 게 아니라 패턴과 입력이 잘못 만난 거였다.
AWS 2017년 스토리지 장애, 명령 하나가 4시간이 됐다
2017년 AWS 스토리지 서비스가 약 4시간 멈추자 인터넷의 상당 부분이 함께 멈췄다. 시작은 잘못 입력한 명령 하나였다. 그런데 진짜 문제는 사람보다 구조 쪽에 있었다.
GitHub 의 43초 네트워크 단절은 왜 24시간 장애가 됐나
2018년 GitHub 은 데이터센터 사이 네트워크가 43초 끊긴 일로 24시간 넘게 정상이 아니었다. 원인은 1분도 안 돼 사라졌다. 나머지 시간은 판단과 검증에 들어갔다.
타임아웃을 걸었는데도 서비스 전체가 느려진다면
타임아웃을 걸어 뒀는데도 의존 서비스 하나가 느려지자 서비스 전체가 느려졌다. 실패할 걸 알면서 계속 기다리고 있었으니까. 그 고리를 끊는 게 서킷 브레이커다.
평균 응답 시간은 120ms 인데 왜 느리다고 할까
대시보드 평균 응답 시간은 120ms 인데 느리다는 문의가 계속 온다. 로그를 뒤지면 5초, 10초짜리 요청이 하루 수만 건 숨어 있다. 평균은 그 꼬리를 뭉개 버린다.
CDN 을 붙였더니 남의 이름이 보인다
CDN 을 붙였더니 내 계정에 다른 사람 이름이 보인다는 문의가 들어왔다. 에러는 한 줄도 없고 지표는 오히려 좋아졌다. 캐시는 주소만 보고 사람은 안 본다.
카프카 컨슈머가 리밸런싱만 반복한다, max.poll.interval.ms
카프카 컨슈머가 일하는 시간보다 파티션을 다시 나누는 시간이 더 길어질 때가 있다. 컨슈머를 늘려도 그대로다. 살아 있는 컨슈머가 처리 시간 때문에 죽은 걸로 판정받고 있어서다.
타임아웃을 안 걸었다면 무한대로 건 것이다
외부 API 가 에러도 없이 응답만 안 주자, 우리 서버 스레드가 하나씩 묶이더니 몇 분 만에 서비스가 멈췄다. CPU 는 한가했다. 스레드는 전부 잠들어 있었다.
DB 는 몇 초 만에 살아났는데 서비스는 왜 계속 죽어 있을까
DB 가 몇 초 느려졌을 뿐인데 서비스가 무너졌고, 원인이 사라진 뒤에도 회복이 안 됐다. 범인은 「실패하면 세 번 재시도」라는 지극히 상식적인 설정이었다.
한 번 눌렀는데 두 번 결제됐다면, 멱등성
사용자는 결제 버튼을 한 번 눌렀는데 청구는 두 번 나갔다. 응답을 못 받았다고 다시 보낸 게 원인이었다. 그런데 보낸 쪽은 처리가 됐는지 안 됐는지 알 길이 없다.
keep-alive 를 안 쓰면 악수만 하다 끝난다
상대 서비스는 5ms 만에 처리하는데 우리 쪽에서 재면 40ms 가 나왔다. 사라진 35ms 는 요청마다 연결을 새로 맺는 데 쓰이고 있었다. 설정은 맞았다. 쓰는 법이 틀렸다.
배포할 때마다 502 가 조금씩 난다
무중단 배포를 설정했는데 배포할 때마다 502 가 몇십 건씩 났다. 설정은 다 맞았다. 서버가 내려가는 순간과 트래픽이 끊기는 순간이 같지 않았을 뿐이다.
적중률 95% 인데 정각마다 DB 가 튄다, 캐시 스탬피드
캐시 적중률은 95% 인데 정각마다 DB 부하가 순간적으로 치솟았다. 알림도 안 울릴 만큼 짧아서 더 고약했다. 같은 시각에 만든 캐시가 같은 시각에 한꺼번에 만료되고 있었다.
조건에 맞는 글이 없다. 브루니가 숨었나 보다.