티스토리 뷰
3주간의 콘서트 예약시스템 프로젝트가 눈 깜짝할 사이에 지나가버렸다.
퇴근하고 와서 코딩하고, 같은 조원들과 리뷰하고, 주말에 수업 듣고 복습하고 했던 과정들이 쉽지는 않았지만
개발에 몰입할 수 있는 기회여서 즐거웠다. 매번 멘토링 때 열정적으로 도움을 많이 주신 허재 코치님께 감사의 인사를 전합니다.
1. 프로젝트 소개
내가 개발한 프로젝트는 콘서트 예약시스템이다. 많은 사람들이 동시에 접속하여 콘서트 티켓 예매를 가정한 시스템을 개발하는 것이다.
콘서트 일정 조회, 토큰 발급, 좌석 예약, 결제 처리에 이르는 모든 기능을 종합적으로 구현해야 하는 프로젝트이다. 대용량 트래픽을 견뎌야 하는 시스템이기 때문에 동시성 제어 등 고민이 필요한 기능들이 있었다. 대용량 트래픽을 견디고, 동시성을 제어하는 시스템을 개발한다는 점에서 매우 흥미로운 주제였다.
진행 기간
2024년 3월 30일 ~ 4월 20일
기술 스택
- SpringBoot 3.2.4
- swagger ui
- Mockito
- JUnit5
- Mysql 8.2.0
구현 기능
1️⃣ **주요 유저 대기열 토큰 기능**
- 서비스를 이용할 토큰을 발급받는 API를 작성합니다.
- 토큰은 유저의 UUID 와 해당 유저의 대기열을 관리할 수 있는 정보 ( 대기 순서 or 잔여 시간 등 ) 를 포함합니다.
- 이후 모든 API 는 위 토큰을 이용해 대기열 검증을 통과해야 이용 가능합니다.
기본적으로 클라이언트가 폴링으로 본인의 대기열을 확인한다고 가정하며, 다른 방안 또한 고려해보고 구현해 볼 수 있습니다.
2️⃣ 기본 예약 가능 날짜 / 좌석 API
- 예약가능한 날짜와 해당 날짜의 좌석을 조회하는 API 를 각각 작성합니다.
- 예약 가능한 날짜 목록을 조회할 수 있습니다.
- 날짜 정보를 입력받아 예약가능한 좌석정보를 조회할 수 있습니다.
좌석 정보는 1 ~ 50 까지의 좌석번호로 관리됩니다.
3️⃣ **주요 좌석 예약 요청 API**
- 날짜와 좌석 정보를 입력받아 좌석을 예약 처리하는 API 를 작성합니다.
- 좌석 예약과 동시에 해당 좌석은 그 유저에게 약 5분간 임시 배정됩니다. ( 시간은 정책에 따라 자율적으로 정의합니다. )
- 배정 시간 내에 결제가 완료되지 않았다면 좌석에 대한 임시 배정은 해제되어야 합니다.
- 배정 시간 내에는 다른 사용자는 예약할 수 없어야 합니다.
4️⃣ **기본** 잔액 충전 / 조회 API ( 대기열 토큰 검증 x )
- 결제에 사용될 금액을 API 를 통해 충전하는 API 를 작성합니다.
- 사용자 식별자 및 충전할 금액을 받아 잔액을 충전합니다.
- 사용자 식별자를 통해 해당 사용자의 잔액을 조회합니다.
5️⃣ **주요 결제 API**
- 결제 처리하고 결제 내역을 생성하는 API 를 작성합니다.
- 결제가 완료되면 해당 좌석의 소유권을 유저에게 배정하고 대기열 토큰을 만료시킵니다.
2. 프로젝트 진행과정
총 3주에 걸쳐서 요구사항분석 , 시퀀스 다이어그램 작성, ERD 설계, API 명세 생성, Mock API 생성, 개발, 통합테스트를 진행하였다.
2-1. 요구사항 분석, ERD 설계, 시퀀스 다이어그램 작성, Mock API (3월 30일 ~ 4월 5일)
이번 프로젝트는 동시성 제어, 좌석 임시배정, 대기열 구현 등 주요 기능들이 있었다. 그래서 초기 요구사항 분석이 매우 중요했다.
특히 DB로 대기열을 구현해야 하는 것이 이 프로젝트의 꽃이어서 어떻게 테이블을 설계하고, 기능을 구현할지 고민이 필요했다.
이번에는 깃헙에서 제공하는 프로젝트 기능을 사용하여 칸반보드처럼 해야할 일을 Todo 리스트로 만들고 하나씩 제거해 나가면서 진행했다. 하나씩 지워가는 재미가 있었다. 그리고 한 번에 하나의 issue들을 처리하면서 각 issue에 집중해서 개발할 수 있었다.
위와 같이 ERD 다이어그램을 그렸다. 주요 테이블은 토큰, 예약내역, 좌석 테이블이다. 이 테이블을 중심으로 결제내역이 생성되고, 사용자가 생성되고, 포인트 내역들이 생성된다. 중간에 허재 코치님이 피드백을 주셔서 콘서트-콘서트 스케쥴 - 좌석 테이블로 3개로 나눴다. 원래는 나는 좌석과 콘서트 테이블을 하나로 하여 Join을 최소화 하려고 했으나 성능과 확장성 이슈로 이 테이블들을 분리하였다.
이번 프로젝트에서 특징적인 부분 중 하나는 본격적으로 개발하기에 앞서서 Mock API를 개발한 것이었다.
그 이유는 우리는 혼자서 일하는게 아니라 프론트엔드 개발자와 협업을 한다. 그렇기 때문에 프론트 개발자들이 직접 API를 호출하면서
작업을 진행할 수 있도록 빠르게 Mock API를 만들어야 한다. 그래서 이번에는 Mock API 까지 만들고 본격적인 개발 준비를 마쳤다.
2-2. Swagger, API 명세, 단위 테스트 작성, 기본 API 개발 (4월 6일 ~ 12일)
Swagger 문서를 이용해서 API 명세를 먼저 만들었다.
총 8개의 API를 개발하게 되었다.
2주차에는 본격적인 개발을 시작했다. 단위테스트를 위한 테스트코드를 먼저 작성하고, 개발을 시작했다. 단위 테스트코드를 먼저 작성하니 어떤 방식으로 먼저 개발을 해야할지 눈에 쉽게 보여 개발하기에 용이했다. 하지만 테스트코드를 먼저 작성하고, 비즈니스 로직을 구현하면서 테스트를 반복하기 때문에 시간은 조금 더 오래 걸렸다. 테스트 자동화가 가능하고, 코드가 변경되었을 때 영향도를 바로 바로 파악할 수 있다는 점에서 테스트코드는 매우 중요하다.
2-3. 기본, 주요 API 개발/ 통합테스트코드 작성 / 회고록 작성 (4월 13일 ~ 19일)
모든 기능 개발을 완성하고 통합테스트 코드를 작성했다.
모든 테스트코드가 정상으로 끝났을 떄의 쾌감이란 ㅋㅋㅋㅋ
3. 프로젝트에서 얻은 점
1) 아키텍쳐 구조
원래는 아키텍쳐 구조의 중요성을 인지하지 못하고 있었다. 규모가 커질수록 아키텍쳐, 패키지 구조는 매우 중요하다.
왜냐하면 아키텍쳐 구조에 따라서 코드간 결합도가 달라지기 때문이다. 이번에 도입한 레이어드 아키텍쳐 + 클린아키텍쳐 구조로 진행했다.
UseCase 레이어를 도입한게 가장 큰 특징이었는데, 비즈니스 로직들을 부페식처럼 모두 개발을 해 놓은 다음 UseCase 프로그램에서 각 도메인별 비즈니스 로직을 필요에 따라서 가져다 사용하면 되는 구조였다. 그렇다보니 각 도메인끼리는 서로를 모르게 되고, 결합도가 낮아졌다. 즉 수정에 대한 영향도가 낮다.
2) 동시성 제어
동시성 제어의 방법이 여러가지가 있다. synchronized, ConcurrentHashMap, 낙관적 락, 비관적 락, 분산락 등. 각각의 장단점을 알고 상황에 맞는 동시성 제어 프로그래밍 방식을 선택할 수 있다는 것도 내가 얻은 큰 수확이다.
'항해플러스백엔드' 카테고리의 다른 글
[플러스백엔드] 5주간의 회고 (1) | 2024.04.20 |
---|---|
[6주차] 한상진 코치님 발제 : CI/CD 배포 파이프라인 구축 (1) | 2024.04.20 |
[플러스백엔드] 4주차 회고 (0) | 2024.04.13 |
[5주차] 하헌우 코치님 발제 - Logging 과 Exception (0) | 2024.04.13 |
[플러스백엔드] 지난 3주간의 회고 (1) | 2024.04.06 |
- Total
- Today
- Yesterday
- 항해플러스후기
- 2023년
- pop_back
- Use case
- 열반스쿨기초반
- 파라메터
- resize
- 항해플러스백엔드
- front
- Inception
- 유즈케이스
- GIT
- 개발자 회고
- github
- 항해솔직후기
- 내년은 빡세게!!
- 인셉션
- ```````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
- 깃허브
- 월부닷컴
- 부동산공부
- Spring boot
- 폭포수
- 재테크공부
- 관계대수
- 도커
- docker
- 월급쟁이부자들
- 깃
- push_back
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |