ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • nGrinder란? (설치 및 부하 테스트)
    성능테스트 2023. 1. 8. 00:01
    728x90

    [1] nGrinder vs Jmeter

    [2] nGrinder란? (설치 및 부하 테스트)

     

    개요

    이전 포스팅에서는 nGrinder와 Jmeter에 대해 비교해보고 nGrinder를 사용하고자 했습니다.

    nGrinder가 무엇인지 조금 더 상세하게 알아보고 실제로 설치 및 부하 테스트를 진행해보겠습니다.

     

    nGrinder란?

    네이버에서 진행한 오픈 소스 프로젝트로 서버의 부하 테스트를 위한 도구입니다.

     

    nGrinder는 어떻게 동작하는가?

    그림 1

    nGriner는 2가지의 중요한 컴포넌트인 Controller와 agent로 구성되어 있습니다.

     

     

    nGrinder Controller

    - 성능 테스터가 테스트 스크립트를 생성하고 테스트 실행을 구성할 수 있도록 하는 웹 애플리케이션

     

    Agent

    - 대상 시스템에 부하를 주는 가상 사용자 생성기

     

    Target

    - 부하 테스트의 대상이 될 서버

     

     

    nGrinder 설치

    우선 자바 설치가 먼저 되어있어야 합니다.

     

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

     

    Releases · naver/ngrinder

    enterprise level performance testing solution. Contribute to naver/ngrinder development by creating an account on GitHub.

    github.com

    그림 2

    [그림 2 ]참고 - 링크로 접속한 후 가장 최신 버전인 war 파일을 다운로드합니다 

     

    nGrinder 실행

    다운받은 경로로 이동하여 아래 명령어를 실행시킵니다.

    8080 포트는 Spring Boot Application을 띄우기 위해 다른 포트를 사용하도록 하겠습니다. (여기서는 80 포트 활용)

    *만약 여러 자바 버전을 가지고 계시다면 유의하시길 바랍니다. (하단에 디버깅 과정 나옴)

    java -XX:MaxPermSize=200m -jar  ngrinder-controller-3.5.7.war --port 80

    nGrinder는 SVNKit, mave, Jetty 서버, groovy, python 등의 라이브러리를 포함하고 있기 때문에 큰 PermGen 메모리를 필요로 합니다.

     

    (문서에서는 옵션을 주지 않으면 에러가 난다고 하는데 사실 저는 에러가 나진 않았습니다)

     

    따라서 해당 옵션을 줍니다.

    -XX:MaxPermSize=200m

     

    nGrinder 실행시 java.io.tmpdir 에러 처리

    ERROR
    Please set `java.io.tmpdir` property like following. tmpdir should be different from the OS default tmpdir.
    `java -Djava.io.tmpdir=${NGRINDER_HOME}/lib -jar ngrinder-controller.war`

    http://ngrinder.373.s1.nabble.com/controller-td3268.html

     

    java -Djava.io.tmpdir=/Users/junuu/.ngrinder/lib -jar ngrinder-controller-3.5.8.war --port 7777

    -Djava.io.tmpdir=/Users/{사용자마다 다른 user}/.ngrinder/lib 를 주어 해결하였습니다.

     

    nGrinder 접속과 Agent 다운로드

    localhost:80 포트에 접속합니다. (위에서 옵션으로 80포트를 주었기 때문 그렇지 않다면 기본값은 8080)

    그림 3

    접속하면 [그림 3] 처럼 페이지가 보이며 초기 아이디와 비밀번호는 admin/admin입니다.

     

    그림 4

    로그인 후 [그림 4]처럼 페이지가 보이며 우측 상단의 에이전트 다운로드를 선택합니다.

     

    agent jar 파일을 다운로드 후, 압축을 풀고 다운된 경로로 이동하여 실행시켜 줍니다.

    ./run_agent.sh

    window에서는 이렇게 하면 됩니다.

    run_agent.bat

     

    실행 후 결과

    그림 5

    스크립트 만들기

    그림 6

    상단 내비게이션에서 스크립트로 이동한 후 만들기 -> 스크립트 만들기

    그림 7

    이후 [그림 7]에 스크립트명과 http 메서드, url을 입력해줍니다.

    스크립트명 : Grinder-test

    테스트할 URL(GET) : http://127.0.0.1:8080/stress-test

     

     

    @RestController
    @RequestMapping("/stress-test")
    class NGrinderTestController {
    
        @GetMapping
        fun helloNGrinder(): String{
            return "hello"
        }
    }

    저는 위의 코드처럼 저는 간단하게 "hello"를 반환하는 메서드를 만들어서 테스트해보겠습니다.

     

    이후 만들기를 누르면 다음과 같은 코드가 보입니다.

    @RunWith(GrinderRunner)
    class TestRunner {
    
    	public static GTest test
    	public static HTTPRequest request
    	public static Map<String, String> headers = [:]
    	public static Map<String, Object> params = [:]
    	public static List<Cookie> cookies = []
    
    	@BeforeProcess
    	public static void beforeProcess() {
    		HTTPRequestControl.setConnectionTimeout(300000)
    		test = new GTest(1, "127.0.0.1")
    		request = new HTTPRequest()
    		grinder.logger.info("before process.")
    	}
    
    	@BeforeThread
    	public void beforeThread() {
    		test.record(this, "test")
    		grinder.statistics.delayReports = true
    		grinder.logger.info("before thread.")
    	}
    
    	@Before
    	public void before() {
    		request.setHeaders(headers)
    		CookieManager.addCookies(cookies)
    		grinder.logger.info("before. init headers and cookies")
    	}
    
    	@Test
    	public void test() {
    		HTTPResponse response = request.GET("http://127.0.0.1:8080/stress-test", params)
    
    		if (response.statusCode == 301 || response.statusCode == 302) {
    			grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", response.statusCode)
    		} else {
    			assertThat(response.statusCode, is(200))
    		}
    	}
    }

    만약 POST 요청을 보내고 싶다면 request.POST로 변경하고 이에 적절한 params을 넣어주면 됩니다.

     

    수정한 부분적 예시

    public static Map<String, Object> params = ["memberId": "string", "eventName": "eventName1"]
    headers.put("Content-Type", "application/json")
    HTTPResponse response = request.POST("http://127.0.0.1:8080/coupons/event", params)

     

     

    웹 화면에서는 검증을 눌러서 Groovy로 작성한 테스트 코드를 실행시키며, 테스트 결과 요청이 정상적으로 날아갔는지 확인해줍니다.

    그림 8

    저는 [그림 8]처럼 무한 검증중이 떠서 그냥 저장하기 눌렀습니다.

    * 이때 nGrinder Controller에서 Enter를 치니까 바로 진행되었습니다.

     

    다음과 같은 에러들이 나타납니다.

    net.grinder.engine.common.EngineException: Error while initialize test runner
    
    General error during conversion: Unsupported class file major version 60
    
    java.lang.IllegalArgumentException: Unsupported class file major version 60
    

    PC에 설치된 JDK는 11 버전인데 빌드 패스의 기본 JRE설정 및 Java Compiler설정이 JavaSE-16 버전으로 되어있는 게 원인이라고 합니다.

     

    로그 메시지를 보면 16 버전으로 실행되었습니다..

    2022-10-26 23:23:59,605 INFO  OpenJDK Runtime Environment 16.0.2+7-67: OpenJDK 64-Bit Server VM (16.0.2+7-67, mixed mode, sharing) on Windows 10 amd64 10.0

     

    자바버전은 11로 찍히는데 왜 이럴까요?

     

    실제로 실행시키는 경로에서 다시 java -verison을 찍어보니 다음과 같이 나옵니다.

    "C:\Program Files\Java\jdk-9.0.4\bin\java.exe" -jar A.jar

    위와 같이하면 특정 버전의 자바로 실행시킬 수 있습니다.

     

    "C:\Program Files\java\jdk-11.0.15.1\bin\java.exe" -XX:MaxPermSize=200m -jar  ngrinder-controller-3.5.7.war --port 80

    저는 이렇게 실행했습니다.

     

     

    다시 검증을 해보니 이제 잘 됩니다. ㅎㅎ

     

     

    실제 성능 측정 시작

    상단의 메뉴에서 성능 테스트 -> 테스트 생성으로 이동합니다.

     

    그림 9

    [그림 9]과 같은 화면이 나오게 되며 에이전트는 아까 다운로드하였던 최대 1개를 지정합니다. (여러 agent 지정하면 여러 개도 가능합니다)

    일단 가상 사용자를 10명으로 설정해보고 스크립트는 아까 지정한 nGrinder-hello.groovy를 불러옵니다.

    이제 저장 후 시작 -> 지금 시작을 눌러줍니다.

     

    그림 10

    이제 [그림 10]처럼 테스트가 하나 생성되고 "1명의 사용자가 테스트를 실행 중에 있습니다."라는 메시지가 보입니다.

     

    그림 11

    [그림 11]은 결과로 1분 동안의 요청에서 TPS는 4,841, MTT는 1.9가 나왔음을 알려줍니다.

     

    TPS(Transaction Per Second) : 초당 처리량 높을수록 좋음

    Mean Test Time : 평균 response time(ms 단위)

     

    그림 12

    이후 100명 Ramp-Up, 3000명 10초 No Ramp-Up 등 다양하게 시도해보았습니다.

    단순한 "hello"를 반환하는 GET 요청이어서 많은 트래픽을 300ms이내에 처리할 수 있는 모습입니다.

     

    마무리

    실제로 성능 테스트를 해보기 전까지는 많이 어려울 것 같다고 예상하였지만, 생각보다 가이드가 좋고 툴이 친절하여 편하게 진행하였습니다.

     

     

     

    참고자료

    https://naver.github.io/ngrinder/

     

    nGrinder

    Please post questions in Discussions not Issues. nGrinder 3.5.5-p1 version is now available. Check the changes at here. nGrinder is a platform for stress tests that enables you to execute script creation, test execution, monitoring, and result report gener

    naver.github.io

    https://github.com/naver/ngrinder/wiki/Installation-Guide

     

    GitHub - naver/ngrinder: enterprise level performance testing solution

    enterprise level performance testing solution. Contribute to naver/ngrinder development by creating an account on GitHub.

    github.com

    https://chinsun9.github.io/2021/03/24/%ED%8A%B9%EC%A0%95-%EC%9E%90%EB%B0%94-%EB%B2%84%EC%A0%84%EC%9C%BC%EB%A1%9C-%EC%8B%A4%ED%96%89/

     

    특정 자바 버전으로 jar 실행

    상황 기존에 사용하던 A.jar 실행파일이 있다 자바 버전을 바꿨다 환경변수 변화로 인해 A.jar이 더 이상 동작하지 않는다 이 실행파일만 기존 자바 버전으로 실행할 수 없을까? 또는 A.jar은 jdk9에

    chinsun9.github.io

     

    댓글

Designed by Tistory.