부하 테스트란 임계치에 도달할 때까지 시스템에 부하를 꾸준히 증가시키며 진행하는 테스트이다. 소위 말해 시스템이 '뻗을' 때까지 부하를 주고, 그렇게 한계치에 도달한 시스템이 어떻게 동작하는지를 테스트하는 것이다.
JMeter를 통해서도 당연히 부하 테스트가 가능하지만, Apache JMeter 공식 홈페이지에서는 부하 테스트(load test) 진행 시 GUI모드가 아닌 CLI모드를 사용할 것을 명시하고 있다.
부하 테스트를 위해서는 먼저 JMeter에서 사용 가능한 HEAP 메모리를 수정해야 한다. JMeter.bat에서 다음 부분을 수정하면 된다.
if not defined HEAP (
rem See the unix startup file for the rationale of the following parameters,
rem including some tuning recommendations
set HEAP=-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m
)
set HEAP= 뒤의 설정값이 다르게 설정되어 있을 것이다. 나는 컴퓨터 환경이 좋은 편이 아니라 얼마 늘리지 못했지만, 본인의 환경에 따라 적당히 맞춰주면 된다. (6g까지 설정한 예제도 어렵지 않게 찾을 수 있었다.)
PC 환경과 수행할 부하 테스트를 고려하여 적절한 용량을 맞춰주면 된다. 용량이 너무 작을 경우 부하 테스트가 정상 실행되지 않고, PC 환경 대비 너무 많은 메모리를 할당할 시 JMeter가 아예 실행되지 않을 수 있다.
CLI 모드로 부하 테스트를 수행하기 위해서는 먼저 GUI 모드에서 작성된 테스트 시나리오가 필요하다. 기본적인 시나리오 작성은 아래 포스트를 참고하자.
[JMeter] JMeter를 활용한 테스트 시나리오 작성 방법(jmx파일)
해당 포스트의 시나리오와 코드를 조금 수정해 부하 테스트 예제를 시행해보도록 하겠다.
먼저, FastAPI 코드의 login 부분을 다음과 같이 수정하였다.
@app.post("/login")
def login(user: User):
id = random.randrange(1, 100)
token = None if id < 30 else str(uuid.uuid4())
return {"id": id, "token": token}
이렇게 수정하면 30% 확률로 token 값에 None을 반환한다. 이렇게 되면 회원 가격 조회 시 30% 확률로 테스트 실패가 발생한다. 테스트 실패가 이후 Dashboard에서 어떻게 나타나는지를 확인하기 위함이다.
이렇게 수정하면 30% 확률로 token 값에 None을 반환한다. 이렇게 되면 회원 가격 조회 시 30% 확률로 테스트 실패가 발생한다. 테스트 실패가 이후 Dashboard에서 어떻게 나타나는지를 확인하기 위함이다.

유저 수, 시간, 반복 횟수는 각각 300,5,200으로 설정했다.
300명의 유저가 5초 동안 시나리오에 작성된 action을 수행하며, 그 과정을 200번 반복한다.
결과적으로 시나리오가 300x200=60000번 실행될 것이라 기대할 수 있다.
수정이 완료되었으면 해당 변경사항 또한 jmx 파일로 저장해두도록 하자.
JMeter CLI 실행을 위해서는 JMeter.bat이 있는 폴더의 터미널에서 다음 명령어를 입력하면 된다.
(윈도우의 경우 PowerShell이 아닌 명령 프롬프트에서 실행해야 한다.)
jmeter.bat -n -t [jmx file] -l [results file] -e -o [Path to web report folder]
jmx file : 실행하고자 하는 시나리오의 jmx 파일 경로results file : 실행 결과를 담은 csv 파일 저장 경로Path to web report folder : 실행 결과 시각화 파일을 저장할 폴더 경로나는 다음과 같이 입력해 부하 테스트를 시행했다.
jmeter -n -t "D:\JMeter\test_plan.jmx" -l "D:\JMeter\example_test_plan_result.csv" -e -o "D:\JMeter\20231005"
상세한 명령어 해설은 다음과 같다.
n : CLI 모드로 실행t : [테스트 계획이 포함된 JMX 파일 이름]을 입력l : [샘플 결과를 기록할 JTL 파일 이름]을 입력j : [JMeter 실행 로그 파일 이름]을 입력r : JMeter 속성 "remote_hosts"로 지정된 서버에서 테스트를 실행R : [원격 서버 목록] 지정된 원격 서버에서 테스트를 실행g : [CSV 파일 경로] 보고서 대시보드만 생성e : 부하 테스트 후 리포트 대시보드 생성o : 로드 테스트 후 보고서 대시보드를 생성할 출력 폴더 (폴더가 존재하지 않거나 비어 있으면 안)H : [프록시 서버 호스트 이름 또는 IP 주소]P : [프록시 서버 포트]
명령 프롬프트에 해당 명령어를 입력하면 위와 같이 부하 테스트가 실행된다. (실행 내용에 따라 다소 시간이 소요될 수 있다.)

csv 파일을 엑셀로 열어보면 위와 같은 결과가 나오는 것을 확인할 수 있다. 각 열별 의미는 다음과 같이 해석할 수 있다.
timeStamp : 요청이 발생한 시각elapsed : 요청에 소요된 총 시간. Latency와 IdleTime을 포함한다.label : 보낸 request의 이름responseCode : 응답 코드responseMessage : 응답 메시지threadName : 쓰레드 그룹 이름dataType : 응답 데이터의 타입success : 테스트 성공 여부failureMessage : 테스트가 실패했을 경우 실패 메시지를 표시한다.bytes : 응답 데이터 바이트sentBytes : 요청 데이터 바이트grpThreads : 현재 활성 스레드 수 (=액티브 유저 수)allThreads : 전체 스레드 수를 의미하지만, 현재 스레드 그룹이 하나뿐이므로 활성 스레드와 같다.URL : 요청 URLLatency : 지연시간. 요청 시작 시점부터 응답 시작 시점까지의 시간을 의미한다.IdleTime : 유휴시간. 작동 가능한데도 작업을 하지 않는 시간.Connect : 연결을 설정하는 데 걸리는 시간 (클라이언트와 서버가 TCP 연결을 설정하는 데 걸리는 시간. 이 시간 이후부터 클라이언트가 서버에 요청을 보낼 수 있다. Latency를 포함한다.)latency가 눈에 띄게 증가하는 구간이 있는 것을 보아 유저가 몰림에 따라 서버가 느려지는 것을 확인할 수 있다. 그에 따라 elapsed도 천차만별이다.
csv 파일로도 대략적인 경향은 확인할 수 있지만 사람이 한눈에 보고 판단하기는 어려움이 있다. 따라서 JMeter에서는 csv 파일의 데이터를 기반으로 한 시각화 결과를 함께 제공한다. 실행 시 [ Path to web report folder ] 에 입력했던 경로에 가면 HTML 파일로 확인할 수 있다.
대시보드는 수행한 작업에 대한 대략적인 통계를 한눈에 보여주는 페이지이다.

분석에 대한 기본적인 정보와 Apdex(Application Performance Index), 성공 및 실패 요청의 비율을 보여주는 그래프를 확인할 수 있다. Apdex는 소프트웨어 애플리케이션 성능 평가 지표 중 하나로, 자세한 내용은 위키백과 링크를 참고하길 바란다.
3개 중 1개 응답에 30% 확률로 FAIL을 주었으므로, 10% 언저리로 기댓값에 준하는 비율이 나왔다.

Statistics는 3개의 구성 가능한 백분위수를 포함하여 트랜잭션당 모든 메트릭의 요약을 하나의 테이블에 제공하는 통계 테이블이다. 전체 샘플 수와 성공/실패 비율, 응답시간의 요약 통계, Throughput과 Network의 성능 평가 지수를 확인할 수 있다. 이를 통해 대략적인 성능을 파악할 수 있다.

하단에는 Error 관련 지표를 확인할 수 있다. Errors는 모든 오류의 요약과 전체 요청에서 차지하는 비율을 제공하며, Top 5 Errors by sampler는 모든 샘플러(트랜잭션 컨트롤러 제외)에 대해 상위 5가지 오류를 제공한다. 나는 '회원 가격을 조회했으나 비회원 가격을 응답으로 받아온 경우'의 하나만을 실패로 처리해주었으므로, 이 실패 유형이 100%가 나왔다.
Charts는 Over time(시간별 지표), Throughput(성능 평가 지표), Response Times(응답 시간)을 그래프로 시각화하여 보여 주는 부분이다. 각각의 그래프는 접혀 있으므로 펼쳐서 확인할 수 있다. 포스팅에서는 대표적인 몇 가지 그래프만 살펴보도록 하겠다.

Response Times Over Time은 트랜잭션 컨트롤러 샘플 결과를 포함한 시간 경과에 따른 응답 시간 그래프이다. Sampler별로 응답시간 증가율을 비교할 수 있는데, 이 차트의 경우 로그인, 회원 가격 확인, 비회원 가격 확인 Sampler가 전부 비슷한 비율로 응답시간이 증가하거나 감소하고 있음을 알 수 있다. 3분여의 테스트에서 1분가량은 응답시간이 급격히 증가하다가 그 후 1분 동안은 완만하게 증가했고, 이후로 감소하는 추세를 보이고 있다.

Throughput(처리량)은 네트워크에서 초당 실제로 처리되는 패킷의 양을 의미하는데, 그중 Hits Per Second는 사용자가 1초 동안 웹 서버로 전송한 HTTP 요청의 수를 나타낸다. 응답 시간 그래프와 비슷한 모양을 띄고 있는데, 이를 통 응답 시간 지연이 HTTP 요청의 수가 늘어나서 발생했다고 유추할 수 있다. 따라서 테스트 실행 후 1~2분 사이에 트래픽이 급격히 증가해 응답 시간 지연이 일어났음을 알 수 있다.
그 밖에 그래프들이 의미하는 바는 JMeter 공식 문서의 Generating Report Dashboard 부분을 참고하면 좋다.
Apache JMeter 공식문서 Generating Report Dashboard
Apache JMeter 공식문서 CLI Mode (Comment Line mode was called NON GUI mode)
GRU - [JMeter]JMeter Basics
토마토조아 - IT/Server [Apache] Jmeter(제이미터) 부하 테스트 방법(콘솔 명령어 기반)