부하 테스트 세팅(JMeter, Gatling)

0

TIL

목록 보기
170/183

부하 테스트를 세팅 - JMeter

JMeter 다운로드 링크

https://jmeter.apache.org/download_jmeter.cgi


터미널 명령어로 다운로드된 폴더에 bin 경로로 들어가서 jmeter.sh 파일을 실행

cd ~/apache-jmeter-5.6.3/bin # 경로로 들어가기
./jmeter.sh # jmeter 실행


테스트 계획 우클릭 -> 추가 -> 쓰레드들(사용자들) -> 쓰레드 그룹

  • 쓰레드들의 수(사용자 수) : 총 몇 개의 스레드를 생성할 것인지
  • Ramp-up 시간(단위: 초) : 스레드 수를 점진적으로 증가시키는 시간을 의미, 1초로 지정한 경우 1초 동안 점진적으로 스레드를 생성하여 트래픽을 발생시키게 된다.
  • 루프 카운트 : 스레드 그룹의 반복 실행 횟수를 의미, 10으로 설정한 경우 전체 스레드가 설정된 동작을 10번 반복하게 된다. Infinite를 체크하면 설정된 동작을 멈출 때까지 끊임없이 반복한다.

위에 사진의 설정에서는 100명의 사용자가 각 10번씩 요청하여 1000번의 요청이 이루어지는 테스트 시나리오이다.


부하 테스트 세팅 - Gatling

Gatling 다운로드 링크 :
https://docs.gatling.io/reference/install/oss/

현재 내 프로젝트는 gradle이므로 Download Gatling for Gradle-Java 선택

다운로드된 파일의 압축을 풀고 내 MSA 프로젝트의 경로 안에 넣는다.

ForTickets
├── application
│   ├── eureka
│   ├── gateway-service
│   ├── user-service
│   └── ...
├── build.gradle
├── component
├── gradle
├── gradlew
├── gradlew.bat
├── gatling  <-- 여기
├── README.md
└── settings.gradle

gatling을 서브프로젝트로 인식시키기 위해 최상위 루트에 있는 settings.gradle에 추가한다.

// ...
include 'gatling'
// ...

이제 /gatling/src/gatling/java/computerdatabase 경로 안에 들어가서 테스트 시나리오 작성을 위한 자바 클래스를 생성한다.

package computerdatabase;

import static io.gatling.javaapi.core.CoreDsl.*;
import static io.gatling.javaapi.http.HttpDsl.*;

import io.gatling.javaapi.core.*;
import io.gatling.javaapi.http.*;

public class UserSimulation extends Simulation {
    // HTTP 프로토콜 설정
    HttpProtocolBuilder httpProtocol = http
            .baseUrl("http://localhost:8080") // user-service의 base URL
            .acceptHeader("application/json")
            .userAgentHeader("Gatling");

    // 시나리오 정의: GET /user/1 API 호출
    ScenarioBuilder scn = scenario("Get User Scenario")
            .exec(
                    http("Get User") // 요청 이름
                            .get("/user/1") // 경로
                            .check(status().is(200)) // 응답 상태 코드 체크
            );

    {
        // 시뮬레이션 설정: 한 번에 10명의 사용자가 시나리오 실행
        setUp(scn.injectOpen(atOnceUsers(10))).protocols(httpProtocol);
    }
}

작성을 완료했다면 테스트를 실행하기 위해 터미널에서 명령어를 입력한다.

# Mac
./gradlew gatlingRun

테스트가 진행되고 결과를 build/reports/gatling 디렉토리에 HTML 형태로 저장한다.


근데 내가 요청하려는 대부분의 api는 로그인된 jwt정보가 필요하다.

때문에 테스트를 하기 위해선 테스트 요청에는 jwt 인증을 하지 않거나 테스트용 jwt 인증 과정을 따로 설정해주어야한다.

나는 처음에 jwt 인증을 하지 않도록 하는 방법을 고민해보았으나 설정을 하려면 security 등 광역으로 수정해야할 부분들이 많아질거같아 테스트 안에서 로그인하여 jwt를 헤더로 반환하여 사용하는 방법을 선택하였다.

package computerdatabase;

import static io.gatling.javaapi.core.CoreDsl.*;
import static io.gatling.javaapi.http.HttpDsl.*;

import io.gatling.javaapi.core.*;
import io.gatling.javaapi.http.*;

public class UserSimulation extends Simulation {

    // HTTP 프로토콜 설정
    HttpProtocolBuilder httpProtocol = http
            .baseUrl("http://localhost:12011") // user-service의 base URL
            .acceptHeader("application/json")
            .userAgentHeader("Gatling");

    // 시나리오 정의
    ScenarioBuilder scn = scenario("유저 정보 조회")
            // 로그인 요청
            .exec(http("로그인")
                    .post("/user-service/auth/login")
                    .header("Content-Type", "application/json")
                    .body(StringBody("{ \"email\": \"user1@email.com\", \"password\": \"Abcd1234!\" }")) // 적절한 사용자 정보로 변경
                    .check(status().is(200))
                    .check(header("Authorization").saveAs("jwtToken")) // JWT 토큰을 추출하여 "jwtToken" 변수에 저장
            )
            // 정보 조회 요청
            .exec(http("유저 정보 조회")
                    .get("/user-service/users") // 유저 정보 조회 API 경로
                    .header("Authorization", "#{jwtToken}") // 세션에서 jwtToken 가져오기
                    .check(status().is(200)) // 응답 상태 코드 체크
                    .check(bodyString().saveAs("responseBody")) // 응답 본문을 변수에 저장
            )
            // 토큰 확인
//            .exec(session -> {
//                String jwtToken = session.getString("jwtToken");
//                System.out.println("JWT Token: " + jwtToken); // JWT 토큰 출력
//                String responseBody = session.getString("responseBody");
//                System.out.println("Response Body: " + responseBody);
//                return session;
//            })
            ;
    {
        // 시뮬레이션 설정: 한 번에 10명의 사용자가 시나리오 실행
        setUp(scn.injectOpen(atOnceUsers(5000))).protocols(httpProtocol);
    }
}

이렇게 5000번을 설정하고 테스트를 해보았더니


무려 75%가 실패로 떴다.

cpu 사용량도 확인해보니 어마어마하게 잡아먹는게 확인됐다.

곰곰히 생각해보니 유정 정보를 요청하는 api 뿐만 아니라 로그인하는 api도 함께 테스트가 되다보니 외부 요인이 작용한다는 생각이 들었다.


그래서 로그인 api는 제외하도록 로그인 요청 api는 진행하지 않고, 직접 post man 등의 방법으로 로그인하여 반환된 jwt토큰을 하드코딩으로 직접 입력해주어 동일하게 5000번 실행하였더니

실패율이 확 줄었고 cpu 사용량도

최대 60%로 확실하게 줄어드는 것을 확인할 수 있었다.

0개의 댓글

관련 채용 정보