- 경매 프로젝트의 주요 API의 성능 테스트 목표는 상품 검색API의 목표 TPS는 500TPS로 설정하였습니다. 입찰 조회 API 목표 TPS는 160TPS로 설정하였습니다.
TPS 산정과정
웹사이트의 TPS는 트래픽 패턴과 이벤트에 따라 변동되지만, 일반적으로 10에서 50 TPS가 발생하고 피크 시에는 최대 250 TPS까지 증가할 것으로 예상했습니다. 여유를 두기 위해 최대 500 TPS까지를 목표로 설정했으며, 상품 검색 API의 경우 피크 시간대에 분당 약 300회의 요청과 약 100명의 동시 사용자를 기준으로 산정했습니다. 이러한 예측을 바탕으로 부하 테스트를 진행해 시스템이 최대 500 TPS까지 안정적으로 처리할 수 있도록 최적화했습니다.
- 경매 프로젝트의 주요 API의 성능 테스트 목표는 상품 검색API의 목표 TPS는 500TPS로 설정하였습니다. 입찰 조회 API 목표 TPS는 160TPS로 설정하였습니다.
- 성능 테스트에는 Locust를 선택했습니다. 이는 Community Server Toy 프로젝트에서의 경험을 토대로 선정되었습니다. Locust를 선택한 이유는 그래프를 통해 정확한 병목 지점을 파악할 수 있기 때문입니다.
우선적으로, 대상 API에 대한 성능 테스트 계획서를 작성해야 합니다.
Auction server의 성능테스트 목표는 배경 설명에 따라, 약 10만 명의 사용자가 해당 경매 사이트를 이용할 것으로 예상되며, 이 중 상품 검색API는 분당 약 300회, 동시사용자는 100명으로 예상하였습니다. 이를 고려하여 해당 API의 목표 TPS는 500TPS로 설정하였습니다. 입찰 조회API는 분당 약 100회, 동시사용자는 100명으로 예상하였으며, 목표 TPS는 160TPS로 설정하였습니다.
성능 테스트를 라이브 환경과 비슷한 조건에서 수행하는 것은 중요합니다. 이는 성능 테스트가 개발 환경에서만 수행될 경우에는 실제 운영 환경에서 발생할 수 있는 문제를 미리 식별하지 못할 수 있기 때문입니다. 예를 들어, 라이브 환경에서 사용되는 데이터베이스 인덱스에 대한 성능 테스트를 생각해보면, 개발 환경에서는 일반적으로 데이터가 적어서 인덱스의 처리 능력을 정확하게 측정하기 어렵습니다. 이를 고려하여 총 10만개의 상품과 경매 내역, 30명의 사용자, 그리고 50개의 카테고리를 Faker 라이브러리를 사용하여 DB 값으로 구성했습니다. 사용자는 입찰 API의 성능 테스트 대상으로 분당 약 최대 30명이 사용할 것으로 예상되었습니다. 또한, 카테고리는 AUCTION 사이트의 중고장터를 참고하여 50개로 구성하였습니다.
해당 데이터를 수작업으로 입력하는 것은 번거롭기 때문에 이를 자동화하기 위해 데이터를 생성하는 컨트롤러를 구성했습니다.
// 사용자 ID 생성
String userId = faker.name().username();
// 카테고리 이름 생성
String department = faker.commerce().department();
// 상품명 생성
String generatedProductName = faker.commerce().productName();
// 생성된 판매 ID
Long generatedSaleId = Double.valueOf(Math.random() * 30 + 1).longValue();
// 시작 가격 생성
int generatedStartPrice = faker.number().numberBetween(1000, 100000);
위의 코드는 JAVA에서 주요 사용했던 Faker 메서드 입니다.
위 코드에서 중복되지 않는 사용자의 ID(User의 ID)와 카테고리 이름을 생성하기 위해 HashSet을 사용하여 중복을 피하며 등록하였습니다.
성능테스트를 위한 DB값을 구성하였으니 각 대상 API에 대한 Python 스크립트를 구성하였습니다.
(자세한 코드는 Git를 참고해주세요.)
이 또한 Python의 Faker 라이브러리를 활용하여 실제 검색과 유사한 데이터를 생성하도록 구현했습니다.
이제 준비를 마쳐 성능테스트를 진행하여 TPS을 확인하였습니다.
Locust 파일의 위치에서 CMD(or Powershell)을 실행하여 python 스크립트를 실행하였습니다.
// Locust 실행 명령어
locust -f [Python 스크립트 파일]
실행 후 http://localhost:8089/# Locust UI에 목표에 해당하는 값을 넣어 테스트를 진행하였습니다.
먼저, 검색 성능을 성능테스트 하였습니다. 시나리오는 100명의 동시 사용자가 초당 100번을 호출하여 분당(5분) 사용자를 100씩 늘려가는 STRESS 테스트를 진행하였습니다.
시나리오에 따라, 5분 동안 최대 500명의 동시 사용자를 시뮬레이션하고자 합니다. 그리고 분당 동시 사용자가 100씩 증가하는데, 이를 초당 증가율로 환산하여 계산하면 100을 60으로 나눈 값이 소수점으로 나누어 떨어지지 않으므로, 올림하여 2로 설정했습니다.
[그림 2]의 Total Requests per Second을 확인한결과 TPS는 평균 57TPS 목표로 하는 500TPS에 도달하지 못했습니다.
입찰 조회 API의 성능테스트도 진행하였습니다.
입찰 조회API의 성능테스트 결과는 평균 TPS는 약 180으로 목표 TPS는 도달하였지만, Response Time을 확인한 결과 병목 지점을 확인했습니다. 이 병목 지점은 스트레스 테스트 도중 발생했으며, 요청 수가 증가할수록 응답 시간이 증가하는 현상을 통해 병목 현상이 발생한 것으로 판단했습니다. 이를 리펙토링하고자 합니다.
목표 TPS를 달성하기 위한 리펙토링 과정에는 쿼리 리펙토링, DB 리펙토링, 코드 리펙토링 등이 포함됩니다. 그 중에서도 검색엔진인 Elasticsearch을 도입하여 DB의 부하를 줄이고, 쿼리 실행 속도를 향상시키는 데이터의 색인화, 분산 아키텍처, 검색 엔진의 최적화, 그리고 실시간 검색을 지원으로 인해 우선적으로 리펙토링하고자 합니다. 또한, 입찰 조회 API도 Elasticsearch를 활용하여 성능을 개선한 후 추가적인 리펙토링을 진행할 계획입니다. 이러한 리펙토링 작업 이후에는 내구성 테스트를 수행하여 시스템의 안정성을 확인할 예정입니다.
경매 서버 성능 최적화: 경매 서버의 Elasticsearch 도입 을 참고 해주세요
참고
Auction server 성능테스트 계획서 | Notion
개요
lean-pen-0eb.notion.site
'Toy Project > Auction-Server' 카테고리의 다른 글
Auction-Server에 Docker 적용하기: 개발과 배포의 효율적인 관리 (0) | 2024.03.11 |
---|---|
경매 서버 성능 최적화: 경매 서버의 Elasticsearch 도입 (0) | 2024.01.08 |
RabbitMQ와 Spring Boot로 구현하는 Auction Server (0) | 2023.11.22 |
Auction 서버 프로젝트 JPA 적용하기 (0) | 2023.09.18 |