[7] 성능 최적화 - Redis(캐싱)
·
Project/Secondhand Market
1. Redis 캐싱 적용 전 (Before)시스템의 병목 지점을 파악하기 위해, 트래픽이 집중되는 '메인 페이지 상품 목록 조회' API에 대해 부하 테스트를 진행하였다.1.1. 부하 테스트 스크립트 (k6/load-test.js)k6를 사용하여 점진적으로 부하를 높이는(Ramp-up) 시나리오를 구성하였다. 동시 접속자(VUs) 100명이 지속적으로 요청을 보내는 Thundering Herd 상황을 시뮬레이션하였다.import http from 'k6/http';import { check, sleep } from 'k6';export const options = { // [부하 시나리오 설정] // 1. Ramp-up: 10초 동안 사용자(VU)를 0명에서 10명까지 늘림 // 2. ..
[6] 성능 최적화(4): Async 적용
·
Project/Secondhand Market
이번 포스팅에서는 외부 API 호출(SMS 발송)과 대용량 파일 처리(이미지 업로드) 시 발생하는 성능 병목을 비동기 처리(Async & CompletableFuture)를 통해 획기적으로 개선한 과정을 정리한다.1. 인증 코드 전송 (SMS)회원가입 시 휴대폰 인증 코드를 발송하는 기능이다. 기존에는 SMS 발송이 완료될 때까지 사용자가 계속 대기해야 하는 문제가 있었다.1.1. 동기 방식 (기존) 기존 코드는 AuthService에서 SMS 발송 메서드를 호출하면, 발송이 끝날 때까지 다음 줄로 넘어가지 않는 블로킹(Blocking) 방식이었다. 외부 SMS 서비스가 느려지거나 장애가 발생하면, 우리 서버의 회원가입 요청도 같이 느려지거나 타임아웃이 발생하는 위험이 존재했다. 변경 전 코드 (동기 처..
[5] 성능 최적화(3): N+1
·
Project/Secondhand Market
1. 상품 목록 조회 API (GET /items) 최적화 상품 목록 조회 API는 한 페이지당 20개의 상품 데이터를 반환하도록 구현되어 있다. API 호출 시 그라파나(Grafana)를 통해 쿼리 실행 내역을 모니터링한 결과, 단 한 번의 요청에 무려 21개의 쿼리가 발생하는 것을 확인했다.1.1. 원인 분석이러한 현상이 발생하는 원인은 ItemService의 getItemList() 메서드 로직에 있다.ItemRepository.searchItems(...)가 호출되면서 Item 엔티티 목록을 조회하는 쿼리 1회가 실행된다.조회된 엔티티들을 DTO로 변환하기 위해 .map(item -> ItemListResponse.fromEntity(...))가 실행된다.문제는 ItemListResponse.fr..
[4] 성능 최적화(2): Lock
·
Project/Secondhand Market
0. 들어가며 당근마켓을 벤치마킹한 프로젝트를 진행하며 기능 구현을 마쳤다. 하지만 "기능이 동작한다"는 것과 "안전하다"는 것은 별개의 문제다. 실제 운영 환경처럼 여러 사용자가 동시에 요청을 보낼 때, 데이터 정합성이 깨지는지 확인해 볼 필요가 있다. 무작정 락(Lock)을 적용하기보다, 어떤 상황에서 왜 문제가 발생하는지 테스트 코드로 직접 증명하고 분석해 본 과정을 기록한다.1. 문제 상황 인식현재 시스템에서 동시성 이슈가 발생할 것으로 예상되는 지점은 크게 3가지다.안심 지수 업데이트: 후기 작성 시 판매자의 점수를 계산하고 수정하는 과정.상품 좋아요 수 집계: 다수의 사용자가 동시에 '좋아요'를 누를 때 카운트 증가.선착순 나눔 신청: 한정된 재고를 두고 다수가 동시에 요청할 때의 재고 관리..
[3] 성능 최적화(1): 복합 Index & FullText Index
·
Project/Secondhand Market
1. 문제 인식: 기존 검색 시스템의 성능 한계중고 상품 플랫폼에서 다양한 조건으로 상품을 검색하는 기능은 핵심 서비스이지만, 데이터 양이 증가함에 따라 검색 속도가 크게 저하되는 현상이 발생하였다. 이는 사용자 경험을 저해하는 심각한 문제로 대두되었다.1.1. 성능 테스트 설계 (item-performance.http)다양한 검색 시나리오를 검증하기 위해 5가지 요청을 구성하였다:### 1. [검색] 데이터가 많은 뒷부분 검색 (Full Scan 시 느림, Index 적용 시 빠름)# 설명: 'Mock 상품 제목 90'으로 시작하는 데이터를 검색합니다. (LIKE 'Mock 상품 제목 90%')# 쿼리: title LIKE %...% (contains)GET http://localhost:8000/it..
[2] 프로젝트 모니터링 설정과 테스트 환경 구축
·
Project/Secondhand Market
1. Gradle 빌드 설정 (build.gradle)// [1] 플러그인 선언: Spring Boot 3.4.1 및 의존성 관리 플러그인plugins { id 'java' id 'org.springframework.boot' version '3.4.1' id 'io.spring.dependency-management' version '1.1.7'}// [2] 프로젝트 메타데이터group = 'com.example'version = '0.0.1-SNAPSHOT'description = 'spring-second-hand-engineering'// [3] Java 17 설정java { toolchain { languageVersion = JavaLanguageVersion..
[1] 프로젝트 소개
·
Project/Secondhand Market
[4] ngrok
·
Project/LinkFolio
1. ngrok이란?ngrok은 개인 PC와 같은 로컬 환경에서 실행 중인 웹 서버를 외부 인터넷에서 접속 할 수 있도록 안전한 터널(Tunnel)을 만들어주는 프로그램이다. 다음과 같은 상황에서 유용하게 사용할 수 있다.외부 서비스의 웹훅(WebHook)을 로컬 환경에서 테스트 할 때개발 중인 웹 사이트나 API를 다른 사람에게 임시로 공유할 때모바일 기기 등 다른 장치에서 로컬 PC의 서버로 접속하여 테스트 할 때2. ngrok 동작 원리ngrok의 마법은 ngrok 클라이언트(사용자 PC 프로그램)와 ngrok 클라우드 서버(외부 인터넷에 존재) 간의 협업을 통해 이루어진다.1단계: 터널 생성 (로컬 → ngrok 서버) 🚪사용자가 터미널에서 ngrok http 80과 같은 명령어를 실행하면, 사..