1. nGrinder
nGrinder는 네이버에서 제공하는 서버 부하 테스트 오픈 소스 프로젝트이다.
애플리케이션을 개발하고 nGrinder에서 여러가지 가상 시나리오를 만들어 트래픽에 몰렸을 때 성능을 측정할 수 있도록 도와준다.
2. 구조
- Controller : 사용자가 테스트 수행을 위한 스크립트를 생성하여 성능 측정을 위한 웹 인터페이스를 제공하며 테스트 결과를 수집해 통계를 보여준다.
- Agent : Controller의 명령을 받아 작업을 수행하며 프로세스 및 스레드를 실행시켜 타겟이 되는 애플리케이션에 부하를 발생시킨다.
3. 설치방법
Docker APP을 통해 nGrinder를 쉽게 설치할 수 있다.
Docker없이 GitHub에서 Controller와 Agent를 다운받아 실행할 수도 있다.
https://github.com/naver/ngrinder
Controller 설치
Docker 설치 후 터미널에서 아래 명령어를 통해 Controller를 설치 및 실행할 수 있다.
$ docker pull ngrinder/controller
$ docker run -d -v ~/ngrinder-controller:/opt/ngrinder-controller --name controller \
-p 80:80 -p 16001:16001 -p 12000-12009:12000-12009 ngrinder/controller
- 80 : Controller 웹 UI 포트
- 9010-9019 : Agent를 Controller에 붙도록 해주는 연결 포트
- 12000-12029 : Controller가 스트레스 테스트에 할당하는 포트
Controller를 실행시키며 필요한 포트 및 볼륨 마운팅을 지정한다. Controller 실행을 위해 위 port번호는 열어놓아야한다.
Agent 설치
docker pull ngrinder/agent
docker run -d --name agent --link controller:controller ngrinder/agent
4. nGrinder 웹페이지
Controller와 Agent 실행을 마쳤으면 아래 주소를 통해 nGrinder 웹페이지 접속이 가능하다.
- 주소 : http://localhost:80
- 아이디 : admin
- 패스워드 : admin
nGrinder 웹페이지에 로그인을 완료하면 위 화면이 보일 것 이다.
페이지 상단에 Performance Test, Script 2개의 메뉴가 있다.
Perfomance Test는 애플리케이션을 테스트하고 그 결과에 대해 조회할 수 있는 메뉴이고, Script는 Perfomance Test를 하기 전 어떻게 테스트할 것인가를 작성하는 Script이다.
Performance Test
위 페이지는 Perfomance Test를 생성할 수 있는 페이지이다.
- 테스트명 : 해당 테스트를 지정하는 이름
- Agent : 테스트에 사용할 Agent 갯수 지정. 현재 max가 1개 이지만 위 Docker를 통해 Agent를 생성하는 과정을 통해 갯수를 늘릴 수 있음
- Vuser per agent : Agent 별 Vuser의 수, 테스트할 사용자의 수
- Script : 테스트할 Script
- Duration : 테스트를 수행하는 시간
- Ramp-Up : 조금씩 사용자를 늘려나갈 때 사용
- 늘어나는 사용자의 숫자를 프로세스이기 때문에 Ramp-Up 기능을 사용하려면 프로세스 숫자가 높아야 한다.
- x축: 시간흐름, y축: 동시접속자
- ex) 초기 대기시간:2, Ramp-Up 주기: 2000 -> 즉, 2초마다 2개의 프로세스가 생성
- Initial Count : 초기 Process/Thread 수
- Increment Step : Process/Thread를 몇 개씩 증가시킬 건지
- Intial Sleep Time : 초기 대기 시간
- Interval : 얼마 주기로 증가시킬 건지
Script
테스트에 사용할 스크립트를 작성해보자.
스크립트는 Groovy, Jython으로 작성할 수 있다. Groovy는 자바와 유사하고 Jython은 파이썬과 유사하다.
스크립트 유형을 선택 후 파일을 생성하면 편리하게도 Sample Code가 작성되어 있다. 테스트할 API, Request Header, Request Body 등을 스크립트에서 설정할 수 있다.
import static net.grinder.script.Grinder.grinder
import static org.junit.Assert.*
import static org.hamcrest.Matchers.*
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 org.ngrinder.http.HTTPRequest
import org.ngrinder.http.HTTPRequestControl
import org.ngrinder.http.HTTPResponse
import org.ngrinder.http.cookie.Cookie
import org.ngrinder.http.cookie.CookieManager
/**
* 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 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, "Test1")
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("https://url", 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))
}
}
}
5. nGrinder 부하테스트 실행
테스트 시나리오
- Agent : 1대
- 테스트 유저 : 2,500
- 테스트 시간 : 3분
- Ramp-Up : 처음에는 테스트유저가 적은 상태에서 테스트시간 종료에 이를 수록 유저가 증가함. (1초마다 테스트 유저 증가)
6. nGrinder 부하테스트 결과
Report를 통해 상세 내용 및 로그를 확인할 수 있다.
- TPS : 초당 트랜잭션 완료 수, 처리량이 높을수록 좋음
- Mean Test Time : 평균 response time
테스트 수행 시 Assertion 검증이 실패하게 될 경우 에러로 잡히게 되는데, 에러가 너무 많이 발생하면 자동으로 테스트가 중단된다.
'Web Programming' 카테고리의 다른 글
백엔드 개발자 기술 질문 리스트 - Spring Framework (0) | 2023.03.01 |
---|---|
구글 로그인 쉽게 구현하기 3편 - 로그인 구현하기 (SpringBoot + Vue.js) (2) | 2023.01.24 |
구글 로그인 쉽게 구현하기 2편 - 개발 환경 설정 (0) | 2023.01.24 |
구글로그인 쉽게 구현하기 1편 - Google Developers 설정 (2) | 2023.01.24 |
네이버 로그인 쉽게 구현하기 3편 - 로그인 구현하기 (SpringBoot + Vue.js) (2) | 2023.01.22 |