Problem

GCS 동시 처리 미지원으로 인한 시뮬레이션 중단 문제

  • 동시 처리 지원의 부재: GCS(중앙통제시스템) 서버가 동시 처리를 지원하지 않아, 웹 서버로부터 새로운 시뮬레이션 요청이 들어오면 기존 진행 중이던 시뮬레이션이 강제 취소됩니다.
  • 장시간 양방향 통신 서버: GCS 서버는 Unity와 장시간(평균 10분) 양방향 데이터 통신을 통해 시뮬레이션을 진행하기 때문에, 중간에 중단되면 사용자는 처음부터 다시 시작해야 합니다.

결론적으로 여러 사용자가 동시에 서비스를 이용할 수 없어 실질적으로 1인 전용 서비스 상태입니다.

간단하게 상황을 정리해 본다면 아래와 같습니다.

  • 아키텍처: 웹 서버 → GCS 서버 ↔ Unity 시뮬레이션
  • GCS 서버: 단일 인스턴스, 동시 세션 미지원
  • 동작 방식:
    • 요청 A 진행 중 → 요청 B 들어옴 → 요청 A 취소됨 → 요청 B 시작
    • 단순 요청-응답이 아닌 장시간 상태 유지가 필요한 세션 기반 서비스

Analysis

기술 스택의 파편화와 하드웨어 자원 한계

문제에 대한 핵심 원인은 GCS 서버에 멀티세션/동시 처리 로직이 구현되지 않았기 때문 입니다. 단순하게 생각하면, 해당 로직을 추가하면 되었지만, 몇가지 제약사항이 존재했습니다.

  • 조직적 제약: GCS 팀은 MVP 기능 구현에 집중하고 있어 동시성 로직 추가 여력이 부족하며, 본인은 Python 기반 웹 개발 중이므로 C# 기반의 GCS 코드를 단기간에 수정하기에 리스크가 큽니다.
  • 자원 점유 문제: 시뮬레이션 특성상 CPU/Memory 자원 사용량이 매우 높아, GCS 서버 내부에서 멀티 세션을 구현하더라도 단일 인스턴스가 버티지 못하고 성능 저하가 발생할 가능성이 높습니다.

대안 분석

이러한 제약을 염두에 두고 다양한 해결 방안을 검토하였습니다

대안 1. GCS 멀티세션 구현 + 비싼 클라우드 서버 사용

GCS 서버 내부 로직을 수정하여 한 대의 서버가 여러 시뮬레이션을 동시에 처리하도록 만드는 방식입니다.

  • 상세 내용
    • GCS 서버 내에서 개별 요청마다 독립적인 세션을 생성하고 Unity와 통신하게 합니다.
    • GCS 서버는 시뮬레이션을 진행하기 위해 많은 자원을 사용하기 때문에, 보다 더 비싼 서버를 사용합니다.
  • 장점
    • 가장 근본적인 해결책입니다.
    • 아키텍처가 단순합니다.
  • **단점
    • GCS 서버의 코드를 수정할 인원이 마땅치 않습니다.
    • 고성능 서버 도입에 따른 고비용이 발생합니다.

대안 2. Redis 큐 + 단일 서버

한 번에 단 한 명만 서비스를 이용할 수 있도록 강제하는 방식입니다.

  • 상세 내용: Redis queue 를 활용해 요청을 줄 세우고, 웹 서버가 GCS 서버의 상태를 확인하여 비어 있을 때만 요청을 하나씩 던집니다.
  • **장점
    • 빠른 구현이 가능합니다.
    • 서버 자원 사용량이 예측 가능하며 안정적입니다.
  • **단점
    • 동시 요청시 무조건적인 대기가 발생하여 사용자 경험 측면에서 치명적입니다. 심지어 시뮬레이션 시간 만큼 대기 해야합니다.

대안 3. Redis 큐 + 수동 스케일링

웹 서버가 여러 대의 GCS 서버 리스트를 알고 있고, 이용 가능한 서버를 찾아 요청을 배분하는 방식입니다.

  • 상세 내용:
    1. GCS 서버를 복제하여 여러 대 띄웁니다
    2. Redis에 각 서버의 사용 여부(Lock)를 기록합니다
    3. 웹 서버는 큐에서 요청을 꺼낼 때 비어 있는 GCS 서버를 찾아 매칭해 줍니다.
  • 장점:
    • 구현을 담당할 인원이 있습니다.
    • 대안 2에 비해 사용자 경험이 향상됩니다.
    • 서버 자원 사용량이 예측 가능하며 안정적입니다.
    • 트래픽이 늘어났을 때 쉽게 확장할 수 있습니다.
  • 단점:
    • 서버 추가/제거 시 수동으로 조절해야 합니다.
    • 여전히 사용자가 오래 대기할 위험성이 있습니다.

대안 4. Docker 컨테이너 및 Auto Scaling

트래픽에 따라 서버가 자동으로 생성되고 사라지는 방식입니다.

  • 상세 내용: GCS 서버를 Docker 이미지로 만들고, AWS ECS나 Kubernetes 상에서 큐의 길이에 따라 인스턴스 개수를 자동으로 조절(Auto Scaling)합니다.
  • 장점: 자동화된 시스템으로 운영 공수가 거의 들지 않습니다.
  • 단점: Docker를 사용하지 않으며, 아키텍쳐적인 이해가 부족하기 때문에 시간 내에 완수하기에는 리스크가 있습니다.

최종 선택: 대안 3

현재 프로젝트의 MVP 단계와 팀의 리소스를 고려했을 때, 대안 3이 가장 합리적이라고 판단했습니다.

  1. 리스크 최소화: GCS 서버의 복잡한 C# 내부 로직을 건드리지 않고, 익숙한 Python 웹 서버에서 해결이 가능합니다.
  2. 비용 및 성능 효율: 고가의 고사양 서버 한 대를 운영하는 것보다, 적절한 사양의 인스턴스를 필요할 때마다 추가하는 방식이 비용 관리 측면에서 유리합니다.

Solution

Redis 기반 요청 직렬화 및 전략적 인프라 운영

전략

  • GCS 서버 수정 없이 웹서버 레이어에서 동적 할당
  • 즉시 구현 가능한 방법으로 시작 → 차후 확장(대안 4)

로직

  • 요청 접수: 사용자가 시뮬레이션을 요청하면, 웹 서버는 먼저 Redis에 등록된 GCS 서버들 중 현재 사용 가능한 서버가 있는지 확인합니다.
  • 비어 있는 서버가 있다면: 해당 서버에 즉시 ‘점유 중(Lock)’ 표시를 하고 시뮬레이션을 시작합니다.
  • 모든 서버가 사용 중이라면:
    • 사용자를 Redis 큐(Queue)에 대기시킵니다.
    • 진행 중이던 시뮬레이션이 끝나 서버가 가용 상태가 되면, Redis는 큐에서 기다리던 다음 사용자를 자동으로 비어 있는 서버에 연결해 줍니다.

Result

회고

처음에는 GCS 서버의 동시 처리 미비가 ‘결함’이라고만 생각했습니다. 하지만 분석을 통해 시뮬레이션의 높은 자원 점유율을 고려할 때, 오히려 서버 한 대당 한 세션을 보장하는 것이 성능 안정성 면에서 더 뛰어난 전략일 수 있음을 깨달았습니다.

팀원 모두가 아키텍쳐적인 지식이 부족하고, 시간 또한 부족해서 AWS auto scaling 등을 시도해 보지 못했지만, 자동적으로 서버를 sacle out 할 수 있는 서비스인 만큼 차후에 적용하는 방향으로 나아가면 좋을 것같습니다.