일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- Springboot 테스트 속도
- 성능테스트 모니터링
- @DirtiesContext 속도
- gradle plugin이란
- 스프링 성능테스트
- 자바Thread
- spring 테스트 성능
- file upload progress
- 테스트 속도
- 스프링 모니터링
- 자바 가상스레드란
- spring socuter
- 스프링 gatling
- gradle pl
- JDK21 가상스레드
- gradle custom plugin
- okhttp sink
- 자바 가상스레드
- gradle plugin만들기
- spring 테스트 속도
- 스프링 scouter
- spring gatling
- okhttp progress
- custom plugin
- JAVA 가상스레드란
- gatling
- okhttp upload progress
- junit 테스트 속도
- @MockBean 속도
- 테스트 속도개선
- Today
- Total
호딩클라우드
[Spring] gatling 성능테스트 with scouter 모니터링 본문
Gatling 설치
오픈소스 기반의 성능 측정 도구이며 내부적으로 Akka와 Netty를 사용하기 때문에 ngrinder와 Jmeter보다 적은 부담으로 더 많은 부하를 이용한 테스트를 진행할 수 있습니다.
홈페이지 : https://gatling.io/
학습페이지 : https://gatling.io/academy
다운로드 : https://gatling.io/open-source/

다운로드 후 /bin 로가면 gatilng 실행파일과 recorder가 존재하는데 recorder는 시나리오 세팅을 도와주는 도구입니다.
예제 프로젝트로는 spring 리포지토리의 petclinic을 사용하겠습니다.
https://github.com/spring-projects/spring-petclinic
예제프로젝트를 다운로드한 뒤 실행시켜 주고 성능테스트를 하려는 페이지에 접속하면서 개발자도구에 네트워크 캡처를 진행해줍니다.
그 후 [개발자도구] - [Network] - [우클릭] - [Save all as HAR with content]를 눌러 HAR 파일을 다운로드해줍니다.

Har file 이란?
HTTP Archive format의 약자로 Json 형태의 파일로 네트워크 기록을 Debug 하기 위해 사용한다. Viewer를 통해 파일을 열어보면 아래 사진으로 확인할 수 있듯이 해당 유저가 Network Tab의 기록동안 어떤 일을 했는지 파악할 수 있다.
출처: https://devroach.tistory.com/125 [Rlog:티스토리]
즉, 특정 화면에서 사용되는 Request를 캡처한 json 형태의 파일입니다.
.. 생략 ..
"cache": {},
"connection": "507062",
"pageref": "page_2",
"request": {
"method": "GET",
"url": "http://localhost:8080/owners?lastName=",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Accept",
.. 생략 ..
시나리오 스크립트 생성
gatiling은 Har file을 통해서 스크립트 초기 세팅을 할 수 있습니다.
1. Recorder mode를 HAR Converter로 지정해 줍니다.
2. 다운로드한 harfile을 Browse 해줍니다.
3. No static resources 버튼으로 static resource를 제거해 줍니다.
4. start 버튼으로 스크립트 파일을 생성해 줍니다.
Simulation information - inferHtmlResources 옵션을 켜게 되면 정적인 리소를 요청마다 받음으로 CDN을 사용할 경우 비용 및 자원낭비 문제로 이어질 수 있으니 서비스 개편, 서비스 최초 오픈 시에만 켜고 테스트하는 것을 권장한다고 합니다.

시나리오 파일은 gatling다운로드 폴더에 user-files/simulations에 생성됩니다.
생성된 파일 하단 부분에 ScenarioBuilder를 보면 HAR 파일을 기반으로 시나리오가 생성되어 있습니다.
private ScenarioBuilder scn = scenario("RecordedSimulation")
.exec(
http("request_0")
.get("/owners?lastName=")
.headers(headers_0),
http("request_1")
.get("/webjars/font-awesome/4.7.0/fonts/fontawesome-webfont.woff2?v=4.7.0")
.headers(headers_1),
pause(Duration.ofMillis(296)),
http("request_2")
.get("/github-markdown-css")
.headers(headers_2)
.check(status().is(404)),
http("request_3")
.get(uri4 + "/?ext_id=baecjmoceaobpnffgnlkloccenkoibbb&ext_width=318")
.headers(headers_3),
http("request_4")
.get(uri1 + "/client")
.headers(headers_4),
http("request_5")
.get(uri1 + "/style")
.headers(headers_4),
http("request_6")
.get(uri1 + "/button?type=standard&shape=rectangular&theme=outline&text=continue_with&size=large&logo_alignment=center&width=318&client_id=630072318488-5jn6np2l4jknug91dehqarem7epqrua4.apps.googleusercontent.com&iframe_id=gsi_993525_871826&as=BY9fh2q7VMgNK2HCvGG4Ag")
.headers(headers_6),
http("request_7")
.get(uri5)
.headers(headers_7),
pause(10),
http("request_8")
.post(uri2 + "?format=json&hasfast=true&authuser=0")
.headers(headers_8)
.formParam("[[1,null,null,null,null,null,null,null,null,null,[null,null,null,null,\"ko\",null,null,null,[[[\"Chromium\",\"122\"],[\"Not(A:Brand\",\"24\"],[\"Google Chrome\",\"122\"]],0,\"macOS\",\"13.4.1\",\"arm\",\"\",\"122.0.6261.57\"],[1,0,0,0,0]]],1112,[[\"1708928993737\",null,null,null,null,null,null,\"[\\\"BY9fh2q7VMgNK2HCvGG4Ag\\\",12,0,null,\\\"630072318488-5jn6np2l4jknug91dehqarem7epqrua4.apps.googleusercontent.com\\\",\\\"https://notegpt.io\\\",[2],null,null,null,null,null,null,4,null,null,null,[1,1,1,318,4,2,1]]\",null,null,12,null,null,null,-32400,null,null,null,null,null,1]],\"1708929003738\"]", "")
);
{
setUp(scn.injectOpen(atOnceUsers(1))).protocols(httpProtocol);
}
생성된 파일에 불필요한 Request를 정리해 줍니다.
..생략..
private ScenarioBuilder scn = scenario("RecordedSimulation")
.exec(
http("request_0")
.get("/owners?lastName=")
.headers(headers_0)
);
{
setUp(scn.injectOpen(atOnceUsers(1))).protocols(httpProtocol);
}
..생략..
기본적으로 gatiling은 일회성 부하를 주도록 설정해 줍니다.
단발성으로는 부하테스트를 하기 어렵기 때문에 스크립트를 수정해야 합니다.
용어 참고
Injection: Virtual User가 유입되는 방식을 결정합니다.
SetUp method 추가정보
SetUp method
----------------------
- nothingFor(duration): duration 만큼 그냥 대기
- atOnceUsers(nbUsers) :사용자수만큼한번에수행
- rampUsers(nbUsers).during(duration) : duration 동안 0~사용자 수 까지 증가
- constantUsersPerSec(rate).during(duration) : duration동안 초당 rate명씩 추가
- constantUsersPerSec(rate).during(duration) randomized() : duration동안 랜덤한 간격으로 rate명씩 추가
- rampUsersPerSec(rate1).to(rate2).during(duration) : 초당 rate1명의 사용자에서 rate2명까지 일정한 간격으로 duration동안 증가 (10, 21, 33, 46, ...)
- rampUsersPerSec(rate1).to(rate2).during(duration).randomized() : 초당 rate1명의 사용자를 rate2명까지 랜덤한 간격으로 duration동안 증가
- stressPeakUsers(rate).during(duration): rate 명의 사용자를 duration동안 부하를 헤비사이드 계단 함수에 맞춰 증가
더 많은 정보 (Gatling document)
아래 스크립트는 3초 동안 3명의 사용자수까지 증가(rampUser)시키고 60초 동안 시나리오대로 요청을 보내도록 설정합니다.
private ScenarioBuilder scn = scenario("RecordedSimulation")
.during(60).on(
exec(
http("searchOwner")
.get("/owners?lastName=")
.headers(headers_0)
)
);
{
setUp(scn.injectOpen(rampUsers(3).during(3))).protocols(httpProtocol);
}
스카우터 설치
다운로드 : https://github.com/scouter-project/scouter/releases
필자는 scouter-all-2.20.0.tar.gz을 다운로드하였습니다.

스카우터 구조
- java agent -> 자바 모니터링 에이전트, jar 실행 시 옵션으로 attach 해줘야 합니다.
- agent.host -> 서버 리소스 모니터링,
- server(colleter) : agnet로부터 데이터수집, 파일가반의 수집서버이기 때문에 DB가 필요 없습니다.
pinpoint는 DB로 하둡를 사용해서 초기 세팅에 조금 더 번거로웠던 걸로 기억하는데 scouter에 경우 비교적 세팅이 수월하여 개인적으로 선호하는 APM입니다.
다운받은 폴더에 /scouter/server로 이동하여 startup.sh 파일에 원하는 버전의 jdk경로를 설정할 수 있습니다.
(scouter는 자바기반 오픈소스 입니다.)

/usr/libexec/java_home -V
사용가능한 jdk 버전과 경로를 확인하는 명령어
agent.host/host.sh 를 실행시켜주고 모니터링할 jar에 실행옵션으로 agent를 attach 해줍니다.
java -javaagent:{java agent 경로}/scouter.agent.jar -jar target/*.jar
스카우터의 초기세팅에 대한 자세한 정보는 아래 링크로 대체하겠습니다.
https://ta-starter.tistory.com/29
[Linux] Scouter 설치 및 구성
@ 사전작업 - Linux에 Tomcat이 설치되어 있는 환경 - Server, Agent, Client 모두 JDK 8 이상 필요 - Selinux disable # 지표 수신 서버(Collector) 작업 1. https://github.com/scouter-project/scouter/releases에서 scouter-all-2.10.0.t
ta-starter.tistory.com
scouter Client를 실행하고 Gatling을 통해 작성된 시나리오로 부하테스트를 실행해봅니다.

부하를 받는 60초 동안은 TPS 및 다른 지표가 증가하는 것을 확인할 수 있습니다.
method 프로파일링
추가적으로 Xlog를 드래그하여 호출에 대한 상세정보를 확인할 수 있는데 이때 method 프로파일링을 추가해야 호출정보를 자세히 확인할 수 있습니다.

[was우클릭] - [configure] 를 통해 설정할 수도 있고 scouter/agent.java/conf/scouter.conf 파일을 수정해도 같은 효과를 얻을 수 있습니다.
해당 파일에 아래 옵션을 적으면 메소드 프로파일링이 활성화됩니다. (서버 재시작 필요)
[메소드 프로파일링 옵션]
hook_method_patterns=org.springframework.samples.petclinic.*.*
hook_method-patterns = ${package 표현식}
프로파일링이 활성화 되면 아래와 같이 노란색 글씨로 호출된 메소드 정보를 확인할 수 있습니다.
메소드 프로파일링에 대한 더 자세한 정보

Gatling Report
gatling 실행을 마친 뒤에 gatling/result 에 보고서 파일이 생성됩니다.

'SpringBoot > 꿀팁' 카테고리의 다른 글
Gradle plugin 이란? Gradle Custom Plugin 만들기 (1) | 2024.02.15 |
---|