전체 글

전체 글

    nGrinder와 Pinpoint로 성능테스트 및 개선하기 (5) - 캐싱

    1. 성능 개선 방법이전 포스팅에서 nGrinder를 통한 성능테스트 및 개선을 수행했다. 계속 진행한 테스트 시나리오를 보면 다음과 같은 플로우로 요청을 하는데 팀목록이나 경기 목록, 경기 정보와 같은 조회 API는 한번 DB에 등록이 되면 변하지 않는다. 따라서 변하지 않는 데이터에 한해서 캐시를 적용해 성능 최적화를 해보려고 한다.1. 로그인2. 팀 목록 3. 경기 목록4. 경기 정보 5. 좌석 등급 목록6. 좌석 등급 정보 7. 예약 좌석 목록8. 좌석 선택9. 예매2. 캐시(Cache)먼저 캐시와 캐싱전략을 알아보자.2.1 캐시(Cache)캐시는 한번 조회된 데이터를 미리 특정 공간에 저장해놓고, 똑같은 요청이 발생하면 서버에게 다시 요청하지 않고 저장해높은 데이터를 가져와 빠르게 데이터를 제공..

    nGrinder와 Pinpoint로 성능테스트 및 개선하기 (4) - Scale out

    1. 성능 개선 방법이전 포스팅에서 문제점을 파악했고, 다음과 같은 방법으로 성능을 개선하기로 했다. Scale out를 적용해 TPS를 높여보겠다. connection pool 크기 확장하기scale out을 통해 트래픽을 분산해 TPS 올리기2. Scale-out2.1 Scale-out vs Scale-upScale-up은 기존 서버나 시스템에 추가 자원을 투입해 성능을 향상시키는 방법이다. 장점은 비교적 빠르게 성능을 향상 시킬 수 있으나 하드웨어의 업그레이드에 비용이 많이 들고 성능 향상이 제한적이라는 단점이 존재한다. Scale-out은 여러 대의 서버를 추가해 시스템의 성능과 용량을 확장하는 방법이다. 분산 시스템을 통해 여러 서버가 협력해 작업을 처리한다. 따라서 높은 확장성을 제공한다는 장..

    nGrinder와 Pinpoint로 성능테스트 및 개선하기 (3) - Connection Pool 크기 조절

    1. 성능 개선 방법이전 포스팅에서 문제점을 파악해 다음과 같은 방법으로 성능을 개선하기로 했다. 그리고 이 포스팅에서 Connection Pool의 크기를 조절해 성능을 개선해보겠다.connection pool 크기 조절 하기scale out을 통해 트래픽을 분산해 TPS 올리기2. Connection Pool먼저 병목이 발생한 getConnection()이 무엇인지 알아보자. getConnection()은 자바 프로그램과 데이터베이스를 네트워크 상에서 연결해주는 메소드이다. 연결에 성공하면 DB와의 연결 상태를 Connection 객체로 표현해 반환한다. 데이터베이스 커넥션을 획득할 때는 다음과 같은 과정을 거친다.어플리케이션 로직은 DB 드라이버를 통해 커넥션을 조회한다.DB 드라이버는 DB와 TC..

    nGrinder와 Pinpoint로 성능테스트 및 개선하기 (2) - 병목지점 파악

    1. nGrinder로 성능테스트1.1 테스트 시나리오 작성KBO-Ticketing이 예매 서비스인 만큼 ‘좌석 예매’에 집중하기로 하였으므로 다음과 같이 시나리오를 만들었다.1. 로그인2. 팀 목록 3. 경기 목록4. 경기 정보 5. 좌석 등급 목록6. 좌석 등급 정보 7. 예약 좌석 목록8. 좌석 선택9. 예매import static net.grinder.script.Grinder.grinderimport static org.junit.Assert.*import static org.hamcrest.Matchers.*import net.grinder.script.GTestimport net.grinder.script.Grinderimport net.grinder.scriptengine.groovy.ju..

    nGrinder와 Pinpoint로 성능테스트 및 개선하기 (1) - 환경 구축

    프로젝트 API를 완성했고, 내가 만든 API가 잘 작동하는지 확인해보고자 한다. nGrinder를 통해서 성능테스트를 수행하고, Pinpoint가 제공하는 병목점을 찾아 개선점을 찾기로 했다. 정확한 성능테스트 및 모니터링을 위해 NCP에서 성능테스트용 서버(centOs 7)를 하나 만들었다. 1. nGrinder네이버에서 제공하는 서버 부하 테스트 오픈 소스 프로젝트이다. 가상 시나리오를 만들어 트래픽이 몰렸을 때 성능을 측정할 수 있도록 도와준다.controller : Web UI를 제공하고 테스트를 구성할 수 있도록 하며 모니터링 하거나 보고서를 시각화Agent : 부하를 발생시키는 역할로 process와 Thread를 이용해 가상 사용자를 생성Target Server : 테스트하고자 하는 서버 ..

    Redis Lua Script 실제로 Atomic할까?

    배경 이전 글에서 Redis 의 Lua Script를 활용해 좌석 선택 기능을 Atomic하게 만들었다. 만들고 나기 의문이 들었다. 내가 만든 기능이 실제로 Atomic한가? 따라서 Atomic한지 테스트해보려고한다. 내가 테스트 하려고 하는 방법은 다음과 같다. ‘읽기 - 쓰기’의 작업 전/후에 로그를 넣어서 같은 좌석을 동시에 다수의 유저가 요청할때 한명만 좌석을 선점하며 동시에 로그가 차례대로 찍히는지 확인할 것이다. 테스트 및 결과 그 전에 Atomic 하게 구현되어 있지 않았을 때 코드를 먼저 테스트해보자. public void selectSeats(SeatDto seatDto, int userId) { String redisKey = String.format("%d_%d_%d", seatDt..

    Redis Lua Script 와 synchronized 간의 성능 비교 테스트 (+ 수정)

    (+2024.06.14  성능 비교 테스트 코드가 잘못된 부분이 있어 수정했습니다. )배경 및 문제점현재 진행하고있는 KBO-ticketing은 야구 예매 서비스이다. 따라서 다음과 같은 기능이 존재한다.좌석을 선택한다. 선택한 좌석은 7분 동안 ‘내 좌석’으로 타인이 선택할 수 없다.좌석을 예매한다.위의 기능을 2개의 API로 나누어서 구현했고, ‘좌석 선택 API’의 flow는 다음과 같다.Redis에 저장된 key를 확인해 좌석이 ‘선택’된 좌석인지 확인하고, redis Key가 존재하면 좌석 선택 불가, redis Key가 존재하지않으면 Redis에 key-value를 저장한다. 이때 value에는 user의 id를 저장한다.@Service@RequiredArgsConstructorpublic c..

    mockito 테스트 시 파라미터에 무엇을 넣어야할까?

    배경 @RestController @RequiredArgsConstructor public class ScheduleController { private final ScheduleService scheduleService; @GetMapping("schedules") public ResponseEntity getSchedules( ScheduleQueryParamDto scheduleQueryParamDto) { ArrayList schedules = scheduleService.getSchedules(scheduleQueryParamDto); return ResponseEntity.ok(CommonResponse.ok(schedules)); } } 다음과 같은 controller 가 있을때 contro..