-
Grinder : 로드(성능, 부하) 테스팅 도구웹개발 2014. 3. 27. 09:00
여러대의 장비를 이용해서 서버의 로드를 테스팅할수 있는 도구.
http://grinder.sourceforge.net/
기본 구조.
Console, Agent, Worker로 구성되어 있음.
Console이 메인 서버로 Agent들에 명령을 내리고
각 Agent들이 개별 장비에 설치되어 실행되고 있다가 Console로 부터 명령을 받아서 테스트를 실행함.
Agent가 Worker를 생성해서 테스트를 수행함.
테스트 방법은 지정된 Jython 스크립트를 이용해서 수행.
여러개의 테스트를 수행할때 각 테스트 케이스에 가중치를 줄 수 있음.
Grinder Console실행java -cp ./grinder-3.11/lib/grinder.jar net.grinder.Console
Grinder Agent 실행
ava -cp ./grinder-3.11/lib/grinder.jar net.grinder.Grinder
Agent가 Console에서 명령을 받아서 Grinder Script를 실행해서 테스트를 진행함.
Console에 연결할 수 없으면 Agent가 로컬에 있는 테스트 설정을 이용해서 테스트 수행
스크립트
1. 스크립트는 TestRunner 클래스를 정의해야 함.
2. TestRunner 인스턴스는 호출가능해야 함.
__call__ 메소드를 정의해야 함.
3. 테스트 스크립트는 grinder 객체를 통해 서비스에 접근할 수 있어야 함.
4. 스크립트 파일의 이름은 마지막이 .py로 끝나야 함.
기본 스크립트 구조.
from net.grinder.script import Test from net.grinder.script.Grinder import grinder test1 = Test(1, "Log method") # Instrument the info() method with our Test. test1.record(grinder.logger.info) class TestRunner: def __call__(self): grinder.logger.info("Hello World")
URL 테스트용 스크립트(sampletest.py). 테스트 케이스별로 가중치를 줄 수 있음.
#coding=UTF-8 import string import random from java.lang import String from java.net import URLEncoder import java.lang.System, java.util.Random from net.grinder.script import Test from net.grinder.script.Grinder import grinder from net.grinder.plugin.http import HTTPRequest from HTTPClient import NVPair from net.grinder.common import GrinderException from random import choice test01 = 'CREATE' test02 = 'READ' test03 = 'UPDATE' test04 = 'DELETE' tests = { test01: Test(1, "Test " + test01), test02: Test(2, "Test " + test02), test03: Test(3, "Test " + test03), test04: Test(4, "Test " + test04), } #가중치 주려는 비율. 합이 100이 되도록 하면 됨. g_Weights = { test01: 20, test02: 40, test03: 30, test04: 10, } SERVER = "http://127.0.0.1:8080" #랜덤 문자열 생성. def randomString(strSize): return (''.join(random.choice(string.ascii_lowercase) for i in range(strSize))) #URL에 요청 보내고 결과치 서버에 보고하기 def send_request(TESTID, SERVER, URI, HEADERS): #Send the request to the server requestString = "%s%s" % (SERVER, URI) grinder.statistics.delayReports = 1 request = HTTPRequest() tests[TESTID].record(request) request.setHeaders(HEADERS) result = request.GET(requestString) if result.getStatusCode() == 200: #log("StatusCode : %s " % result.getStatusCode()) grinder.statistics.forLastTest.setSuccess(1) else: #log("StatusCode : %s " % result.getStatusCode()) grinder.statistics.forLastTest.setSuccess(0) #테스트를 진행하는 함수들 def doTest01(): send_request(test01, SERVER, '/test01’, [NVPair("", "")]) def doTest02(): send_request(test02, SERVER, '/test02’, [NVPair("", "")]) def doTest03(): send_request(test03, SERVER, '/test03', [NVPair("", "")]) def doTest04(): send_request(test04, SERVER, '/test04', [NVPair("", "")]) # 지정된 가중치 생성 def weightAccumulator(i_dict): keyList = i_dict.keys() keyList.sort() # sorting is optional - order coming-in doesn't matter, but determinism is kinda cool listAcc = [] weightAcc = 0 for key in keyList: weightAcc += i_dict[key] listAcc.append((key, weightAcc)) return (listAcc, weightAcc) # order going-out does matter - hence "listAcc" instead of "dictAcc" g_WeightsAcc, g_WeightsAccMax = weightAccumulator(g_Weights) g_WeightsAccLen, g_WeightsAccMax_1 = len(g_WeightsAcc), g_WeightsAccMax-1 g_rng = java.util.Random(java.lang.System.currentTimeMillis()) #주어진 min, max 사이에서 random 숫자 만들기 def randNum(i_min, i_max): assert i_min <= i_max range = i_max - i_min + 1 # re-purposing "range" is legal in Python assert range <= 0x7fffffff # because we're using java.util.Random randnum = i_min + g_rng.nextInt(range) assert i_min <= randnum <= i_max return randnum log = grinder.logger.info # out = grinder.logger.TERMINAL class TestRunner: def __call__(self): opNum = randNum(0, g_WeightsAccMax_1) opType = None for i in range(g_WeightsAccLen): if opNum < g_WeightsAcc[i][1]: opType = g_WeightsAcc[i][0] break assert opType in g_Weights.keys() if opType==test01: doTest01() elif opType==test02: doTest02() elif opType==test03: doTest03() elif opType==test04: doTest04() else: assert False
Grinder 결과 그래프로 보기
Grinder Analyzer 이용
http://track.sourceforge.net/
jython을 이용하고 jython버전은 2.2.1, 2.5.0, 2.5.1, 2.5.2을 지원함.
실행
jython ./analyzer.py "
" [number of agents]
grinderReport에 결과 파일 생성됨.
'웹개발' 카테고리의 다른 글
nginx에 basic auth 설정 (0) 2014.02.19 yeoman 설치 및 실행 (0) 2014.02.12 OSX에 Nginx 설치 (0) 2013.12.23 댓글