Case Study · AI 게임 스타트업 실서비스 (2026.06 ~ )

경보가 없으면 사고가 없는 것이 아니라,
보이지 않을 뿐이다

수동 배포에 알림이라곤 서버 다운 경보 1개뿐이던 실서비스를 맡아, 잠복해 있던 에러 22.6만 건과 메모리 붕괴의 원인을 찾아내고, 마케팅발 트래픽 10배 급증을 에러율 0.05% 이하로 수용하기까지 3개월의 기록입니다. 모든 수치는 CloudWatch, 배포 로그, Cost Explorer로 재현할 수 있습니다.

다이어그램 렌더링 중…

1. 시작점: 조용한 시스템

합류했을 때 이 서비스의 알림은 서버가 죽었는지를 알리는 경보 하나가 전부였습니다. 애플리케이션 로그는 관측을 전제로 설계돼 있지 않았고, 대시보드는 없었습니다. 시스템은 조용했습니다. 문제는, 조용한 이유를 아무도 설명할 수 없었다는 것입니다.

2. 가시화: 들을 귀부터 만들기

기능 개발보다 로깅을 먼저 손봤습니다. 관측 가능한 로그를 심고, 그 위에 CloudWatch 메트릭 필터와 경보 39개, 대시보드 12개를 Terraform 코드로 구축했습니다. 체계가 서자마자 결과가 나왔습니다. 경보 없이 쌓여 있던 누적 에러 226,012건이 드러났고, 분류해 보니 단일 근본원인이 65%였습니다.

3. 발견: 동시 접속 다섯에 무너지는 서버

대시보드에 잡힌 가장 위험한 신호는 메모리였습니다. 동시 접속이 한 자릿수인데 메모리 점유율이 급등해 프로세스가 넘어지는 패턴이 보였습니다. 인메모리로만 들고 있던 캐릭터 기억 데이터가 eviction 없이 무한 증가하는 구조였고, 로컬 측정에서는 12분 만에 170개가 1,554개로 불어나며 메모리를 밀어냈습니다. 상태가 전부 프로세스 안에 있으니, 프로세스가 죽으면 사용자 데이터도 함께 사라질 수 있는 구조적 위험이 있었습니다.

4. 재현: 고치기 전에 증명하기

바로 고치지 않고 k6로 같은 붕괴를 재현했습니다. 20VU에서 p95 90ms로 버티다가 50VU에서 붕괴하는 지점을 실측으로 확정하고 나서야, 원인이 추정이 아니라 사실이 됐습니다. 이 숫자는 이후 인스턴스 사이징과 확장 설계의 근거가 됐습니다.

5. 재설계: 상태를 프로세스 밖으로

인메모리 상태를 RDS(PostgreSQL)와 DynamoDB로 영속화하고, RAM에는 상한이 있는 워킹셋만 남겼습니다. append 전용 쓰기와 recency 복합 인덱스, UPSERT 멱등 쓰기로 엔진의 읽기·쓰기 패턴을 감당하게 설계했고, 전환은 기능 플래그로 경로를 나눠 단계적으로 진행해 중단 없이 넘어갔습니다.

다이어그램 렌더링 중…

6. 시험대: 트래픽 10배

마케팅으로 트래픽이 일 최대 7만 요청까지 10배 급증했을 때, 서비스는 에러율 0.008~0.05%, 응답 p95 0.3초로 받아냈습니다. 개선 전 나쁜 날의 에러율이 최대 2.9%였으니 30배 이상의 차이입니다. 동시 활성 세션은 한 자릿수에서 세 자릿수 피크까지 무중단으로 올라갔습니다.

지표개선 전개선 후
경보 체계서버 다운 알람 1개경보·메트릭 필터 39개, 대시보드 12개
에러 가시성무경보 (22.6만 건 잠복)표면화 후 단일 근본원인 65% 규명
급증 구간 에러율최대 2.9%0.008~0.05% (p95 0.3초)
동시 세션 수용력한 자릿수에서 불안정세 자릿수 피크 무중단
배포수동, 16분CI/CD, 8분

7. 배운 것

01 · 경보가 없으면 사고가 없는 것이 아니라, 보이지 않을 뿐이다

에러 22.6만 건은 시스템이 조용해서 없던 것이 아니라, 들을 도구가 없어서 안 들렸을 뿐입니다. 관측을 세우기 전의 '무사고'는 성과가 아니라 미지수입니다.

02 · 원인은 재현한 다음에 말한다

메모리 그래프가 튀는 것을 보고 바로 고치지 않고, k6로 같은 붕괴를 재현해 원인을 확정한 뒤 움직였습니다. 재현 없는 수정은 두 번째 장애의 예약입니다.

03 · 구조 교체는 스위치가 아니라 단계 전환으로

인메모리에서 DB로의 이전은 기능 플래그로 경로를 나눠 검증하며 넘어갔습니다. 되돌릴 수 있는 전환이었기 때문에 무중단이 가능했습니다.

아키텍처 다이어그램 원본과 나머지 프로젝트는 포트폴리오에서, GitHub에서 코드로 확인할 수 있습니다. · tksz0613@gmail.com