1인개발자 티켓시스템 개발기

정토리·2022년 3월 12일
3

안녕하세요, 풀스택 개발자 햄치코치입니다.
제가 첫 번째로 개발을 한 플랫폼 (공연 티켓 판매 사이트) 를 만들면서 느낀점을 일기처럼 남겨보려합니다.

주니어 개발자의 공연티켓 개발스토리

🤩 입사 후 임무

2021년 9월 1일날 공연관련 스타트업에 합류하였습니다.

입사한 지 1주일 만에 저에게 주어진 임무는, 한 달 반~두 달 안에 뮤지컬 티켓 판매 사이트를 완성하는 것이었습니다.
개발자는 저 혼자였고, 뮤지컬은 연말에 인기가 많기 때문에 최소한 11월 전에는 오픈해야 고객 반응을 확인할 수 있었습니다. 대표님께서는 저에게 화이팅을 외치며 응원해 주셨습니다.

혼자서 서비스를 전체적으로 만들어보고 싶다는 막연한 생각을 가지고 있었습니다.
당장은 힘들겠지만 내가 전체적으로 서비스 프로세스를 이해할수 있을 거라는 마음이였습니다.

먼저, 빠르게 결과물을 만들어야 하는 상황에서 기술 스택을 정해야 했습니다.
프론트엔드에서는 React와 Vue 중 고민했지만, React에 대한 지식이 좀 더 있는 만큼 React를 선택했습니다.
백엔드는 레퍼런스가 가장 많은 Node.js와 Fastfiy 조합을 선택하게 되었고요.

또 기존에 운영하던 공연 정보를 알려주는 서비스가 중단되면서,
그때 사용하던 MongoDB에 이미 공연 관련 스키마가 남아있었습니다.
이를 유지하고 활용하기로 했습니다.

기술스택

  • React
  • Nodejs + express
  • mongodb 기존 회원정보, 공연정보(공연장, 아티스트)
  • mysql 회원 포인트 저장, 티켓 발권 등

🤪 아무것도 모르고 개발 재택근무 밤샘 개발의 시작

저의 회사의 유일한 개발자 였습니다.
2달동안 개발해야하는 목록은 크게 2가지 였습니다.

웹서비스

  • 웹 백엔드: 메인 웹사이트의 로그인, 결제, 티켓구매 API 등
  • 웹 프론트엔드: 사용자들이 공연을 확인하고 티켓을 구매할 수 있는 화면개발

CMS (콘텐츠 관리 시스템)

  • CMS: 공연정보, 티켓, 유저, 포인트머니 관리 기능을 포함한 관리자용 페이지
  • CMS: 좌석도 업로드 기능

위에 처럼 좌석을 보여주고 관리자가 지정한 판매석만 오픈 해야했습니다.

🪑 좌석도 만들기

공연 판매의 핵심인 좌석도를 만들어야 했습니다.

  • 어떻게만들지?
  • 어떻게 판매하는좌석으로 하지?
  • 어떻게 좌석을 닫아버리지?
  • 좌석의 등급 및 가격은 어떤좌석에 매칭시키지?
  • 좌석번호는 어떻게 입력하지?

생각해보면 좌석도는 일반적으로 엑셀처럼 칸별로 있다는 생각에 엑셀로 만들어서 업로드하는 방식으로 만들 수 있었습니다.

서비스 런칭 및 회고 (충전금액 폭팔)

🚨 서비스 중 발생한 문제와 해결 과정
서비스 런칭 이후, 3개 공연은 문제 없이 잘 진행되었습니다. 이후 유명한 공연을 진행하게 되어 30분간 충전금액이 말도안되게 충전되었습니다. 서비스가 점차 성장하고 있다는 걸 실감할 수 있는 순간이었죠.

첫번째 문제

하지만, 예상하지 못한 트래픽 폭주로 인해 한 번은 서버가 다운되는 상황이 발생했습니다. 이때는 임시방편으로 서버와 RDS 용량을 급격히 늘렸고, Redis를 활용해 공연 정보와 같은 실시간 변동되지 않는 데이터를 캐싱하는 방법을 도입했습니다. 이를 통해 공연 소개, 포스터, 공연장 정보 등은 캐시 처리하여 서버 부하를 줄였고, 서버가 터지는 문제는 해결할 수 있었습니다.

두번째 문제

그럼에도 불구하고, 두 번째 문제가 발생하게 되었습니다. 동일한 좌석을 2명이 구매한 경우가 발생한 것입니다. 이 문제는 서비스에서 가장 중요한 좌석 예매 시스템에서 발생한 동시성 문제였고, 공연을 좋아하는 고객들에게는 큰 불편을 주는 상황이었습니다. 결국, 고객에게 좌석이 잘못 판매된 점에 대해 설명하고, 직접 전화로 사과와 버그 설명을 해야 했습니다. 이때는 개발자로서 고객 서비스를 직접 경험할 수 있었고, 고객의 입장에서 이해할 수 있는 서비스 개선의 필요성을 절실히 느꼈습니다.

🛠️ 문제 해결 과정

이 문제를 해결하기 위해, 처음에는 MongoDB에 저장된 좌석 정보를 활용하여
Mysql에 ["1열 2번", "1열 3번"] 형식으로 좌석을 처리하고 있었으나, 유니크 인덱스를 고려하지 않은 설계 때문에 동시성 문제를 제대로 처리하지 못했습니다.

이를 뒤늦게 깨닫고, 복합 유니크 인덱스를 사용하여 좌석 데이터의 유니크성을 보장하려고 했지만, 여전히 실시간 좌석 구매에서의 동시성 문제를 해결하는 데 한계가 있었습니다.

이후, Redis에서 제공하는 atomic (increment) 기능을 활용하여, 좌석을 구매할 때마다 좌석 번호에 대해 incr 명령어를 사용해 좌석을 예약하는 방식으로 개선했습니다. 이를 통해, 각 좌석마다 구매가 이루어지면 그 좌석의 상태가 atomic하게 증가되며, 첫 번째 사용자가 맞는지 체크할 수 있는 시스템을 만들었습니다. 결제 과정 중에는 해당 좌석이 이미 예약된 상태라면 두 번째 구매자가 좌석을 구매할 수 없도록 처리할 수 있게 되었습니다.


소감

해당 회사에 근무 할 당시 저는 플랫폼 개발경험이 없는 신입 개발자였습니다.
이 과정에서 동시성 문제를 해결하면서, 서비스 안정성을 한층 높일 수 있었고,
고객에게 더 신뢰를 줄 수 있는 시스템으로 발전할 수 있었습니다. 또한, 이 문제를 해결하는 과정에서 Redis와 같은 캐시 시스템을 어떻게 효율적으로 활용할 수 있는지에 대해 많은 것을 배울 수 있었습니다.

profile
풀스택으로 개발하고 공부하고 있습니다. 감사합니다.

10개의 댓글