실행하기 앞서 성능 테스트용 nGrinder를 설치하는 작업을 거쳤었다. 그 과정을 간략하게 정리해보면

  1. 성능 테스트용 서버 생성
  2. nGrinder 설치
  3. nGrinder 및 에이전트 실행
    으로 나눌 수 있다. 이제 성능 테스트를 진행하기 위해 후속 작업을 차근차근 진행해보자.

nGrinder 구조

nGrinder상 시스템 아키텍처는 크게 세가지로 구성이 되어 있다.

  • Controller : 성능테스트를 위한 웹 인터페이스를 제공하며, 테스트 프로세스를 제공한다. 앞서 맨처음에 설치하고 실행했던 nGrinder 프로그램이라고 볼 수 있다.
  • Agent : Controller에서 셋팅한 값을 토대로 실제로 부하를 주는 역할을 한다. 테스트 스크립트를 실행하여 실제 타겟 서버에 부하를 준다.
  • Target Server : 테스트 대상이 될 서버이다. 실제 개발 혹은 운영중인 서버라고 이해하면 될 것 같다.

성능 테스트 스크립트 작성

스크린샷 2021-08-13 오전 9 44 47

nGrinder에 접속 한 후 위 상단의 Script 메뉴를 통해 부하테스트를 실행할 스크립트를 관리할 수 있다.
스크립트는 Groovy, Jython, Groovy Gradle Project와 같은 형식으로 작성해야 하며, 필자의 경우 Groovy로 작성하였다.

스크립트 작성 법은 다른 포스트를 통해 추가로 설명할 예정이며, 필자는 아래와 같이 작성하였다.

import static net.grinder.script.Grinder.grinder
import static org.hamcrest.Matchers.*
import static org.junit.Assert.*
import net.grinder.plugin.http.HTTPPluginControl
import net.grinder.plugin.http.HTTPRequest
import net.grinder.script.GTest
import net.grinder.scriptengine.groovy.junit.GrinderRunner
import net.grinder.scriptengine.groovy.junit.annotation.BeforeProcess
import net.grinder.scriptengine.groovy.junit.annotation.BeforeThread
 
import org.junit.After
import org.junit.Before;
import org.junit.Test
import org.junit.runner.RunWith
 
import HTTPClient.CookieModule
import HTTPClient.HTTPResponse
import HTTPClient.NVPair
 
/**
 * A simple example using the HTTP plugin that shows the retrieval of a
 * single page via HTTP. 
 * 
 * This script is automatically generated by ngrinder.
 * 
 * @author Gisoo Gwon
 */
@RunWith(GrinderRunner)
class TestRunnser {
    public static GTest test
    public static HTTPRequest request
    public Object cookies = []
 
    @BeforeProcess
    public static void beforeProcess() {
        HTTPPluginControl.getConnectionDefaults().timeout = 6000;
        test = new GTest(1, "login test");
        request = new HTTPRequest();
        test.record(request);
        grinder.logger.info("before process started.");
    }
 
    @BeforeThread
    public void beforeThread() {
        grinder.statistics.delayReports=true;
        grinder.logger.info("before thread started.");

        // reset to the all cookies
        def threadContext = HTTPPluginControl.getThreadHTTPClientContext()
        cookies = CookieModule.listAllCookies(threadContext)
        cookies.each {
            CookieModule.removeCookie(it, threadContext)
        }
         
        // do login & save to the login info in cookies 
        NVPair[] params = [new NVPair("email", "테스트 계정"), new NVPair("password", "테스트 계정 비번")];
        HTTPResponse res = request.POST("로그인 url", params);
        cookies = CookieModule.listAllCookies(threadContext)
    }
 
    @Before
    public void before() {
        // set cookies for login state
        def threadContext = HTTPPluginControl.getThreadHTTPClientContext()
        cookies.each {
            CookieModule.addCookie(it ,threadContext)
            grinder.logger.info("{}", it)
        }
    }
 
    @Test
    public void test(){
        HTTPResponse result = request.GET("테스트 할 url")
 
        if (result.statusCode == 301 || result.statusCode == 302) {
            grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", result.statusCode);
        } else {
            assertThat(result.statusCode, is(200));
        }
    }
}

이렇게 만든 스크립트를 Upload하고 Validate까지 진행하여 오류가 발생하지 않는지 확인하자.

성능 테스트 실행

성능 테스트는 nGrinder 메뉴중에서도 Performance Test를 통해 진행할 수 있다. Create Test 버튼을 클릭하면 아래와 같이 테스트를 위한 셋팅 창이 나온다.

스크린샷 2021-08-13 오전 9 57 01

  • Agent : 실제로 부하를 주는 장비, Agent를 여러 대로 설정할 경우 설정한 개수만큼 사용 가능하다.
  • Vuser per agent : 에이전트별로 서버에 접속하는 가상 유저
  • Script : 부하테스트시 실행할 스크립트를 설정합니다.
  • Target Host : 테스트를 진행할 서버를 셋팅한다.
  • Duration : 어느 기간동안 테스트를 실행할지 셋팅한다. Run Count를 통해 횟수로 지정할 수도 있다.
  • Ramp-Up : 부하를 점차 늘리는 기능이다. process나 thread를 늘리는 방식으로 되어있다.
    • Initial count : 처음 시작할 때의 가상 사용자 수를 셋팅한다.
    • Initial Sleep Time : 테스트를 언제부터 실행시킬지 셋팅한다.
    • Incremental Step : process나 thread를 얼마만큼 증가시킬지 셋팅한다.
    • Interval : 얼만큼의 주기만큼 설정한 항목들을 증가시킬지 셋팅한다.

실질적으로 Agent * Vuser per agent수만큼 부하를 준다고 볼 수 있다.

셋팅을 하고 부하를 주었더니 대략 아래와 같은 결과가 나왔다 :

스크린샷 2021-08-13 오전 10 03 51

  • 평균 TPS : 971
  • 최고 TPS : 1213
  • 평균 조회하는데 걸리는 시간 : 200.38ms
  • 테스트 실행 수 : 52538/52499
  • 에러 : 39

이 테스트는 게시글 조회기능 대상으로 1분동안 부하를 준 결과이다. 다른 케이스에서도 부하 테스트를 해보고 어느정도까지 견딜 수 있는지, 개선방향이 있는지 확인해봐야겠다.



oksusutea's blog

꾸준히 기록하려고 만든 블로그