본문 바로가기

Server

nGrinder - 서버 부하 테스트 :: DANIDANI

이번에는 nGrinder를 이용하여 서버 부하 테스트를 진행해보겠습니다.

서버는 AWS ec2 t2.medium을 사용했고 docker를 이용하였습니다.

가상 유저 수를 늘려가며 테스트를 했습니다.


what is nGrinder?

  • 네이버에서 The Grinder 오픈소스에 기반하여 자바로 개발한 성능 측정 오픈소스

nGrinder Architecture

Controller

  • 부하 테스트를 위한 GUI 제공
  • 부하 테스트 모니터링

Agent

  • 부하를 발생시키는 대상
  • Controller의 명령을 받아 부하 발생

Target Server

  • 테스트할 대상 서버

Controller 실행 방법

  1. tomcat을 이용
  2. 직접 실행
  3. docker에 설치

이번 예제에서는 3번인 docker에 설치하여 진행하겠습니다.

서버 사양

AWS ec2 t2.medium를 사용하였습니다.

   vCPU: 1

   시간당 CPU 크레딧: 24

   메모리: 4GiB

 


Docker에서 nGrinder 사용하기

도커가 설치되어 있다고 가정 후 진행합니다.

controller 설치

docker pull ngrinder/controller:3.5.3

ngrinder controller 3.5.3 버전 이미지를 내려받습니다.

controller 컨테이너 생성 후 실행

docker run -d -v ~/ngrinder-controller:/opt/ngrinder-controller -p 8080:80 -p 16001:16001 -p 12000-12009:12000-12009 ngrinder/controller:3.5.3

컨테이너 생성 후 백그라운드로 접속을 합니다.

접속 포트는 8080으로 설정했습니다.

agent 설치

docker pull ngrinder/agent:3.5.3

agent 컨테이너 생성

docker run -v ~/ngrinder-agent:/opt/ngrinder-agent -d ngrinder/agent:3.5.3 (ip 주소):8080

실행 중인 컨테이너 확인

docker ps

 


nGrinder 접속

(ip 주소):8080

 

3.35.93.103:8080

초기 아이디: admin

초기 비밀번호: admin

agent 확인

nGrinder - 에이전트 관리

에이전트 하나가 생성되어 있는 것을 확인할 수 있습니다.

nGrinder 시작하기

 

홈 화면에서 테스트하고자 하는 타겟 서버의 주소를 적어준 후 스크립트 타입을 선택하고 테스트 시작 버튼을 누릅니다.

테스트 설정

 

에이전트별 가상 사용자(vuser)동시에 접속하는 가상 사용자의 숫자입니다.

vuser = agent x process x thread

 

[ vuser 변화에 따른 테스트 결과 ]

(1) vuser = 2000

(2) vuser = 3000

(3) vuser = 4000

 

vuser 커질수록 에러율도 커집니다.

5000은 에러 30%를 넘어서 실행이 안되고 꺼졌습니다.

TPS: 초당 트랜잭션의 수(HTTP request가 성공할 때마다 트랜잭션 수 1씩 증가) , 초당 처리 수


NodeJS API에 test

vuser 1000으로 설정하고 실행했더니 실시간 로그에서 계속 http 통신이 이뤄지는 것을 확인했습니다.

 

에러가 0% 인 것을 보면 이 서버에서 이 api에 대하여 유저 1000명은 가능하다는 것을 예상할 수 있습니다.

AWS ec2 t2.medium에서 수행한 후 모니터링을 해보았더니 CPU 사용률이 60%까지 올라간 것을 볼 수 있었습니다.


로그 확인

Controller에 실행한 서버에 로그가 남습니다.

${user.home}/.ngrinder/perftest

실행 스크립트 - 자동 생성됨(아래는 예제)

import static net.grinder.script.Grinder.grinder
import static org.junit.Assert.*
import static org.hamcrest.Matchers.*
import net.grinder.plugin.http.HTTPRequest
import net.grinder.plugin.http.HTTPPluginControl
import net.grinder.script.GTest
import net.grinder.script.Grinder
import net.grinder.scriptengine.groovy.junit.GrinderRunner
import net.grinder.scriptengine.groovy.junit.annotation.BeforeProcess
import net.grinder.scriptengine.groovy.junit.annotation.BeforeThread
// import static net.grinder.util.GrinderUtils.* // You can use this if you're using nGrinder after 3.2.3
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith

import java.util.Date
import java.util.List
import java.util.ArrayList

import HTTPClient.Cookie
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 admin
 */
@RunWith(GrinderRunner)
class TestRunner {

	public static GTest test
	public static HTTPRequest request
	public static NVPair[] headers = []
	public static NVPair[] params = []
	public static Cookie[] cookies = []

	@BeforeProcess
	public static void beforeProcess() {
		HTTPPluginControl.getConnectionDefaults().timeout = 6000
		test = new GTest(1, "www.google.com")
		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)
		cookies.each { CookieModule.addCookie(it, HTTPPluginControl.getThreadHTTPClientContext()) }
		grinder.logger.info("before. init headers and cookies");
	}

	@Test
	public void test(){
		HTTPResponse result = request.GET("http://www.google.com", params)

		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));
		}
	}
}

 

참고

naver/ngrinder

[nGrinder]nGrinder란? & docker 설치 방법

 

728x90