실제 엔지니어를 위한 보물찾기 엔진 설계하기
요약
게임 플랫폼의 보물찾기 엔진인 Veltrix를 구축하며 겪은 모놀리식 아키텍처의 한계와 마이크로서비스로의 전환 과정을 다룹니다. 확장성 문제와 지연 시간을 해결하기 위한 아키텍처 설계 및 성능 최적화 경험을 공유합니다.
핵심 포인트
- 모놀리식 구조의 확장성 한계와 성능 저하 문제 직면
- 마이크로서비스 아키텍처 도입을 통한 독립적 구성 요소 확장
- Prometheus와 Grafana를 활용한 실시간 성능 모니터링
- 5만 명 동시 접속 시에도 200ms 미만의 응답 시간 달성
우리가 실제로 해결하고 있었던 문제
저는 인기 있는 게임 플랫폼을 위한 보물찾기 엔진을 구축하는 팀의 일원이었습니다. 이 엔진은 사용자들에게 점점 더 어려워지는 도전 과제와 더욱 매력적인 보상을 통해 몰입형 경험 (immersive experiences)을 제공할 것을 약속했습니다. 우리의 목표는 명확했습니다. 실시간으로 보물찾기를 동적으로 생성할 수 있고, 대규모의 동시 접속 사용자 (concurrent users)를 처리하며, 실시간 단서, 퍼즐, 힌트를 제공할 수 있는 엔진을 만드는 것이었습니다. 간단하게 들리나요? 하지만 현실적으로 우리의 시스템은 사용자 기반이 성장함에 따라 성능 문제, 지연 시간 급증 (latency spikes), 그리고 빈번한 충돌 (crashes)로 가득 차 있었습니다.
우리가 처음에 시도했던 것 (그리고 실패한 이유)
처음에 우리는 Veltrix라고 명명된 우리의 보물찾기 엔진이 퍼즐 생성부터 데이터베이스 쿼리 (database queries)까지 모든 것을 처리하는 하나의 커다란 모듈인 모놀리식 아키텍처 (monolithic architecture)를 채택했습니다. 우리는 개발의 용이성과 빠른 시장 출시 (time-to-market)를 위해 이 접근 방식을 선택했지만, 이것이 확장 (scale)될 수 없다는 것이 곧 분명해졌습니다. 우리의 솔루션은 새로운 요청과 사용자의 부하 아래 서버가 질식하면서 빠르게 한계에 도달했습니다. 우리는 문제 해결을 위해 더 많은 하드웨어를 투입하려 노력했지만, 결국 서버 군단을 구축할 수 있다 하더라도 우리의 시스템 아키텍처가 근본적으로 망가져 있다는 것을 깨달았습니다.
아키텍처 결정
몇 주간의 자기 성찰과 격렬한 토론 끝에, 우리는 Veltrix를 독립적으로 확장할 수 있는 더 작고 관리하기 쉬운 구성 요소들로 분해하기로 결정했습니다. 우리는 퍼즐 생성, 사용자 인증 (user authentication), 그리고 데이터베이스 쿼리가 각각 별도의 프로세스에 의해 처리되는 마이크로서비스 아키텍처 (microservices architecture)를 구현했습니다. 이를 통해 모든 것을 한꺼번에 업그레이드할 필요 없이, 어떤 구성 요소에 더 많은 리소스가 필요한지 쉽게 선택하고 결정할 수 있게 되었습니다. 우리의 새로운 설계는 또한 실시간 성능 지표 (performance metrics)를 기반으로 리소스 할당을 동적으로 조정하는 구성 계층 (configuration layer)을 구현할 수 있게 해주었습니다.
수치가 말해주는 것
새로운 아키텍처(architecture)가 구축된 후, 우리는 이번에는 성능 지표(performance metrics)에 온전히 집중하며 사용자 부하(user load)를 다시 도입했습니다. 우리는 Prometheus와 Grafana 같은 도구를 사용하여 응답 시간(response times), 처리량(throughput), 메모리 사용량(memory usage)과 같은 핵심 성과 지표(KPI)를 모니터링했습니다. 결과는 놀라웠습니다. 사용자 수가 50,000명의 동시 접속자(concurrent users)로 급증했을 때도 초당 500개의 요청(requests per second)이라는 일관된 처리량을 유지했으며, 평균 응답 시간은 200밀리초(milliseconds) 미만을 기록했습니다. 또한, 이전에는 우리 시스템을 괴롭혔던 지연 시간 급증(latency spikes)과 크래시(crashes)가 현저히 감소한 것을 관찰할 수 있었습니다.
다르게 했을 점
돌이켜보면, 처음부터 좀 더 신중한 접근 방식을 취했더라면 좋았을 것 같습니다. 우리는 프로젝트 마감 기한을 맞추는 데 너무 몰두한 나머지, 몇몇 명백한 아키텍처(architectural) 문제들을 간과했습니다. 만약 다시 해야 한다면, 확장 가능한 시스템(scalable system)을 설계할 때 수반되는 근본적인 트레이드오프(trade-offs)를 조사하고 이해하는 데 더 많은 시간을 할애할 것입니다. 구체적으로, 개발의 용이성(ease of development)이나 빠른 시장 출시(fast time-to-market)보다 지연 시간(latency)과 처리량(throughput)을 우선시할 것입니다. 우리의 경험은 복잡한 시스템을 설계할 때 신중한 계획과 실제 성능에 미치는 영향에 대한 고려가 얼마나 중요한지에 대한 값진 교훈이 되었습니다.
나는 이것을 내가 AI 도구(AI tooling)를 평가하는 방식과 동일하게 평가합니다: 무엇이 실패하는지, 얼마나 자주 실패하는지, 그리고 실패했을 때 어떤 일이 발생하는지 말입니다. 이 항목은 통과입니다: https://payhip.com/ref/dev3
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기