발단
이 카톡의 시작으로 PM분과 만나서 팀을 꾸리게 되었습니다. 이 때 상당히 흥미로운 주제를 가지고 오셔서 고민 없이 바로 둘이서 팀을 만들기 시작했습니다.
개발을 시작하기 전까지 사람을 모으는 것이 가장 어려웠습니다. 구인 광고를 해도 아무것도 없는 팀에 선뜻 도전하는 사람은 없었습니다. 저 역시 개인적인 카톡이 오기 전에는 관심이 없었기 때문에 이해는 갔습니다.
그래서 지인 중심으로 사람을 모으기 시작했습니다. 그러나 주변에 백엔드 개발자만 있어서 그런지 프론트엔드 개발자를 구하기가 쉽지 않았습니다.
왜 기업들이 사람을 뽑기가 어렵다고 하는지 간접적으로 체험할 수 있었습니다.
여차저차해서 개발 시작 전까지 1 PM, 1 디자이너, 2 백엔드, 3 프론트 총 7명이 모였고,
개발 중간에 프론트 1명이 추가로 합류하여 총 8명이 MVP를 개발하였습니다.
아이디어
PM분이 가져온 아이디어는 학교 주변의 카페와 연결하여 커피 원격 주문 서비스를 학생들에게 제공하는 것이었습니다. 이 아이디어는 학생들이 교내 카페를 쉬는 시간에 이용하고 싶더라도 줄이 너무 길어서 이용하지 못하는 경우가 많다는 점에서 출발했습니다.
실결제 서비스가 궁금하기도 하였고, 아무도 사용하지 않더라도 최소한 저
라는 유저 한 명은 서비스의 끝까지 사용할것 같아서 긍정적으로 생각했습니다.
계획
개발 기간은 매우매우 촉박하였습니다. 각자 기존에 계획된 일정을 마무리하고 10월 23일에 개발 시작을 하기로 결정했기 때문이었습니다.
배포는 기말고사(12월 11일 전주)인 12월 4일에 하기로 계획을 했었는데, 왜냐하면 학생수가 종강주에 점점 줄어 들기 때문에 최소한 그 전 주에는 서비스를 시작해야 유의미한 데이터를 얻을 수 있다고 판단했기 때문입니다.
또한 유의미한 데이터를 얻지 못하면 다음 학기에 서비스를 시작해야 하는데, 그렇게 된다면 경험상 팀이 흩어지는 경우가 많기 때문에 종강전 까지 빨리 서비스를 시작해야 했습니다.
따라서 6주
라는 짧은 기간내에 실제 결제가 가능한 서비스를 만들어야 했기 때문에 속도와 안정성 이라는 모순된 목표를 가지고 개발을 진행했습니다.
기획
기획 단계에서 고려해야 했던 부분은 여러가지가 있었습니다. 먼저 크게 핵심 기능인 학생들이 커피를 멀리서 주문을 하기 위한 유저 페이지
와 유저의 주문을 카페 사장님이 받기 위한 점주 페이지
가 필요했습니다.
기능적으로 유저 페이지에는 로그인
, 메뉴판
, 장바구니
, 주문
, 결제
, 결제 취소
, 주문 상태
,주문 내역
, (주문) 즐겨찾기
, 이벤트
, 쿠폰
등 여러가지가 있었고,
점주 페이지에는 로그인
, 주문 거부
, 주문 수락
, 주문 상태 변경
, 주문 내역
, 알림톡 전송
, 메뉴 품절
, 매출 확인
등이 있었습니다.
대학생 8명이 학교를 다니며 6주내로 개발을 할 수 있을지 의심이 들었지만 실패를 하더라도 최선
을 다해보자는 마음으로 개발을 시작했습니다.
인프라 설계
인프라를 할 수 있는 사람이 저밖에 없기 때문에 저 혼자서 인프라를 설계하고 구축하였습니다. 같이 논의할 사람이 없기 때문에 외로운 작업이었습니다.
인프라를 설계 할 때는 비용
이라는 큰 제약이 이었기 때문에 AWS
와 Oracle Cloud
의 프리티어
를 최대한 사용하려고 노력했습니다. 그러고 나서 추후에 AWS Activate를 통해서 크레딧을 받고 나면 AWS
로 이전을 하기로 결정했습니다.
실제 서비스가 시작되면 오류에 대한 수정이나 기능 추가에 대한 점검을 서버에서 하기 어렵기 때문에 main서버
와 dev서버
를 분리하기로 했습니다.
메인 서버
개발 서버
인프라에 투자할 시간이 많이 없어서 모니터링을 도입하지 못한건 아쉬웠습니다. 메인서버가 Oracle Cloud
이기 때문에 AWS
의 CloudWatch
를 사용할 수 없었고, 모니터링 시스템을 직접 구축하기에는 많은 리소스가 들기에 2주라는 서비스 기간 동안 제가 인간 CloudWatch
가 되기로 결정했습니다.
불행인지 다행인지 동시 접속자가 30명을 넘어가지 않아서 서버가 죽는 일은 없었습니다.
Github Action
이번에 처음으로 Github Action
을 사용해보았는데, 매우 만족스러웠습니다.
기존 프로젝트에서 인프라를 담당했을 때는 변경이 일어나면 제가 직접 빌드
하고 수동
으로 서버에 접속해서 배포
를 했었습니다. 그러다 보니 저도 시간을 많이 잡아먹고, 상대방도 저를 기다려야 했기 때문에 매우 비효율적
이었습니다. 그 과정에서 오류
가 발생 한다면 더더욱 시간이 많이 소요되었습니다.
그래서 시간이 많이 없는 이번 프로젝트에서는 CI/CD
를 도입하기로 마음 먹었는데, yml파일로 관리가 쉬운 Github Action
을 사용하기로 결정했습니다.
여러 커스텀을 해서 빌드에 실패를 하면 닫아버리고, 빌드에 성공하면 서버에 접속해서 자동으로 배포
를 하도록 설정했습니다. 그리고 모든 결과에 대해서 디스코드
로 알림을 받도록 설정했습니다. 그 결과 모두의 시간을 아낄 수 있었습니다.
그래도 단점이 아닌 단점이 있었습니다. 비용
절감을 위해서 organization Free
플랜을 썼었는데 organization secrets
를 사용 못해서 4개의 레포지토리(점주 백/프, 유저 백/프)에 모두 secrets
를 등록해야 했습니다. 그래서 관리가 힘들었지만 적은 러닝커브로 CI/CD
를 사용할 수 있어서 좋았습니다.
그래도 Github Action
을 사용하지 않았더라면 프로젝트를 완성하지 못했을 것이라고 장담합니다.
ERD 설계
ERD를 설계하는 것은 쉽지 않았습니다. ERD를 잘못 설계하면 나중에 엄청난 비용
을 치뤄야 하기 때문에 신중하게 설계해야 했습니다. 하지만 나름 신중하계 설계를 했다고 생각했고 설계의 이유도 있었지만, 실제 개발을 하면서 더 나은 방법이 있어서 ERD를 수정하게 되었습니다.
초기 ERD보다 많은 수정을 했지만, 그래도 개선할 점이 많이 보입니다.
개발
기획과 인프라가 끝나고 개발을 시작했습니다. 백엔드는 2명으로 둘 다 사용해 본적이 있는 Spring Boot
를 사용하기로 결정했습니다. API명세서를 작성해 보니 약 50개의 API가 필요했고, 저는 외부 API(PG사, 알림톡)과 관련된 API를 맡았습니다.
PG사는 TossPayment
를 사용했습니다. 주문, 결제를 처음으로 해보는 것이라 이해를 하는데 시간이 걸렸지만, 이해를 하고나니 TossPayment
의 인프라가 매우 잘 구축되어 있어서 개발이 매우 쉬웠습니다.
테스트 결제
에서는 결제 실패
를 하는 경우가 없어서 결제 실패
에 대한 처리를 하지 못했는데, 실제 결제
에서는 결제 실패
가 생기는 경우가 있어서 당황했습니다. 3건
이 결제 실패
가 되었는데, 모두 잔액 부족
이었습니다. 그래서 테스트 환경
과 실제 환경
이 다르니 테스트 환경
에서 장애가 발생하지 않더라도 실제 환경
에서는 장애
가 발생할 수 있다는 것을 깨달았습니다.
단기간 내에 개발을 해야했기 때문에 기존에 공부했던 것들이 큰 도움이 되었습니다. 그 중에서 보안
공부를 했던것이 가장 도움이 되었습니다. 결제가 들어가는 서비스이다 보니 시큐어 코딩
을 신경 써서 적용할 수 있었고, 모든 결제에 대해 DB데이터와 Tosspayment
데이터를 비교해 보았을 때 모두 일치
하는 것을 확인할 수 있었습니다.
개발 중간에도 Race Condition
이 발생할 수 있는 부분을 발견할 수 있었습니다. 쿠폰 발급
과 쿠폰 사용
두 가지 경우에서 발생 할 수 있었습니다.
쿠폰 사용
의 경우 isUsed
를 true
로 바꾸는 경우라 낙관적 락
을 사용해서 해결했습니다.
하지만 쿠폰 발급
의 경우 락
을 사용해서 해결하지 못했습니다. 쿠폰 발급
은 쿠폰 테이블
에 존재하는 쿠폰의 갯수
를 센다음에 쿠폰의 갯수
가 쿠폰 상세 테이블
에 존재하는 발급 가능 갯수
보다 작으면 쿠폰 발급
을 하도록 했습니다.
SQL count
는 데이터의 변경이 아니라서 락
을 걸 수 없었습니다. 그렇다고 테이블 락
을 사용하기에는 쿠폰 발급
, 쿠폰 사용
이라는 작업이 자주 일어난다고 판단하여 테이블 락
을 사용하기에는 적절하지 않았습니다.
그래서 대신에 Synchronized
를 사용해 쓰레드
를 조정하여 해결하였습니다. 하지만 먼~~훗낫 MSA
환경이 된다면 Synchronized
를 사용할 수 없기 때문에 완벽한 해결책은 아닙니다.
글을 작성하고 있는 지금 생각한건데 쿠폰 상세 idx
와 유저 idx
를 복합키
로 설정하고 유니크
를 걸어서 쿠폰 발급
할 때 유일성
을 보장합니다. 그리고 쿠폰
에 사용 가능 횟수
를 두어서 쿠폰 사용
할 때 사용 가능 횟수
를 차감(낙관적 락)
하는 방법으로 해결할 수 있을 것 같습니다.
QA
개발을 다 하고 나니 서비스 시작 예정까지 6시간
도 남지 않았습니다. 점주
님들과의 계약
이 있었기 때문에 서비스 시작을 미루기가 어려웠습니다. 그래서 남은 시간동안 QA
를 진행했습니다.
이미 출시 때문에 며칠을 밤을 새서 개발을 했기 때문에 마지막 QA와 수정은 모든 팀원들이 정신력
으로 버틴것 같습니다. 그래도 끝까지 포기하지 않고 QA를 한 덕분에 치명적인 오류는 없었습니다.
이슈
문제는 QA까지 완료한 이후에 발생했습니다. QA를 다한 후 30분 뒤 점주
님에게 주문 승인용 아이패드를 전달해 드릴려고 준비를 하고 있었는데, 아이패드에서 점주페이지
가 하얀 화면
이 나오면서 아무것도 보이지 않았습니다.
원인을 모르나 최신 iphone
과 mac
에서는 잘 실행 돼서 ios
의 버전 문제
라고 추측하였습니다. 하지만 아이패드가 구형
아이패드라서 최신 버전을 설치할 수 없었습니다. 그래서 팀 내에 유일한 mac
인 저의 맥북에 연결을 하여 확인했습니다.
확인해보니 ios
에서 정규식
을 사용할 때 후위표기
를 지원하지 않아서 발생하는 문제였습니다. 원인을 파악한 후에는 금방 해결할 수 있었습니다. 만일 저도 윈도우를 사용하고 있었다면 어떻게 해결을 했을지 모르겠습니다.
반응
유저
아쉽게도 유저들의 반응은 예상보다 뜨겁지는 않았습니다. 이미 종강
을 한 강의도 존재했고, 홍보가 잘 되지 않아서 저희 서비스를 알지 못하는 사람들이 많았습니다. 그래도 2주간의 서비스 기간동안 227
명의 유저가 저희 서비스를 이용해 주었습니다.
홍보 부스를 운영했는데 몇몇 분들이 응원을 해주시고 치켜세우기도 해주셔서 매우 감사했습니다.
점주
점주님들의 반응은 매우 좋았습니다. 한 점주님은 계약 때 시험기간에 바쁘다는 이유로 3일
만 서비스를 사용하신다고 말씀을 해주셨는데, 3일이 지나고 마지막 주차
까지 계속해서 서비스를 사용해 주셨습니다.
하지만 점주 페이지에서 아이패드로 오래 창을 켜두고 있으면 주문이 들어올 때 알림 소리가 나지 않는다는 버그
를 알게 되었습니다. 그래서 점주님들께서는 주기적으로 확인을 해 주문이 들어왔는지 확인을 해야 했습니다. 이 부분은 모든 점주님들께서 불편하다고 하셨고 다음 학기까지 수정하기로 했습니다.
크론탭을 이용해서 매주 월요일마다 DB에 있는 주문 내역을 액셀로 바꾸고 정리해서 드라이브에 저장하는 자동화 프로그램을 만들었는데, 이 부분도 점주님들께서 매우 만족해 주셔서 기분이 좋았습니다.
지표
현재까지 측정한 지표로는 서비스가 지속가능한지 판단을 하는데 무리라고 생각합니다. 아직 해보지 못한것들도 많고 마케팅
도 부족하다고 생각하기 때문입니다.
정확한 DAU는 아니지만 Analytics를 통해서 2주간의 유저를 측정해 보았습니다.
13일에 유저수가 가장 많았는데 12일 밤에 에브리타임에 핫게시물로 올라가서 그런 것 같습니다. 그러나 종강 이슈로 13일에 구매전환이 일어나지 않았습니다.
매출은 64만원 정도로 나왔는데 다 점주님께 드리고 마케팅 비용을 제외하면 마이너스입니다. 취소가 29건인 이유는 저희가 테스트를 위해 결제를 하고 취소한 것과, 주문 소리가 나지 않는것 때문에 점주님들이 주문을 오랫동안 승인을 하지 않아서 취소가 된 것이 이었습니다.
그 외
사실 이렇게 개발을 다 하고 나서 서비스를 시작하지 못 할뻔 했습니다. 서비스 시작
이 12월 4일
인데, 알림톡
전송을 위한 카카오톡 승인
이 12월 1일
에 되었습니다. 또 결제를 위한 카드사 승인
이 당일 10시
에 되었습니다. 이게 안됐다면 서비스를 시작하지 못했을 것입니다.
- 카카오톡 승인
- 카드사 승인
개발도 중요하지만 서비스를 시작하기 위한 준비도 중요하다는 것을 깨달았습니다.
마무리
무식하면 용감하다는 말이 있습니다. 이번 프로젝트만큼 잘 어울리는 말은 없었던 것 같습니다. 무식하게도 6주라는 짧은 기간에 실제 결제가 가능한 서비스를 만들었고, 용감하게도 서비스를 시작했습니다. 조금이라도 똑똑했더라면 이 서비스를 시작하지도 않았을 것입니다.
돌이켜 보면 엄청난 운이 따른 것 같습니다. 모든 과정에서 하나라도 잘못됐다면 서비스를 시작하지 못했을 것입니다. 그 중에서도 가장 큰 운이라고 생각하는 것은 좋은 팀원들을 만난 것입니다. 몸은 엄청 힘들었지만 팀원들과 함께 해서 개발하는 동안 정말 즐거웠습니다.
- 실제 서비스 화면