개요

 

Delfood의 0.1버전을 배포하였습니다. 제가 만든 프로젝트가 실제로 트래픽을 받았을 때 어느정도의 퍼포먼스를 보여주는지 측정해보기로 했습니다.

 

사용한 부하 발생기는 Ngrinder입니다. 정석 대로라면 직접 Tomcat에 설치하고 각종 환경을 세팅해야 하지만 보다 간편하게 만들어져 있는 Docker 이미지를 받아 사용하였습니다.

 

Ngrinder의 부하 발생 구조

Ngrinder는 크게 Controller, Agent 두 가지로 구성되어 있습니다. 실제 트래픽은 Agent에서 발생시키고 그 Agent를 Controller에서 관리합니다. 그림으로 보면 다음과 같이 볼 수 있겠네요.

 

 

스크립트 작성 과정

Ngrinder에서 부하를 발생시키기 위해서는 Groovy Script 작성이 필요합니다. 회원과 관련된 간단한 스크립트를 다음과 같이 작성하였습니다.

 

package org.ngrinder;

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 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
	
	// Provide a method to convert map to NVPair array 
	def nvs(def map) {
		def nvs = []
		map.each {
			key, value ->  nvs.add(new NVPair(key, value))
		}
		return nvs as NVPair[]
	}

	@BeforeProcess
	public static void beforeProcess() {
		HTTPPluginControl.getConnectionDefaults().timeout = 6000
		test = new GTest(1, "49.50.164.160")
		request = new HTTPRequest()
		test.record(request);
		grinder.logger.info("before process.");
	}

	@BeforeThread 
	public void beforeThread() {
		HTTPResponse result = request.POST("http://49.50.164.160/members/login", nvs(["id":"yyy9942", "password":"password"]))
		grinder.statistics.delayReports=true;
		grinder.logger.info("before thread.");
	}

	@Test
	public void myInfotest() {
		request.GET("http://49.50.164.160/members/myInfo")
	}
	
	@Test
	public void idDuplicated() {
		request.GET("http://49.50.164.160/members/duplicated/yyy9942")
	}
	
	@Test
	public void categorySearch() {
		request.GET("http://49.50.164.160/categories/");
	}
	
	@Test
	public void searchShopByCategory() {
		request.GET("http://49.50.164.160/categories/available/shops", nvs(["categoryId":"1"]));
	}
}

 

성능 테스트 진행

현제 사용하는 서버가 CPU 1개짜리 Compact급 서버입니다. 사양이 낮다보니 가상 사용자 수가 500명 이상으로 높아지면 오류율이 급격히 늘기 떄문에 가상 사용자를 400명으로 잡았습니다. 테스트 기간은 10분 이상을 잡아야 유의미한 데이터를 얻을 수 있을것이라 생각했습니다.

 

직전에 만들어 둔 스크립트로 테스트를 실행시켰습니다.

 

약 1%대의 오류가 있고 TPS는 80 ~ 160사이를 왔다갔다하고있습니다. 서버 리소스는 아래와 같이 사용중입니다.

 

400명의 유저만으로 CPU가 100% 사용되고있습니다. 이제 이 모니터링 결과를 가지고 JVM의 옵션을 변경해가며 어떻게 변하는지 테스트해봐야겠습니다.

 

+ Recent posts