사전 Gatling
구현체

Gatling

gabury1

Gatling 은 서버에 부하를 걸어 보는 도구입니다. 사람이 쓰는 것처럼 요청을 대신 보내고, 서버가 어디까지 버티는지 재 줍니다. 무엇을 보낼지는 화면에서 그리지 않고 코드로 적습니다. 다 돌고 나면 그래프가 든 웹 페이지 한 벌이 떨어집니다.

상세

프로젝트 README 는 Gatling 을 오픈소스 부하 테스트 플랫폼이라고 적습니다. 공식으로 지원하는 프로토콜은 여섯입니다. HTTP(HyperText Transfer Protocol) · WebSocket · Server-Sent Events · JMS(Java Message Service) · gRPC · MQTT(Message Queuing Telemetry Transport) 입니다. 그리고 CI/CD(Continuous Integration / Continuous Delivery, 지속적 통합·지속적 배포) 파이프라인과 관측 도구에 붙는다고 적습니다.

테스트를 코드로 정의하는 것이 이 도구의 기본 자세입니다. 대본을 쓸 수 있는 언어는 다섯입니다. Java · Scala · Kotlin · JavaScript · TypeScript 입니다. 공식 FAQ 는 지금 모든 판이 이 다섯을 지원한다고 적습니다. 그리고 대개 Java 를 권한다고 덧붙입니다. 전산학 과정에서 널리 가르치는 언어라 다른 개발자를 끌어들이기 쉽다는 이유입니다.

대본을 쓰는 도구 묶음을 Gatling 은 SDK(Software Development Kit, 소프트웨어 개발 키트)라고 부릅니다. 용어집은 이 SDK 의 부품들이 원하는 효과의 정의일 뿐이라고 못 박습니다. 부르는 자리에서 효과가 나지 않는다는 뜻입니다. 부품들이 서로 엮여 마지막에 setUp 으로 넘어갔을 때에야 Gatling 엔진이 그것을 해석하고 효과를 냅니다.

시뮬레이션

시뮬레이션은 부하 테스트를 서술한 것입니다. 여러 사용자 집단이 어떤 시나리오를 밟고 새 가상 사용자가 어떻게 투입되는지를 담습니다. 테스트 클래스는 Simulation 을 상속해야 Gatling 이 띄울 수 있습니다.

flowchart TD
    P["프로토콜 설정"] --> S["setUp"]
    N["시나리오"] --> S
    I["주입 프로파일"] --> S
    S --> E["Gatling 엔진"]
    E --> R["리포트"]

주입 프로파일은 가상 사용자를 시작시키는 방식입니다. 용어집은 둘로 갈라 적습니다. 시간에 따라 초당 몇 명을 새로 넣느냐가 열린 워크로드고, 시간에 따라 동시에 몇 명이 붙어 있느냐가 닫힌 워크로드입니다.

무엇 위에서 도나

자바 계열 SDK 를 쓰려면 64비트 OpenJDK LTS(Long-Term Support, 장기 지원) 판이 필요합니다. 공식 튜토리얼은 11부터 25까지 지원하고 17 이나 21 을 권한다고 적습니다. 기본 설정 파일 gatling-defaults.conf 에는 Netty 의 리눅스 네이티브 전송을 Java NIO 대신 쓸지를 정하는 gatling.netty.useNativeTransport, TLS(Transport Layer Security)를 OpenSSL 로 처리할지 JSSE(Java Secure Socket Extension)로 처리할지를 정하는 gatling.ssl.useOpenSsl 같은 키가 들어 있습니다.

결과물

리포트는 기본으로 테스트가 끝날 때 자동으로 만들어집니다. HTML(HyperText Markup Language) 파일이라 웹 브라우저가 있는 기기면 어디서든 볼 수 있다고 용어집이 적습니다. 로컬 실행이면 target/gatling 아래에 떨어집니다.

포기한 것

가상 사용자마다 스레드 하나

용어집은 이렇게 적습니다. 어떤 부하 도구들은 가상 사용자를 스레드로 구현하고, Gatling 은 그것을 메시지로 구현한다고. 그래서 확장이 훨씬 잘 되고 동시 사용자 수천 명을 쉽게 다룰 수 있다는 설명이 붙습니다.

README 도 같은 자리를 짚습니다. 오래된 도구 상당수가 블로킹 입출력과 사용자 한 명당 스레드 하나 구조에 기대고, 그래서 부하 발생 서버를 잔뜩 유지해야 한다고 적습니다. Gatling 은 논블로킹·비동기 구조를 써서 노드 하나당 자원 효율과 확장성을 최대로 끌어올린다고 적습니다.

포기한 자리는 사용자 하나를 실행 흐름 하나에 얹는 단순한 모델입니다. 얻은 것은 노드 하나가 감당하는 동시 사용자 수입니다.

커뮤니티판의 분산 실행

여러 부하 발생기를 쓰는 분산 테스트는 Enterprise Edition 의 핵심 기능이라고 FAQ 가 적습니다. 그리고 커뮤니티판(Community Edition)으로 분산 테스트를 하는 것은 지원하지 않는다고 못 박습니다. 여러 시뮬레이션을 잇달아 돌리는 것에도 답이 "아니오" 입니다. 그건 Gatling 밖에서 하라고 적습니다. Maven 플러그인 실행을 여러 번 걸거나 Jenkins 잡을 여러 개 두는 식입니다.

대신 커뮤니티판이 얻은 것은 한 대로 끝나는 실행 모델입니다. 조율할 노드도 결과를 합칠 자리도 없습니다. FAQ 는 사용자 한 명이 요청 하나인 경우 로컬 머신에서 초당 64,000 사용자를 낼 수 있다고 적습니다. 그 한계는 운영체제지 Gatling 이 아니라는 단서가 붙습니다. 부하 발생기를 늘려야 하는 지점도 셋으로 적혀 있습니다. 지금 발생기가 심하게 눌릴 때, 동시 가상 사용자가 50,000 명을 넘겨야 할 때, 지리적으로 다른 곳에서 사용자를 넣어야 할 때입니다.

리포트 모듈의 오픈소스 라이선스

Gatling 은 Apache License v2.0 으로 배포된다고 라이선스 문서가 적습니다. 다만 가능한 한 그렇게 한다는 단서가 붙습니다. Apache License v2.0 과 안 맞거나 오픈소스에 친화적이지 않은 의존성을 만날 때가 있다는 설명입니다.

기본 리포트 생성 모듈이 그 자리입니다. 이 모듈은 Highcharts 와 Highstock 이라는 자바스크립트 라이브러리를 씁니다. 문서는 이 둘이 오픈소스도 아니고 Gatling 의 용도에는 무료도 아니라고 적습니다. Gatling 쪽은 개발자 라이선스를 사고 Highsoft 와 합의해서 배포할 권리를 얻었습니다. 그 결과 이 모듈은 오픈소스로 낼 수 없고 gatling-highcharts 라는 별도 프로젝트로 떨어져 나갔습니다.

제약 둘이 문서에 그대로 적혀 있습니다. Highcharts 라이선스를 사지 않으면 이 모듈의 소스를 고칠 수 없습니다. 함께 배포된 Highcharts·Highstock 사본은 Gatling 의 표준 사용 밖에서는 쓸 수 없습니다.

포기한 것은 배포물 전체를 한 라이선스로 맞추는 것입니다. 얻은 것은 아무것도 따로 붙이지 않고도 테스트 끝에 그래프가 든 HTML 리포트가 나온다는 것입니다.

예시

BasicSimulation

공식 자바 튜토리얼이 마지막에 내놓는 완성 파일입니다. 3.15.1 판 이후를 기준으로 적힌 문서입니다.

Java
package example;

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 BasicSimulation extends Simulation {

  HttpProtocolBuilder httpProtocol =
    http.baseUrl("https://api-ecomm.gatling.io")
      .acceptHeader("application/json")
      .userAgentHeader("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36");

  ScenarioBuilder scenario =
    scenario("Scenario").exec(http("Session").get("/session"));

  {
    setUp(scenario.injectOpen(constantUsersPerSec(2).during(60))).protocols(httpProtocol);
  }
}

http.baseUrl 이 요청을 보낼 서버를 정합니다. 시나리오 이름은 "Scenario" 고 /session 으로 GET 요청 하나를 던집니다. constantUsersPerSec(2).during(60) 은 초당 두 명씩 1분 동안 넣는다는 뜻이라고 튜토리얼이 적습니다.

실행은 Maven 래퍼로 합니다.

./mvnw gatling:test

프롬프트가 뜨면 [1] example.BasicSimulation 을 고릅니다. 끝나면 터미널에 리포트 경로가 찍힙니다. target/gatling/basicsimulation-<timestamp>/index.html 입니다.

열린 모델 주입 프로파일

주입 스텝을 늘어놓은 공식 예제입니다. 스텝은 적힌 순서대로 처리됩니다.

Java
setUp(
  scn.injectOpen(
    nothingFor(4), // 1
    atOnceUsers(10), // 2
    rampUsers(10).during(5), // 3
    constantUsersPerSec(20).during(15), // 4
    constantUsersPerSec(20).during(15).randomized(), // 5
    rampUsersPerSec(10).to(20).during(10), // 6
    rampUsersPerSec(10).to(20).during(10).randomized(), // 7
    stressPeakUsers(1000).during(20) // 8
  ).protocols(httpProtocol)
);
스텝 문서가 적는 것
nothingFor(4) 주어진 시간 동안 멈춥니다
atOnceUsers(10) 주어진 수의 사용자를 한꺼번에 넣습니다
rampUsers(10).during(5) 주어진 수의 사용자를 그 시간 창에 고르게 나눠 넣습니다
constantUsersPerSec(20).during(15) 초당 사용자 수를 일정하게 유지하며 넣습니다. 간격은 일정합니다
constantUsersPerSec(20).during(15).randomized() 같은 비율인데 간격을 무작위로 흩습니다
rampUsersPerSec(10).to(20).during(10) 초당 사용자 수를 시작 비율에서 목표 비율까지 끌어올립니다
stressPeakUsers(1000).during(20) 헤비사이드 계단 함수를 그 시간만큼 늘려 매끄럽게 근사한 모양으로 넣습니다

시간 단위를 안 적으면 초입니다. 비율은 소수로도 적을 수 있습니다.

운영

설정이 겹치는 순서

설정은 Typesafe Config 라이브러리를 쓰고 파일은 HOCON(Human-Optimized Config Object Notation) 형식입니다. 값이 겹칠 때의 우선순위가 문서에 한 줄로 적혀 있습니다. 시스템 프로퍼티가 gatling.conf 를 이기고, gatling.conf 가 gatling-defaults.conf 를 이깁니다.

gatling-defaults.conf 는 gatling-core jar 안에 들어 있고 손대면 안 된다고 적혀 있습니다. gatling.conf 는 파일 시스템이 아니라 클래스로더에서 찾습니다. Maven·Gradle·sbt 프로젝트면 src/test/resources 에 둬야 한다는 뜻입니다. 파일 이름은 시스템 프로퍼티 -Dgatling.conf.file 로 바꿉니다. 이때도 클래스패스 기준이라 경로를 적으면 안 됩니다.

문서가 따로 못 박는 함정이 하나 있습니다. gatling.conf 를 고칠 때 줄 앞의 # 을 지우지 않으면 그 변경은 먹지 않습니다.

리포트가 읽는 기본값

리포트의 응답 시간 구간과 백분위수는 gatling.conf 에서 정해집니다. 기본값은 배포판에 든 gatling-defaults.conf 가 갖습니다.

키 기본값 무엇을 정하나
gatling.charting.indicators.percentile1 50 리포트와 콘솔 요약에 표시할 첫 번째 백분위수
gatling.charting.indicators.percentile2 75 두 번째 백분위수
gatling.charting.indicators.percentile3 95 세 번째 백분위수
gatling.charting.indicators.percentile4 99 네 번째 백분위수
gatling.charting.indicators.lowerBound 800 응답 시간 구간의 아래 경계
gatling.charting.indicators.higherBound 1200 응답 시간 구간의 위 경계
gatling.charting.maxPlotPerSeries 1000 차트 하나에 찍는 점의 개수
gatling.charting.useGroupDurationMetric false 그룹 타이밍을 누적 응답 시간 대신 그룹 지속 시간으로 바꿉니다
gatling.http.requestTimeout 60000 HTTP 요청 하나의 제한 시간. 밀리초입니다
gatling.data.writers [console, file] 시뮬레이션 데이터를 어디로 쓰나
gatling.data.console.writePeriod 5 콘솔에 쓰는 간격. 초입니다
gatling.data.enableAnalytics true 익명 사용 통계 전송. 기본이 켬입니다

백분위수 그래프는 성공한 요청만 씁니다. 실패한 요청은 일찍 끝나거나 타임아웃 때문에 생기는 것이라 백분위수 계산을 크게 흔든다는 설명이 붙어 있습니다.

한 대가 먼저 부딪히는 자리

Gatling 은 도는 동안 열린 파일 핸들을 아주 많이 쓴다고 운영 문서가 적습니다. 운영체제가 그 개수를 제한하기 때문에 소켓을 많이 열려면 값을 손봐야 할 수 있다는 설명입니다. 문서가 드는 예는 ulimit -n 1048576 입니다. 다만 그 변경은 지금 셸 세션에만 걸린다는 단서가 붙습니다.

커널과 네트워크 쪽 값도 예로 적혀 있습니다. /etc/sysctl.d/99-gatling.conf 에 fs.nr_open · net.ipv4.ip_local_port_range · net.ipv4.tcp_fin_timeout · net.ipv4.tcp_tw_reuse 같은 것들을 넣는 식입니다.

IPv6 는 자바에서 기본으로 켜져 있습니다. 그런데 성능 문제를 일으킬 때가 있다고 확인되어, 실행 스크립트가 -Djava.net.preferIPv4Stack=true 와 -Djava.net.preferIPv6Addresses=false 로 끕니다.

끝난 뒤에 남는 것

실행이 중간에 끊겼으면 -ro 옵션으로 잘린 simulation.log 에서 리포트를 다시 만들 수 있습니다. 다만 로그를 쓰는 부품이 버퍼를 쓰기 때문에, 강제로 끊으면 마지막 데이터가 빠질 수 있다고 문서가 적습니다.

그 simulation.log 를 직접 파싱해도 되느냐는 물음에는 FAQ 가 "아니오" 라고 답합니다. 이 파일은 공식 HTML 리포트를 만들려고 두는 구현 세부이고, 포맷은 문서화되어 있지 않으며 언제든 예고 없이 바뀔 수 있다고 적습니다. 사내 연동을 이 파일 위에 세우지 말라는 문장이 붙어 있습니다.

관련 항목

이것이 공식으로 지원하는 프로토콜

HTTP · WebSocket · Server-Sent Events · JMS · gRPC · MQTT

대본을 쓸 수 있는 언어

Java · Scala · Kotlin · JavaScript · TypeScript

Gatling을 실행하는 빌드 도구

Maven · Gradle · sbt

시뮬레이션을 이루는 구성 요소

가상 사용자 · 시나리오 · 주입 프로파일 · 열린 워크로드 모델 · 닫힌 워크로드 모델 · 부하 발생기 · Feeders

이것이 붙는 CI/CD 요소

지속적 통합 · 지속적 배포 · 파이프라인 · Jenkins · APM

실행과 설정이 기대는 하부 기술

Netty · TLS · OpenSSL · JSSE · OpenJDK · HOCON · Typesafe Config · 클래스로더 · Java NIO

이것이 택한 처리·동작 방식

논블로킹 입출력 · 캐싱 · 병렬 처리

리포트가 갖는 형식과 지표

브라우저 · HTML · 응답 시간 · 백분위수

부하가 커질 때 맞닥뜨리는 운영체제 자원

운영체제 · 커널 · 네트워크 · 셸 · IPv6 · 파일 디스크립터 · Linux

Gatling이 속한 갈래와 겨루는 도구

부하 테스트 · ab · wrk

Gatling이 갈리는 배포판과 라이선스

Enterprise Edition · Community Edition · Apache License 2.0

리포트 모듈에 관여하는 회사·프로젝트

Highcharts · Highstock · Highsoft · gatling-highcharts

다른 이름: 개틀링 · gatling