Introducing
Your new presentation assistant.
Refine, enhance, and tailor your content, source relevant images, and edit visuals quicker than ever before.
Trending searches
nGrinder V.2.1
잦은 릴리즈
많은 플랫폼
nLocation
1.5
Arcus
1.0
nLocation
Arcus
BLOC
3.2
BLOC
OWFS
1.0
OWFS
...
Lucy
1.7
Lucy
nLucene
1.2
nLucene
The Grinder를 이용한 테스트
GRINDERPATH=/Users/kwangsub/Dev/app/grinder-3.4
GRINDERPROPERTIES=$GRINDERPATH/grinder.properties
CLASSPATH=$GRINDERPATH/lib/grinder.jar:$CLASSPATH
PATH=$JAVA_HOME/bin:$PATH
java -Xmx1024m -cp $CLASSPATH net.grinder.Console
GRINDERPATH=/Users/kwangsub/Dev/app/grinder-3.4
GRINDERPROPERTIES=$GRINDERPATH/grinder.properties
CLASSPATH=$GRINDERPATH/lib/grinder.jar:$CLASSPATH
PATH=$JAVA_HOME/bin:$PATH
java -Xmx1024m -cp $CLASSPATH -Dgrinder.hostID="api.agent" net.grinder.Grinder $GRINDERPROPERTIES
CUBRID
8.4
3rd-party
GROUND
GrinderAnalyzer
복사 or 다운로드
CUBRID
USF
3.0
USF
XE 1.5
XE
API G/W
1.2
API G/W
Java 기반 오픈소스
통합, 커스터마이징 용이
지속적인 성능검증
컴포넌트형식 분리
시나리오 테스트
Java Process와 Thread로 VUser생성
while(true) {
target.request();
}
통합테스트셋을 구축하자.
while(true) {
target.request();
}
누가? 어떻게? Request를 만드나?
* 1 Agent의 Worker 수 == Process * Thread
Virtual User 개수 :
* 전체 Agent의 Worker 수 == Process * Thread
Jython스크립트를 이용한 시나리오
쇼핑몰에서 상품을 구매하는 절차
+
테스트 시작!
500 TPS
500 TPS
250 TPS
800 TPS
800 TPS
370 TPS
성능 테스트
코드 수정/빌드때마다 측정해야 하는데...
현실! 플랫폼, 개발자들 보다는 서비스, QA 우선
테스트 측정 도구를 많이 설치해서 Pool을 늘려라!?
request = test.wrap(HTTPRequest(url="http://대박.com"))
class TestRunner:
def __call__(self):
request.GET("/helloworld.jsp")
성능이 떨어지진 않았나?
시나리오테스트를 잘 만족하나?
- http://grinder.sourceforge.net
자주 성능측정할 수 있게
더이상의 Terminal
http://grinder.sourceforge.net/index.html
질문할 수 있는 공간이 있습니다.
http://nhnopensource.org/ngrinder_forum
One more thing
정의
왜
하루 고작 2~3명 접속하는 서비스를 만들고 싶은신가요?
1만명, 1000만명이 월활하게 사용할 수 있는 그런 서비스
http://nhnopensource.org/ngrinder
신나게 상품을 고르고 결제를 하려는데...
예상을 해야하는데...
예상? 잘 안됩니다.
세상엔 변수가 너무 많아요. 이런경우
작년에 오픈할때 평균 나왔어!
아 그래? 나도 그 정도야...?
while(true) {
target.request();
}
우린 개발자!
어떻게?
while(true) {
target.request();
}
CPU 90% ? 100%?
while(true) {
target.request();
}
...
1대로 부족하다?
100 Vuser
500 ms Res. Time
50 TPS
장비 증설,
CPU, 메모리 업그레이드,
병목을 찾든...
https://github.com/nhnopensource
1. Test랩핑, TPS 1 증가방식
1. Test랩핑, TPS 1증가 방식
# _*_ coding: utf8 _*_
from net.grinder.script import Test
from net.grinder.plugin.http import HTTPRequest
from net.grinder.script.Grinder import grinder
test1 = Test(1, "First Test")
wrapper = test1.wrap(HTTPRequest("http://11.22.33.44"))
class TestRunner:
def __call__(self):
url = "/ngrinder/get.nhn?username=kwangsub&password=4321"
result = wrapper.GET(url)
# _*_ coding: utf8 _*_
from net.grinder.script import Test
from net.grinder.plugin.http import HTTPRequest
from net.grinder.script.Grinder import grinder
test1 = Test(1, "First Test")
wrapper = test1.wrap(HTTPRequest("http://11.22.33.44"))
class TestRunner:
def __call__(self):
url = "/ngrinder/get.nhn?username=kwangsub&password=4321"
result = wrapper.GET(url)
grinder.sleep(1000)
print wrapper.GET(url).getText()
2. 간단한 HTTP 호출
2. 간단한 HTTP 호출
# _*_ coding: utf8 _*_
from net.grinder.script import Test
from net.grinder.plugin.http import HTTPRequest
from net.grinder.script.Grinder import grinder
test1 = Test(1, "Dummy GET")
requestGet = test1.wrap(HTTPRequest(url="http://11.22.33.44:8080"))
class TestRunner:
def __init__(self):
print "Init"
def __call__(self):
url = "/ngrinder/get.nhn?username=kwangsub&password=4321"
result = requestGet.GET(url)
grinder.sleep(1000)
# _*_ coding: utf8 _*_
from net.grinder.script import Test
from net.grinder.plugin.http import HTTPRequest
from HTTPClient import NVPair
from net.grinder.script.Grinder import grinder
test = Test(1, "Dummy POST")
requestPost = test.wrap(HTTPRequest(url="http://11.22.33.44:9080"))
class TestRunner:
def __call__(self):
url = "/ngrinder/post.nhn"
params = [NVPair("username", "kwangsub"),
NVPair("password", "4321") ]
result = requestPost.POST(url, params)
앞으로
NHN에서는 얼마나 사용했을까?
3. Random변수 사용, Java API사용
The Grinder기반 성능 측정도구이며 오픈소스
3. HTTPRequest, 성공/실패 분기
# _*_ coding: utf8 _*_
from net.grinder.script import Test
from net.grinder.plugin.http import HTTPRequest
from net.grinder.script.Grinder import grinder
from java.util import Random
test = Test(1, "test")
request = test.wrap(HTTPRequest(url="http://11.22.33.44:8080"))
random = Random()
class TestRunner:
def __call__(self):
params = []
params.append("param1")
params.append("param2")
params.append("param2")
randomInt = random.nextInt(len(params))
grinder.sleep(1000)
request.GET("/ngrinder/index.nhn?param=" + params[randomInt])
from your.java.code import Something
...
test = Test(1, "TEST")
obj1 = test.wrap(Something())
class TestRunner:
def __call__(self):
test.hello()
Jython스크립트를 이용하여 시나리오를 이용
+
JVM상에서 Process와 Thread를 이용해 반복적인 Request를 만듬
4. 1초에 한번씩 호출
2012년 2월 17일
# _*_ coding: utf8 _*_
from net.grinder.script import Test
from net.grinder.plugin.http import HTTPRequest
from net.grinder.script.Grinder import grinder
test1 = Test(1, "Test")
request1 = test1.wrap(HTTPRequest(url="http://11.22.33.44"))
log = grinder.logger.output
class TestRunner:
def __call__(self):
url = "/nhn/performance/1k.xml"
result = request1.GET(url)
last_test_time = grinder.statistics.forLastTest.time
remain = last_test_time % 1000
grinder.sleep(1000 - remain)
Process나 Thread를 늘려가며 RampUp
Duration은 Process가 동작하는 시간
5. HTTPResponse, 성공/실패 분기
5. Random 변수 사용
설정정보와 CPU, Memory등 리소스 정보가 Cubird에 저장
# _*_ coding: utf8 _*_
# WebPlatformTeam
from net.grinder.script import Test
from net.grinder.plugin.http import HTTPRequest
from net.grinder.script.Grinder import grinder
test1 = Test(1, "hello")
url1 = "11.22.33.44"
request1 = test1.wrap(HTTPRequest(url=url1))
log = grinder.logger.output
class TestRunner:
def __call__(self):
grinder.statistics.delayReports = 1
grinder.sleep(1000)
url = "/nhn/performance/1k.xml"
result = request1.GET(url)
if result.statusCode > 200 or result.text == "null" or result.text.find("hello") < 0:
grinder.statistics.forLastTest.success = 0
else:
grinder.statistics.forLastTest.success = 1
카피 설치, 건 테스트
부하를 주는 Agent도 부하를 받을 수 있음
6. Ramp Up
- 점차 부하를 늘려주고 싶을 때
Java Process를 늘리는 방식
from net.grinder.script.Grinder import grinder
from net.grinder.common import Logger
def log(message):
grinder.logger.output(message, Logger.TERMINAL)
class TestRunner:
def initialSleep( self):
sleepTime = grinder.threadNumber * 5000
grinder.sleep(sleepTime, 0)
def __call__( self ):
if grinder.runNumber == 0: self.initialSleep()
grinder.sleep(500)
log("in __call__()")
모든쓰레드를 띄워놓고 sleep()시켰다
시간 지나면 하나하나 깨우는 방식
http://grinder.sourceforge.net/g3/script-gallery.html#threadrampup.py
소스는 열려있습니다.
마음껏 가져다 쓰시고 기여도 많이 해주세요.
class TestRunner:
def __call__(self):
self.getRegister()
self.postSubmit()
self.getComplete()
def getRegister(self):
result1 = request1.GET("http://deview.kr/register")
def postSubmit(self):
result2 = request2.POST("http://deview.kr/submit")
grinder.sleep(1000);
def getComplete(self):
result3 = request3.GET("http://deview.kr/complete")
from net.grinder.script import Test
from net.grinder.plugin.http import HTTPRequest
test1 = Test(1, "Register page")
request1 = test1.wrap(HTTPRequest())
test2 = Test(2, "Submit page")
request2 = test2.wrap(HTTPRequest())
test3 = Test(3, "Complete page")
request3 = test3.wrap(HTTPRequest())
class TestRunner:
def __call__(self):
self.getRegister()
self.postSubmit()
self.getComplete()
def getRegister(self):
result1 = request1.GET("http://deview.kr/register")
def postSubmit(self):
result2 = request2.POST("http://deview.kr/submit")
def getComplete(self):
result3 = request3.GET("http://deview.kr/complete")
1. request.GET("http://deview.kr/register")
2. request.POST("http://deview.kr/submit")
3. request.GET("http://deview.kr/complete")
몇명의 VUser를 이용해 어떻게 부하를 발생할지 설정합니다.
완료된 테스트의 요약결과 리포트를 보여주고 상세한 데이터와 그래프를 보여줍니다.
- Agent 선택
- VUser 개수
- 시나리오 스크립트
- 모니터링 대상 장비
- 테스트 시간 (Duration or Count)
- Ramp Up
- 그외 변수 설정, Path등록 등
The Grinder
① http://대박.com/login
② http://대박.com/search
③ http://대박.com/view?id=1
④ http://대박.com/basket
④ http://대박.com/pay
* 각 요청을 뒤죽 바꿔서 시나리오를 잡을 수 도 있음.
시나리오, 결과요약, 리포팅을 프로젝트단위로 관리합니다.
- TPS현황(차트, 표)
- Resource사용현황(CPU, Memeory등)
- 성능 테스트 묶음관리
- Jython을 이용한 시나리오
- library jar 추가
- 테스트 히스토리
- 웹기반 에디터 제공
- 결과 리포트 관리
- 스크립트 유효성 체크
- 시나리오 관리
The Grinder
발표자 : 김광섭
The Grinder
진행중인 테스트현황 그래프, Target, Agent장비의 리소스그래프를 보여줍니다.
시나리오를 생성/편집하고 필요한 Lib를 추가합니다.
while(true) {
target.request();
}