게틀링(Gatling) 사용해서 성능 수치화하기

한샘·2026년 3월 19일
post-thumbnail

나: n+1 문제를 해결해서 성능을 올렸습니다!
면접관: 얼마나요?
나: 엄... 그건 잘...
면접관: 수치화 안했어요?
나: 네......

프로젝트를 진행하다가..

DMS(Dorimtory Management System) 프로젝트를 개발하다가
모범학생 투표 기능에서 투표에서 제외된 학생을 가져오는 로직에서 쿼리가 오래걸리는 문제가 생겼다. 알고보니 학생을 가져오는 로직에서 room 이라는 하위 엔티티를 가져올 때 N+1 문제가 발생하는 것이었다.
그래서 나는 @EntityGraph(attributePaths = {"room"}) 을 이용하여 원래는 학생을 조회하면 room이라는 하위 엔티티를 가져오는 과정에서 발생하는 N+1 문제를 해결했다.

선배의 말씀

선배: 한샘아 그래서 얼마나 좋아졌는데?
나: 많이...?
선배: 수치화 해야겠지?
나: 그게 뭐죠?

수치화의 중요성

수치화를 해야 before와 after의 차이를 명확하게 알 수 있고, 내가 한 작업이 얼마나 성능을 올려주었는지 확인하는 것은 매우 중요하기 때문에 수치화를 하는 것은 개발자에게 있어서 매우 중요하다.

그럼 게틀링(Gatling)이 뭔데?

게틀링이란 코드(Scala/Java/Kotlin)로 작성하는 고성능 오픈소스 부하 테스트 도구이다.

  • 비동기 처리 방식을 사용해 적은 사양의 컴퓨터로도 수만 명의 가상 유저를 만들 수 있다.
  • GUI를 이용하는 것이 아니라 코드를 이용해서 시나리오를 짜기 때문에 git으로 관리가 편하다.
  • 테스트가 끝나면 이쁜 html 리포트를 생성해준다.

게틀링(Gatling)을 이용해서 성능 테스트하기

게틀링 사용법

public class BasicSimulation extends Simulation {

    HttpProtocolBuilder httpProtocol = http
    	// 모든 요청의 기본이 되는 공통 주소 (Host)
        .baseUrl("http://localhost:8080") 
        
        // 모든 요청에 포함될 공통 헤더
        .header("Content-Type", "application/json") 
       
        // 공통 인증 토큰
        .header("Authorization", "Bearer token"); 
        
	// 테스트 시나리오의 이름 (보고서 식별용)
    ScenarioBuilder scenario = scenario("get excluded-student") 
        .exec(
        	// 개별 HTTP 요청의 이름 (보고서에 통계로 찍힘)
            http("get-excluded-student-request")
            
            	// 상세 경로 (baseUrl 뒤에 붙음)
                .get("/votes/excluded-student")
                
                // 응답 상태 코드가 200(성공)인지 검증
                .check(status().is(200)) 
        );

    {
        setUp(
            scenario.injectOpen(
                // atOnceUsers(100)  // 100명의 사용자가 동시에 요청
                // rampUsers(100).during(10) // 10초 동안 100명의 사용자가 순차적으로 요청
                // constantUsersPerSec(10).during(30) // 초당 요청 수(TPS 10)을 유지하면서 30초동안 요청
                
            )
        ).protocols(httpProtocol);
    }
}

위 코드에서 setUp 부분에서 요청을 보내는 방식은 개발자가 선택하면 된다.

Docker 사용

여기서 중요한 점은 서버와 비슷한 환경에서 테스트를 해야한다는 점이다. 자신의 컴퓨터가 양자컴퓨터 뺨치면 N+1이든 N^2+1이든 상관이 없기 때문이다.
그렇기 테스트는 Docker라는 독립적인 환경에서 테스트를 진행하였다.

deploy:
  resources:
    limits:
      cpus: '2'    # OS가 일할 최소한의 통로 확보
      memory: 4G   # OS 메모리 영역 침범 방지

이런식으로 docker-compose.yml 에서 docker 에서 cpu와 메모리를 얼마나 할당한지 정해줄 수 있다. 이 방법을 이용해 배포되어있는 서버와 최대한 비슷한 환경으로 테스트를 하면 더 정확할 수 있다.

이제 환경설정이 끝났다면 터미널에 아래 명령어를 실행 시켜주면 된다.

gradle

./gradlew gatlingRun

maven

mvn gatling:test


그리고 이런식으로 build 패키지 안에서 report를 확인할 수 있다.
여기서 주의할점은 이름을 따로 바꾸어 놓아야 나중에 확인이 편하다는 점이다!

이제 n+1 문제를 해결한 코드를 비교해보자

테스트 조건

  • 사용자 수: 100명
  • 요청 방식: atOnceUsers(100) (한 번에 100명이 동시 요청)
  • 테스트 환경: Docker (CPU 2.0 / Memory 4GB 제한)

before

after

지표 (Metric)기존변경 후성능 개선
Mean(평균)1,697 ms812 ms2.09배 빨라짐
Min(최소)410 ms220 ms1.86배 빨라짐
Max(최대)2,217 ms1,008 ms2.20배 빨라짐
50th pct(중간값)1,795 ms865 ms2.08배 빨라짐

위를 표를 보면 기존 코드보다 대략 평균 응답 시간이 약 2배 이상 개선되었고,
최대 응답 시간 또한 감소하여 전체적인 응답 안정성도 향상된 걸 확인할 수 있다.

결론

성능을 개선하면 어떻게 성능을 개선했는지도 중요하지만 얼마나 성능이 개선되었는지 수치화하는 것 또한 중요하다. 수치화를 통해 다른 사람들에게 내가 한 작업을 통해 얼마나 성능이 개선되었는지 알려줄 수 있기 때문이다.

참고자료
https://junuuu.tistory.com/902

profile
BE-Engineer

3개의 댓글

comment-user-thumbnail
2026년 3월 30일

워밍업 추가하면 더 정확한 결과를 얻을 수 있을 것 같아요

1개의 답글
comment-user-thumbnail
2026년 6월 20일

"자신의 컴퓨터가 양자컴퓨터 뺨치면" 표현 너무 웃기네요 k6만 사용해봤는데 게틀링도 사용해봐야겠어요!

답글 달기