Skip to content

1차: 요구사항 개발

Park minji edited this page Sep 4, 2024 · 24 revisions

🛠️ 개발 주요 사항

🔺 재고 수량 관리 시 동시성 문제 해결

  • 발생 지점: 티켓 구매 시 현재 재고 확인 후 재고 감소하는 로직에서 발생
  • 원인: 현재 재고보다 더 많은 스레드가 재고 확인 시 재고가 존재함을 확인하고, 동시에 재고를 차감하는 과정에서 실제 재고보다 더 많은 구매가 이루어질 수 있음
    • Check-And-Act 패턴 사용
  • 해결: 선착순이어야 하고 동시 요청이 많은 기능이므로, 티켓 재고 확인 시 MySQL의 SELECT FOR UPDATE 사용
    • 낙관적 락은 선착순이 보장되지 않으며, 동시 요청에서 재시도 부하가 추가로 발생하므로 사용하지 않음
  • 검증: 동시성 문제가 재발한 경우 바로 확인 가능하도록, 자바 스레드 기반 동시성 테스트를 작성하여 자동으로 검증

⚡ 쿼리 최적화

  • 불필요한 DB I/O 감소를 위해 JPA 사용 시, 필요 없는 열까지 가져오는 쿼리를 필요한 열만 가져오도록 수정
  • 의미 없는 쿼리 실행 방지를 위해, JPA 연관 관계 엔티티의 글로벌 로딩 전략을 Lazy로 변경
  • 쿼리 성능 개선을 위해 기존 데이터베이스 스키마에서 누락된 논리적 FK 인덱싱 추가

🗄️ 캐싱

  • 캐싱할 API 파악:

    • 최근 개최될 페스티벌 목록 조회 API
      • 웹사이트의 첫 화면에서 사용되므로 자주 호출되며, 실시간으로 변경될 필요 없음
    • 티켓팅이 진행될 페스티벌의 상세 조회 API
      • 이미 공개된 페스티벌의 상세 정보는 자주 변경되지 않으며, 티켓팅 진행 시 트래픽 급증 가능성 있음
  • 캐시 전략:

    • 1시간마다 만료, 최대 사이즈 10000인 캐시로 관리

🔧 설정값 수정

  • 부하 테스트 결과에 따라 성능에 영향을 미치는 설정값을 수정
  • 수정한 설정값 목록:
    • 히카리풀 최소, 최대 커넥션 수
    • 톰캣 최소, 최대 스레드 개수
    • 톰캣 Backing Queue 용량
      • Backing Queue: 스레드가 모두 사용 중일 때 요청을 대기시키는 대기열

🚀 성능 테스트

테스트 계획 수립

  • 동시 접속자 수: 3000명, 5000명, 7000명
  • 시나리오: 동시 접속자들이 다음 순서대로 API 요청
    1. 티켓 구매 권한 획득
    2. 티켓 구매 미리보기 조회
    3. 티켓 구매
    • 참고: API 요청 실패 시 다음 API를 요청하지 않음
  • 검증: 상태 코드가 200인지 여부, 티켓 구매 성공한 요청 수와 MySQL 티켓 구매 수 일치 여부
  • 핵심 지표: 각 API 응답 시간

결과 분석

Screenshot 2024-09-04 at 1 32 37 PM
  • 티켓 구매 미리보기 조회, 티켓 구매 권한 획득, 티켓 구매 순으로 API 응답 시간이 짧음
    • 티켓 구매 미리보기 조회 API의 응답 시간이 긴 이유는 티켓 구매 권한 획득 API의 응답 시간이 길기 때문일 수 있음
      • Tomcat이 현재 처리할 수 없는 요청은 accept queuebacking queue에 저장되는데, 큐에 저장된 요청은 처리 진행 중인 요청이 끝나야 처리되므로 처리 중인 요청의 처리 시간만큼 딜레이가 발생함
    • 티켓 구매 권한 획득 API 응답 시간이 긴 이유는, 티켓 재고 수 차감 시 사용하는 비관적 락에서 병목이 발생하기 때문

결론

티켓 구매 권한 획득 시 티켓 재고 수 차감 로직의 락 병목 해결 필요