프로젝트 개요
핸디버스는 공연/행사 관람객들의 이동 수요를 모아 편안하게 공연을 관람할 수 있도록 버스 노선을 개설, 제공해주는 수요 응답형 모빌리티 서비스
입니다.
24년 8월, 구글폼, 노션을 활용한 작은 MVP 서비스 시절에 합류하여 25년 2월 V1 서비스를 런칭, 한달만에 누적 7000명의 유저, 1600개의 예약 건수를 기록, 1억의 매출을 달성하였습니다.
체계가 부족하던 초기 단계의 서비스에서 모빌리티 도메인의 복잡한 비즈니스 로직을 분석해 시스템과 서비스에 구조적으로 반영하였고, 이를 기반으로 많은 유저와 결제 건을 안정적으로 처리할 수 있는 WAS를 설계·개발·배포하였습니다.
이후 2025년 5월, 개선된 UX와 시스템을 바탕으로 V2 서비스를 성공적으로 런칭했으며, 타다와의 MOU 체결을 통해 수요 기반 도어 투 도어 서비스를 제공하는 신규 상품도 기획·개발하였습니다.
서비스 소개 및 특장점
수요조사와 상품 구매의 통합된 UX
기존 DRT의 분절된 수요조사와 상품 탐색 경험은 유저의 참여를 유도하기 어렵고 사이트의 생동감을 저해하는 문제점이 있었습니다. 이를 해결하기 위해 ‘행사’와 ‘정류장(PoI)’ 개념을 중심으로 수요조사와 노선의 도메인 관계를 느슨히 결합시켜 모델링하여 두 과정을 하나의 흐름으로 묶었습니다.
이를 통해 유저는 판매 중인 상품을 확인하는 것과 수요조사에 참여하는 것을 하나의 연속된 경험으로 받아들일 수 있게 되었습니다.
특히 ‘정류장’이라는 명확한 운영상 PoI(Point of Interest) 개념을 도입함으로써, 내부적으로는 운영 자동화 및 노선 설계 자동화를 위한 기술적 기반을 마련하였습니다.
데이터 기반의 자동화 시스템
실시간으로 수집되는 유저의 수요 데이터는 내부 추천 노선 설계 기술과 유기적으로 결합됩니다. 이 자동화된 파이프라인을 통해 시스템은 개별 수요를 즉각적으로 해석하고, 유저가 원하는 노선을 신속하게 식별해 제공합니다. 수요응답형 서비스에 걸맞는 ‘데이터 기반의 고객 친화적 운영’을 실현합니다.
복잡함을 감춘 편리한 온보딩
X(트위터), 팬카페 등으로 유입된 유저들이 빠르게 가입, 수요조사를 진행하도록 독려하기 위해 쾌적한 UX의 온보딩 플로우를 제공하고자 노력하였습니다.
OAuth를 활용하여 각종 약관동의 및 기본값을 원터치로 제공 받을 수 있게 하였으며, 뒷단의 복잡한 비즈니스 로직인 명의 당 첫가입 쿠폰, OAuth 연동 계정에 필수 정보가 없는 경우 등의 예외처리 등은 서버에서 엄밀히 처리하여 복잡한 온보딩 요구사항을 유저에게 은닉하였습니다.
기술적 차별점과 개인 기여
핸디버스는 제대로된 기업체나 소프트웨어도 없던 시절, 팀에 초기 창업 멤버
로 합류하여 기획과 백엔드 개발 전과정을 참여하였습니다.
스타트업 운영 전과정의 DDD 기반 시스템화
제가 합류한 초기 핸디버스는, 단순한 MVP 웹사이트와 노션, 구글폼 등으로 운영되며 유저 수요 수집부터 예약, 버스 대절, 공지 전달까지 전 과정을 수기로 처리하고 있었습니다. 결제 역시 계좌이체 후 수기 확인 방식으로, 시스템화가 전혀 이루어지지 않은 상태였습니다. “공연 시장에서 열악한 교통 환경으로 인해 셔틀버스를 원하는 수요가 있다”는 문제 인식에서 출발한 이 서비스가 성공적인 비즈니스로 발전하기 위해서는, 이러한 복잡하고 파편화된 오퍼레이션 전 과정을 정밀하게 분석하고, 이를 구조화하여 시스템에 반영하는 작업이 필수적이었습니다.
수요조사 받기 및 문자 보내기 기능만 있던 열악한 MVP
저는 서비스를 단순 자동화하는 것을 넘어, 우리가 해결하려는 핵심 도메인—즉 “공연행사 특화”, “수요기반”, “셔틀 운영”이라는 복합적인 도메인을 근본적으로 재정의하는 작업부터 시작했습니다.
도메인 주도 설계(DDD)를 차용하여, 이를 다수의 서브도메인(예: 예약, 정산, 배차, 셔틀 운영, 고객 관리 등)으로 나누고, 각 도메인 간 상호작용과 외부 오퍼레이션 흐름을 시각화하기 위해 이벤트 스토밍을 수행했습니다. 이 과정을 통해 시스템이 책임질 수 있는 경계, 구체적인 정책 포인트, 추상적이었던 운영 기준들을 명확히 했고, 유비쿼터스 언어도 함께 정립했습니다. 결과적으로 각 기능을 독립적으로 모듈화 할 수 있는 바운디드 컨텍스트들이 도출되어, 아키텍처의 기반을 형성할 수 있었습니다.
이벤트 스토밍을 통한 도메인 분석
도메인 주도 설계를 통해 운영 측에서 인식해야 할 핵심 개념과 정책을 정립하고, 이를 바탕으로 오퍼레이션 매뉴얼을 체계화할 수 있었습니다. 동시에 도메인의 본질을 반영한 시스템 설계와 유비쿼터스 언어 정립을 통해 운영·개발 간 커뮤니케이션을 통일하고, 병행 개발이 가능해져 스타트업의 빠른 사업 확장에 효과적으로 대응할 수 있었습니다.
트래픽 급증형 서비스에서 안정적인 서버 운영
핸디버스는 공연 특화형 모빌리티 서비스이고, SNS 기반 팬덤 중심형 마케팅의 영향을 많이 받는 서비스 입니다. 이에 따라 특정 팬덤 커뮤니티에서 정보가 확산되는 순간 (흔히 좌표가 찍힐 때) 순간적으로 많은 사용자가 동시에 접속하는 트래픽 집중 현상이 발생합니다.
서비스 런칭 이후의 성과 통계
이미지를 보시면 하루 동안 최대 8천명의 가입자와 6천건의 결제 및 2천건 가량의 결제 취소건이 발생했던 스파이크를 확인할 수 있습니다.
핸디버스는 사용자 요청에 대한 복잡한 연산은 적고, 외부 시스템과의 네트워크 통신이 대부분을 차지합니다. 이에 최초 개발 시 비동기 처리에 최적화된 Node.js 스택을 채택했습니다. 다수의 I/O 요청이 동시에 발생해도 메인 스레드를 막지 않았기 때문에, 트래픽 급증 상황에서도 서버는 병목 현상 없이 핵심 로직을 원활하게 수행할 수 있었습니다.
스파이크 트래픽을 안정적으로 처리했던 두 번째 요인은 인프라였습니다. ECS Fargate 기술을 활용해, 트래픽이 몰리면 자동으로 서버 수를 늘리고 트래픽이 줄면 다시 수를 줄이는 오토 스케일링 시스템을 구축했습니다.
JMeter를 통한 부하 테스트를 통해 트래픽이 폭주할 때 결국 WAS의 CPU 작업보단 데이터베이스에서 가장 먼저 문제가 발생한다는 점을 파악했습니다. 그래서 다른 장비보다 DB 서버의 사양을 높게 유지하여 시스템이 멈추지 않도록 균형을 맞춰 설계했습니다.
핸디버스는 ‘공연, 모빌리티, 수요응답형’ 서비스가 결합된 복합 도메인입니다. 이로 인해 정규화된 데이터베이스에서 단일 조회 시에도 수많은 JOIN
이 발생하는 문제가 있었습니다. 특히 쓰기 정합성을 위해 도입했던 DDD(도메인 주도 설계)의 Aggregate 패턴은, 역설적으로 조회 성능에 불필요한 객체 로딩 오버헤드를 유발했습니다.
이를 해결하기 위해 CQRS, NoSQL, CDC 등 여러 아키텍처를 검토했으나, 회사 규모와 리소스 한계를 고려해 CQRS 패턴의 핵심 사상(읽기/쓰기 분리)만을 차용하는 실용적인 접근을 택했습니다.
기존의 DDD 모델은 데이터 변경의 일관성을 책임지는 쓰기 전용 모델로 역할을 한정했습니다. 그리고 조회는 비정규화된 뷰 테이블(View Table) 기반의 독립적인 파이프라인으로 구축하여, 불필요한 객체 오버헤드를 제거하고 SQL 튜닝 효과를 극대화했습니다.
읽기/쓰기 모델을 분리하여 조회 성능을 개선했음에도, 특정 조회 API에서 데이터베이스의 쿼리 실행 속도와 최종 API 응답 시간 사이에 상당한 격차가 발생하는 현상을 발견했습니다. 근본 원인은 ORM에 있었습니다. 관계형 데이터베이스는 JOIN
결과를 중복이 포함된 거대한 ‘평평한(Flat)’ 테이블 형태로 반환하며, ORM은 이 데이터를 애플리케이션이 원하는 ‘계층적(Nested)’ JSON 객체 구조로 재조립하는 과정에서 막대한 CPU 연산을 수행했습니다.
이 문제는 관계형 데이터 모델과 객체 지향 애플리케이션 간의 구조적 불일치에서 비롯되는 고질적인 병목이었습니다. 특히 다대일 관계가 중첩될수록 ORM의 데이터 재조립 비용은 기하급수적으로 증가하여 서버에 큰 부담을 주었습니다. 이를 해결하기 위해 ORM의 역할을 최소화하고, 데이터 구조화의 책임을 데이터베이스로 이전하는 전략을 채택했습니다.
해결책으로, DB 뷰 테이블을 생성하는 단계에서부터 강한 결합도를 가진 1:N 관계 데이터를 미리 JSON 형태로 집계했습니다. 예를 들어, ‘노선’과 그에 속한 ‘정류장’ 목록을 단일 JSON 컬럼에 저장하는 방식입니다. 이를 통해 ORM의 복잡한 데이터 재조립 작업을 원천적으로 제거하고, CPU 집약적인 연산을 DB의 효율적인 집계 기능으로 이전하여 애플리케이션의 부하를 획기적으로 줄일 수 있었습니다.
수요 기반 노선 설계 자동화 기술 개발
모집된 수요조사를 기반으로, 지역 별 최적화된 노선 설계를 자동으로 해주는 알고리즘을 개발했습니다.
실제 서비스 데이터에서 도출된 노선 추천 화면
다양한 비즈니스 상황에 대응할 수 있도록 추천 설계 기준을 변수화 하였습니다.
알고리즘 최적화를 통해 2000개의 수요데이터 기준 200ms 내로 처리되도록 설계했습니다. 또한 캐싱을 활용해 실제 연산 처리에 대한 빈도 또한 최적화 하였습니다. 이를 통해 최상단의 대시보드에서 수많은 행사에 대한 노선 예측 결과를 복수조회 해도 부담없게 제작하였습니다.
확장성을 고려한 DDD 기반 모듈러 모놀리식 서비스 설계
스타트업 환경은 빠른 시장 반응이 핵심이기 때문에, 설계보다는 속도 중심의 개발이 일반적입니다. 그러나 이는 곧 유지보수와 확장에 취약한 레거시로 이어지기 쉽습니다. 저는 이러한 구조적 리스크를 예방하기 위해, 서비스 초기부터 도메인 주도 설계(DDD)의 전술적 설계 방법론을 적용하여 각 기능을 명확히 분리하고 도메인의 순수성을 보존하는 구조를 설계했습니다.
핵심 비즈니스 로직인 결제와 예약 도메인은 서로 밀접하지만 명확히 다른 바운디드 컨텍스트(BC)로 구분하고, 이벤트 기반 비동기 메시징으로 상호 통신하게 하여 강결합을 방지했습니다. 도메인 레이어 내부는 계층 간 DIP(의존성 역전 원칙)를 적용해 외부 의존성을 인프라 레이어로 분리하고, PG사나 OAuth 등 외부 채널과의 연동 로직은 인터페이스와 팩토리 패턴을 통해 추상화하여 캡슐화하였습니다. 이를 통해 도메인 중심의 유연하고 테스트 가능한 구조를 확보했습니다.
전체 구조는 MSA의 오버헤드를 피하면서도 모듈화된 아키텍처를 구현한 ‘모듈러 모놀리스’ 방식으로, 기능별 책임을 명확히 분리하되 단일 애플리케이션 내부에서 유지보수가 가능하도록 설계했습니다. 이를 통해 신규 개발자도 빠르게 온보딩할 수 있는 가독성과 일관성을 확보했고, 점진적 MSA 전환도 염두에 둔 유연한 설계 기반을 마련했습니다.
시스템 아키텍처 설계의 상세 내용은 블로그 포스트에 정리되어 있습니다.