[WIL] 항해99 10주차 - 실전프로젝트(2)

Doyeon·2023년 3월 26일
0
post-thumbnail
post-custom-banner

실전프로젝트를 시작한지 2주일이 지났고 중간발표 시간을 가졌다.
남은 4주동안 해결해야 할 문제들과 공부해야할 것들이 산더미지만, 할 일이 있다는 것에 감사하며…
이번 WIL에는 중간발표 자료와 피드백 내용을 정리해본다.


중간발표

프로젝트 소개

프로젝트 명 : ParkNav

주차장을 찾아가는 네비게이션과 같이 쉽게 주차장을 조회하고 예약할 수 있는 서비스

  • 전국에 있는 주차장을 검색하고 주차장의 정보를 확인할 수 있습니다.
  • 주차장을 선택하여 주차 예약을 할 수 있습니다.
  • 주차장의 입차, 출차 현황을 관리할 수 있습니다.

주요 기능

☑️ 주차장 검색

  • 장소 검색 기능 제공(주소, 키워드 검색)
  • 사용자 위치 기반 검색 기능 제공
  • 카테고리 필터 조회 기능(주차 시간 당 요금, 주차장 유형 검색)

☑️ 주차 예약 시스템

  • 선택한 주차장의 현재 주차 가능 대수, 예약하고자 하는 시간의 예약 건수, 예상 주차요금 확인
  • 날짜, 시간 선택하여 주차 예약 가능
  • 나의 예약 현황 조회 가능
  • 주차 예약 취소 가능

☑️ 차량 등록

  • 차량등록 및 대표차량 설정 가능

☑️ 주차장 현황 관리

  • 입차, 출차 현황 조회 가능
  • 출차 시 주차요금 확인

활용 데이터

  • 주차장 정보 - 공공 데이터 포털 제공(1.4만여건 DB 저장 완료) + 카카오맵 크롤링(8만여건 수집중)
  • 주차 예약 정보 - 75만건 생성 완료
  • 주차 현황 정보 - 135만건 생성 완료
  • 주차장 정보 dummy 데이터 생성 + 예약, 현황 정보 추가 생성 계획

프로젝트 시연

https://youtu.be/cWK6YQGPLxI


아키텍처

기술스택

Back-EndSpring Framework (Spring Boot, Spring MVC, Spring Data JPA, Spring Security), Docker, Java17, elastic search, junit5
DatabaseMySQL, H2, redis
Front-EndHTML5, CSS3, JavaScript, Bootstrap, Axios, thymeleaf
ToolGit, Github, Github Actions, IntelliJ IDEA, jmeter, pinpoint
API카카오 Map API
serverEC2, RDS

구조도


기술적 의사결정

CI/CD 파이프라인 구축

  • 도입 이유

    • 프로젝트 개발 및 배포과정을 자동화하여 개발 생산성을 향상시키고, 인프라 관리 비용 및 시간을 절감할 수 있음
  • 문제 상황

    • 현재 수동적인 빌드, 배포, 테스트 과정으로 인한 생산성 저하와 버전 관리 및 협업과정에서 발생하는 인적 오류가 존재함
    • 빠른 배포를 위한 빌드와 배포의 자동화 부재로 배포 지연 및 품질 저하 발생 가능성이 높음
  • 해결 방안

    • 1안) Github Actions + Docker
    • 2안) Jenkins + Docker
  • 의견 조율

    • CI/CD 파이프라인 구성에 필요한 도구와 기술 선정 및 검토
      • 무료이거나 비용이 저렴해야 한다.
      • 짧은 기간에 사용해야하기 때문에 러닝커브가 낮아야 한다.
  • 의견결정

    • AWS EC2, Docker, GitHub Actions, Docker Hub을 사용하여 CI/CD 파이프라인 구성
    • 프로젝트 내에서 CI/CD 파이프라인 구성 및 관리를 담당할 담당자 선정
    • 도커 이미지 관리 및 배포를 위해 Docker Hub 계정 생성 및 연동

대용량 트래픽 테스트

  • 도입 이유

    • 주차장 시스템은 대규모 데이터를 처리해야 하므로, 이를 위한 적절한 테스트 도구를 도입해야 함
    • 테스트 도구를 이용하여 시스템의 성능을 측정하고 문제를 해결하며 안정적인 서비스를 제공하기 위함
  • 문제 상황

    • 주차장 시스템에서는 동시 접속자가 많아 대규모 데이터를 처리할때 예약과 입차, 출차가 중복되거나 입력이 되지 않는 현상이 있어 트래픽 테스트를 통해 성능을 개선해야 함
  • 해결 방안

    • 대용량 트래픽을 처리할 수 있는 도구로 Apache JMeter, Gatling, Locust 등의 도구들을 비교 분석하여 적절한 도구를 선택해야 함
  • 의견 조율

    • JMeter는 대용량 트래픽을 처리하는 데 최적화되어 있으며, 다양한 프로토콜과 기술을 지원하며, 사용이 간편하고 확장성이 높다는 장점이 있음
    • Gatling은 스칼라 언어로 작성해야 하고 GUI 환경이 없어 사용이 어려울 수 있음
    • Locust는 파이썬 언어로 작성하며 Http 프로토콜만 지원함
  • 의견 결정

    • JMeter는 오픈소스 점유율이 가장 높으며 대규모 트래픽을 처리하고 분석하기 위한 기능이 우수하고, GUI로 사용이 쉽다는 장점이 있어서 JMeter로 결정

지도 검색 API 사용

  • 도입 이유

    • 주차장 정보 크롤링을 하거나, 주차장을 검색 조회할 때, 장소 검색 키워드에 해당하는 주소의 위도, 경도 정보가 필요함
    • 위도, 경도 정보를 바탕으로 지도에 위치를 표시할 수 있음
  • 문제 상황

    • 사용자가 검색할 경우 일반적으로 동 명칭, 지역명, 특정 건물 등 키워드로 검색하는 경우가 많음
    • 주소 또는 키워드로 검색하는 장소의 위도, 경도 정보를 구해야 함
  • 해결 방안

    • 1안) Geopy
    • 2안) Naver Map API
    • 3안) Kakao Map API
  • 의견 조율

    • Geopy와 네이버지도 API는 주소에 대한 검색만 지원함
    • 카카오맵 API는 동 명칭, 지역명, 특정 건물 등 모든 일반적인 검색에 대한 결과를 지원함
  • 의견 결정

    • 주소 또는 키워드로 검색하는 장소의 위도, 경도 정보를 구할 수 있는 카카오맵 API를 선택하여 주차장 검색시 사용함

추후 개발 및 기술적인 도전 계획

최종 완성본 아키텍쳐 구상도

기능 및 성능 개선

  • 예약 알고리즘 정합성 높이기
    • 현재 알고리즘
    • 개선 알고리즘
    • 예약한 차량이 안정적으로 입차할 수 있도록 다양한 케이스 작성 및 테스트
    • 주차장별, 시간대별 예약 가능 대수를 정하고, 예약 신청시 시간대별 예약차량 수, 예약 가능 자리 수를 보여주도록 구현
    • 운영 가능 구획 효율성을 높일 수 있는 방안 모색
  • 주차장 검색 로직 최적화
    • 현재 로직
    • 키워드 검색 시, DB에 저장된 주차장 데이터 중 키워드와 일치하는 데이터가 있다면 해당 결과의 좌표를 반환하는 로직 추가
    • 현재 검색 로직에서 유사한 검색 결과가 여러 개 나오는 경우 어떤 장소를 보여줄 것인가에 대한 로직 추가
  • 입차, 출차, 예약 시 동시성제어 적용
    • Locking
      • Optimistic Locking : 데이터에 version정보를 포함시켜 비교했을시 만약 다른 트랜잭션이 해당 데이터를 업데이트 하여 버전이 변경됐을 경우 수정 불가능. 동시 접속인 경우 lock 충돌 발생 가능
      • Pessimistic Locking : 데이터를 읽을때 해당 데이터를 다른 트랜잭션이 수정하지 못하도록 락을 걸어 놓고, 해당 트랜잭션의 모든 작업이 끝날경우 락 해제. 대용량 트래픽일 경우 성능 저하 발생 가능
    • Synchronized
      • 동일한 차량번호로 동시에 요청이 들어오는 경우는 거의 없으므로 Synchronized 처리는 하지 않기로 결정
    • Redis
      • Lettuce
        • 사용이 간단하고, 높은 성능과 안정성을 보장합니다.
        • 비동기 작업을 지원하기 때문에 I/O 대기 시간을 최소화하고 성능을 극대화할 수 있습니다.
      • Redisson
        • ettuce보다 다양한 동시성 제어 기능을 제공합니다.
        • 객체 락(lock)과 관련된 다양한 기능을 제공하여 복잡한 구현을 간단하게 처리할 수 있습니다.
      • 위 두개의 라이브러리를 활용해서 동시성 제어를 할 예정이지만, 비동기 방식을 이용하여 성능적인 면이 좋고, 사용이 간편한 Lettuce를 최종적으로 적용 할 것같습니다.
      • 위의 동시성 제어 기법들뿐 아니라 추가적으로 공부 후 테스트 해볼 예정입니다.
  • 나의 예약 조회, 주차 관리 현황 검색 기능 구현 및 성능 향상
    • 날짜, 주차장 유형, 주차장 이름, 사용여부 등 다양한 필터를 적용하여 원하는 결과를 보여주도록 기능 구현
    • QueryDSL을 이용한 쿼리 최적화
    • B-TREE index, full-text index 적용
    • Elasticsearch & Redis Cache를 통한 검색 시간 단축
  • 테스트 코드 작성
    • 주차 예약, 입차, 출차 등 로직을 수행할 때 작성한 코드가 의도한대로 작동하는지 검증
  • Ngnix 무중단 배포
    • 새 버전이 merge 되었을때 이전 버전이 중단되고 다음 버전이 실행되는 중간 배포가 중단되는 상황
    • 또한, v1이 배포된 상황에 v2를 dev에 PR 날렸으나, 이상이 있다면 v1으로 대체시킬수도 있는 장점
    • https 적용

피드백 정리

  1. 주차 예약로직 앞으로 개선할때 예약 대수를 구하는 로직 및 어떤 방식으로 데이터를 관리할 것인가요?

    • 피드백 : 1~2시 예약 가득 찼을때 사용자가 조금 더 편하게 서비스를 이용하려면 시간대별 예약 카운트가 노출되면 좋을거 같습니다. 하지만 데이터를 만들어내는 과정의 쿼리가 복잡할 수 있고, 이럴때 효율적인 데이터 제공에 대한 고민이 필요, 시간대별로 데이터를 갖고있다면 편할거 같습니다.

    → 프론트 예약화면에 시간대별 예약 카운트 노출시키기, 화면 구상 필요

    → 예약 카운트 구하는 쿼리 만들기

    → 시간대별 데이터를 가질 수 있는 방법 찾아보기

  2. 동시성 제어시 왜 이러한 락킹 방법을 사용했는지 고민해 봤으면 좋겠습니다.

    → 현재 Pessimistic Locking, Redis 스핀락 적용해본 결과 Peesimistic Locking 속도가 더 빠름. 그 이유 찾아볼 것

  3. jmeter가 아닌 테스트 코드에서 동시성 제어에 관한 내용이 나왔으면 좋겠습니다.

    → 테스트코드에서 쓰레드를 동시에 열어서 보낼 수 있음. 입차 부분 findAllByParkInfoId 테스트 시도함

    → 테스트코드에서 어떻게 동시성 제어 부분 테스트를 구현할 수 있을지 찾아볼 것

  4. redis에 어떤 데이터를 담아두고 캐시를 쓸 수 있을까 고민해 봤으면 좋겠습니다.

    → 차량 예약이 일어날 때 잔여 차량 수(예약 가능 수)

    → 또 캐시에 담을 수 있는 데이터 무엇이 있는지

  5. 주차장 검색에 대해 쿼리 dsl로 쿼리 최적화 한다고 했는데 검색할때 다양한 필터가 있는데 성능 향상을 위해서 어떻게 index를 만들지 고민해보고 구체화했으면 합니다.

    → index 어떻게 만들지 방법 찾기

  6. 일반차량 예약과 예약차량 50:50으로 나누면 100프로 효율이 안나오니, 이걸 100프로 효율을 낼 수 있도록 알고리즘을 수정해보면 좋을것 같습니다.

    → 주차 예약 알고리즘별 브랜치 푸시

    → 주차장 운영 공간 효율성, 안정적인 입차, 안정적인 예약 확인할 수 있는 지표, 테스트 시나리오 작성하기

    → 표로 한눈에 효율성과 안정성을 확인할 수 있도록 표를 잘 구성해보기

profile
🔥
post-custom-banner

0개의 댓글