본문 바로가기
http

ngrinder 를 통한 부하 테스트(+jmeter)

by misankim 2023. 3. 24.

Locust 부하 테스트 도구로 웹서버 부하 테스트를 진행해봤는데, ngrinder 및 jmeter 에서도 Locust 를 통한 부하 테스트 결과와 동일한 결과가 나타나는지, 또 부하 테스트를 위한 여러 도구 중 어떤 도구를 사용하는게 더 편할지 등이 궁금해서 ngrinder 및 jmeter 를 통해 간단하게 부하 테스트 진행해봤습니다.

1. ngrinder 란

네이버에서 만든 부하 테스트 도구

공식 사이트
https://naver.github.io/ngrinder/

컨트롤러 - 부하 테스트 및 에이전트를 관리하는 호스트
에이전트 - 테스트 간 실제 부하를 발생 시키는 역할의 호스트

2. ngrinder 컨트롤러 다운로드/실행

ngrinder 는 java spring 프레임워크를 기반으로 동작하기 때문에 별도 설치는 필요 없이 java 만 설치되어 있다면 다운로드하여 바로 실행 가능합니다. 아래 공식 github 를 통해 컨트롤러 war 파일을 다운로드합니다.

https://github.com/naver/ngrinder/releases

# 컨트롤러 실행({version}은 다운로드한 버전으로 치환)
java -jar ngrinder-controller-{version}.war



이렇게 실행이 완료되면 8080포트를 통해 웹으로 접속합니다. 네이버에서 만들었기 때문에 한국어도 지원합니다. 초기 아이디/비밀번호는 admin/admin 입니다. 로그인 후 적절하게 변경합니다.

3. ngrinder 에이전트 다운로드/실행

에이전트는 부하를 발생시키는 역할로, 컨트롤러와 다른 호스트에 설치해도 되지만, 간단하게 테스트하려면 컨트롤러에서 실행해도 됩니다. 에이전트와 컨트롤러 간에는 통신을 위한 별도 포트가 지정되어 있기 때문에 방화벽(혹은 보안 그룹) 허용이 필요합니다. 동일 서버에서 컨트롤러와 에이전트 모두 실행하더라도, 다운로드된 에이전트 설치 파일에는 컨트롤러의 공인 아이피로 프리셋이 설정되어 있기 때문에, (마치 다른 호스트에 설치한 것과 동일하게) 공인 아이피에 대한 접속 허용을 별도로 해야합니다.

Agent ==> Controller : 16001
Agent ==> Controller : 12000 ~ 12000+(테스트의 회수가 증가함에 따라 포트 번호도 증가하기 때문에 범위로 열어야합니다)
Controller ==> Monitor : 13243
Controller ==> Public user : 톰캣에 연동하는 경우에는 톰캣의 포트를 허용해야하고, 연동 없이 독립 실행하려면 기본 포트인 8080을 허용해야합니다. 톰캣 연동은 필수가 아닙니다.

관리자 로그인 후 우측 상단의 아이디 부분을 눌러 열리는 팝업 메뉴에서 "에이전트 다운로드"를 클릭하여 에이전트 tar 파일을 다운로드하거나, 해당 경로를 복사하여 에이전트를 설치한 호스트에서 wget 으로 내려받습니다.

이제 컨트롤러 혹은 별도 부하 발생용 호스트에서 압축을 해제하고 run_agent.sh 파일을 실행합니다. 만약 에러가 발생한다면 에러 내용 및 방화벽 등을 확인합니다.

이제 컨트롤러 웹 콘솔에서 "에이전트 관리" 메뉴로 이동하여 정상적으로 에이전트가 등록되었는지 확인합니다.


4. 테스트 작성 및 실행

이제 부하 테스트를 위한 세팅은 완료되었으니 실제 테스트를 진행해봅니다. 기본적으로 ngrinder는 스크립트 탭에서 테스트를 위한 스크립트를 구성하고, 성능 테스트 탭에서 부하 테스트에 대한 상세 정보를 구성하지만, Quick Start 를 이용하면 둘 다 쉽게 구성이 가능합니다. 메인 페이지에서 Quick Start 부분에 http(s) 및 포트번호를 포함한 URL 경로를 입력하고 "테스트 시작" 버튼을 누르면 상세 설정 페이지로 이동합니다.

이동한 테스트 설정 페이지에서 아래 예시와 같이 테스트에 대한 구체적인 정보를 지정합니다.

1) 에이전트 - 테스트에 사용할 부하 생성기(에이전트)의 수를 입력(현재는 컨트롤러와 동일 호스트에 설치된 에이전트 1개만 있는 상황)
2) 가상 사용자 - 가상의 유저 수로, 입력하면 알아서 프로세스 수와 쓰레드 수를 분배해줍니다.(프로세스 수 * 쓰레드 수 = 가상 유저 수)
3) 스크립트 - Quick Start 로 시작하였기에 스크립트는 자동으로 구성되어 있습니다. 그냥 둡니다.
4) 테스트 기간/실행 횟수 - 부하 테스트를 일정 시간동안 진행할지, 아니면 일정 횟수로 진행할지 지정합니다.
5) Ramp-Up - 프로세스/쓰레드의 수를 처음부터 최대치로 올리는 것이 아닌 일정 시간을 두고 천천히 올립니다.

구성이 완료되면 "저장 후 시작" 버튼을 눌러 부하 테스트를 시작합니다. 아래와 같이 테스트 진행간 상황을 모니터링 가능하며, 테스트가 완료되어 결과가 보여집니다. TPS(초당 트랜잭션 수)를 보아 평균적으로 1초에 20개의 트랜잭션을 처리할 수 있는 것을 확인할 수 있습니다.

초당 처리할 수 있는 트랜잭션 수를 초과했음에도 에러가 0으로 보이는 것은 커넥션 타임아웃이 너무 길기 때문으로, 스크립트 탭으로 이동하여 "HTTPRequestControl.setConnectionTimeout" 값을 밀리 세컨드 단위로, 새로 지정합니다. (기본 값은 300초) 테스트에서는 300000(300초)을 5000(5초)으로 수정하여 다시 테스트했습니다.

수정 후 테스트 결과는 아래와 같습니다. 에러가 좀 보이는 것을 확인할 수 있습니다.

5. jmeter 와 결과 비교

jmeter 에서 위의 설정과 가능하면 동일한 조건으로 테스트를 진행해봤습니다. 60초에 걸쳐 100개의 가상 사용자를 생성하고 30초의 Ramp-Up 기간을 줬습니다. 커넥션 및 응답 타임 아웃은 5초로 각각 지정했습니다.


위의 조건으로 테스트 진행 시 아래와 같이 결과가 나타났습니다. ngrinder를 통해 부하 테스트했을 때와 동일하게 초당 약 20의 트랜잭션을 처리하는 것을 확인할 수 있습니다. Summary Report 에서 보여지는 Troughput(처리량=TPS)도 20.9/sec 을 확인할 수 있습니다. 에러율의 경우에도 약 1%로 nginder 에서의 에러율과 거의 같습니다.(에러 수(10) / 총 테스트 수(954) = 약 1%)


6. 결론

위에서 테스트한 것과 같이 동일 대상에 대해 동일한 조건으로 테스트를 진행하는 경우 거의 유사한 결과가 나타나는 것을 확인할 수 있습니다. 어떤 도구로 부하 테스트를 진행할지는 개인의 취향이지만 간단하게나마 사용해본 느낌으로는 ngrinder는 네이버에서 만들었기 때문에, 한국어 지원이 되는 점과 한국어 커뮤니티가 있어 한국어로 된 정보 검색이 용이한 점, 부하 테스트를 위한 설정 및 결과가 심플하게 보여지는 점이 장점으로 보이며, jmeter의 경우 apache 프로젝트의 일부로, 웹 부하 테스트 도구 중 가장 널리 쓰이기 때문에 인터넷을 통한 정보 검색이 용이한 점, 추가적인 플러그인 설정을 통해 결과를 원하는 방식(그래프, 테이블, 요약)으로 다양하게 표현하고 가공할 수 있는 점이 장점으로 보입니다.

7. (추가) ngrinder를 이용하여 추가 테스트 진행

동일한 tomcat 서버에 대해 여러 서버 설정(Max Threads) 및 소스(DB 쿼리 유무 및 쿼리의 양), 부하 테스트 조건(가상 사용자 수, Ramp-Up 기간)을 달리하여 17회의 추가 테스트를 진행하였습니다. 특정 조건을 달리하였을 때에 해당 조건이 결과에 미치는 정도를 어느정도 가늠해보고자 여러 조건으로 테스트를 진행해봤습니다.

테스트 간 동일 조건

테스트에 사용한 tomcat 서버 스펙(1vCPU, 1GB Mem), tomcat 메모리 관련 옵션, 부하 생성기의 스펙(2vCPU, 4GB Mem), RDS의 스펙(2vCPU, 2GB Mem)

테스트 간 다른 조건

1) 페이지 DB 연동 여부

부하 테스트를 진행할 페이지가 DB를 연동하고 있는지, 아닌지 등의 조건입니다. 톰캣 기본 페이지(DB 연동 X)와 DB를 연동하여 SELECT 결과를 표로 출력하는 페이지(DB 연동 O), SELECT 쿼리는 하되, 레코드를 출력하지는 않는 페이지(DB 연동 O, 출력 간소화)로 구성하였습니다.

-> DB의 연동 여부는 TPS(초당 트랜잭션 수)에 큰 영향을 미치는 것을 확인했습니다.(DB를 연동하는 경우 TPS 감소, 테스트 결과 1번/14번 비교)


또한 DB로부터 받아온 쿼리의 결과를 while 문을 통해 반복하여 테이블로 표시하는데, 쿼리의 결과를 받아오기만 하고 테이블로 표시하지 않도록 하는 경우에도 TPS의 변화가 어느정도 나타났습니다.(테스트 결과 5번/16번 비교)



2) 쿼리 결과 레코드 수

DB를 연동한 페이지의 경우 전체 약 12,000개의 레코드 중 결과로 표시한 레코드의 수를 달리하였습니다.

-> DB로부터 쿼리의 결과로 받아오는 레코드의 수는 TPS에 많은 영향을 미치는 것을 확인하였습니다.(결과로 받아오는 레코드 수가 많을수록 TPS 감소, 테스트 결과 1~4 비교)



3) DB 호스트 위치

MySQL 서버가 실행되는 위치입니다. 톰캣 서버와 동일 호스트에서 동작하도록 하거나, 혹은 RDS를 통해 톰캣 서버와 분리하였습니다.

-> RDS를 통해 톰캣 서버와 DB를 분리하였을 때에 약 10%정도의 TPS 향상이 있었으나, 이 부분은 네트워크 성능 및 RDS 스펙, RDS의 스토리지 타입에 따라 달라질 것으로 예상됩니다.(테스트 결과 1번/5번 비교)

4) Tomcat Max Theads

톰캣의 최대 쓰레드 수를 기본 값인 200으로 설정하였을 때와 500으로 늘렸을 때를 비교하였는데, 쓰레드를 늘렸을 때에 오히려 TPS가 감소하는 결과를 보였습니다. 테스트 구성에서 TPS에 영향을 주는 요소가 톰캣 최대 쓰레드 수 보다는 DB 쿼리의 영향을 크게 받은 것으로 생각됩니다.(테스트 결과 6번/10번 비교)

5) 가상 사용자 수

ngrinder 부하 테스트 시 사용되는 가상 사용자 수 설정입니다. 가상 사용자 수는 TPS에 큰 영향을 주진 않았지만, 톰캣 서버의 처리량의 한계보다 유입되는 요청이 너무 많은 경우 에러 응답 수가 증가하였습니다.(테스트 결과 6번~8번 비교)

6) Ramp-Up 기간

설정한 가상 사용자 수에 도달하기 위해 점진적으로 가상 사용자 수를 늘리는 기간으로 Ramp-Up 기간과 TPS의 큰 관계는 없는 것으로 보입니다. 다만, Ramp-Up 기간을 짧게 설정하면 그만큼 서버의 최대 처리량에 빨리 도달하기 때문에 에러 응답 수가 증가하였습니다.(테스트 결과 8번/9번 비교)

전체 테스트 결과

테스트 번호 페이지 DB 연동 여부 쿼리 결과 레코드의 수 DB 호스트 위치 Tomcat Max Theads 가상 사용자 수 Ramp-Up 기간 테스트 기간 TPS(초당 트랜잭션 수) 최고 TPS 에러 응답 수 평균 응답 시간(단위 ms)
1 O 약 12,000개 로컬호스트 200 99 12초 60초 18.6 26.5 5 4,457.62
2 O 1,000개 로컬호스트 200 99 12초 60초 177.4 203.5 27 471.46
3 O 100개 로컬호스트 200 99 12초 60초 585.0 657.5 0 149.57
4 O 10개 로컬호스트 200 99 12초 60초 812.1 870.5 0 108.59
5 O 약 12,000개 RDS(MySQL) 200 99 12초 60초 20.1 34.5 23 4,081.55
6 O 10개 RDS(MySQL) 200 99 12초 60초 1,124.4 1,253.5 0 77.86
7 O 10개 RDS(MySQL) 200 10 6초 60초 1,196.1 1,451.0 0 7.83
8 O 10개 RDS(MySQL) 200 500 35초 60초 1,149.3 1,558.5 219 221.27
9 O 10개 RDS(MySQL) 200 500 6초 60초 1,133.0 1,388.0 291 366.93
10 O 10개 RDS(MySQL) 500 99 12초 60초 1,032.5 1,242.5 0 82.22
11 O 10개 RDS(MySQL) 500 500 35초 60초 1,094.6 1,348.0 169 243.04
12 X(tomcat 기본 페이지) 500 99 12초 60초 1,759.5 2,308.5 0 48.27
13 X(tomcat 기본 페이지) 500 500 35초 60초 1,876.0 2,552.5 0 162.32
14 X(tomcat 기본 페이지) 200 99 12초 60초 1,965.0 2,542.5 0 44.53
15 X(tomcat 기본 페이지) 200 500 6초 60초 1,777.0 2,325.0 0 265.77
16 O(출력을 간소화) 약 12,000개 RDS(MySQL) 200 99 12초 60초 141.6 157.5 0 566.85
17 O(출력을 간소화) 10개 RDS(MySQL) 200 99 12초 60초 1,363.8 1,543.0 0 64.59

테스트 결과를 통해 알 수 있었던 점

위의 테스트를 통해 현재 테스트 구성에서 웹 소스(RDS에서 수행되는 쿼리, RDS에서 받아온 결과를 어떻게 출력할 지)가 TPS에 큰 영향을 미치는 것을 확인했습니다. (DB에서 병목 현상이 발생하는 것으로 보임) 또한 어느정도 WAS + RDS 가 처리할 수 있는 TPS의 한계(테스트 구성에서는 1,000~1,200)에 다다르면 다른 조건들에 변화를 주더라도 크게 수치가 변화하지는 않는 것을 확인하였습니다.