nGrinder 는 네이버에서 만든 오픈소스다. 관련 코드는 아래 Github에 있다.
https://github.com/naver/ngrinder/releases
접속해서 파일을 다운로드 받는다. 여기서는 3.4.3 버전으로 진행했다.
파일명: ngrinder-controller-3.4.3.war
다운로드 받은 파일을 톰캣없이 실행이 가능하다 해서 해봤는데 내 경우는 안됐다.
(dataSource 를 찾는데 왜인지 모르겠음)
실행코드
java -XX:MaxPermSize=200m -jar ngrinder-controller-3.4.3.war -p 7777
에러메세지
Error creating bean with name 'dataSource' defined in org.ngrinder.infra.config.DatabaseConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.commons.dbcp.BasicDataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.IllegalArgumentException
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
그래서 tomcat 을 따로 설치받아서 ROOT.war 파일을 톰캣의 webapps 폴더에 옮겨 설치해 실행했다.
브라우저로 접근하니 로그인 화면이 떳다.
처음 계정은 admin 비밀번호도 admin 이다.
Agent 실행
agent는 테스트에 필요한 worker 를 실행, 관리해준다
우측 상단에 admin > Download Agent 를 클릭한다
다운로드한 파일을 압축해제 한 후에 적당한 폴더로 이동한다
터미널을 켠 후 폴더로 이동하여 agent 를 실행한다.
./run_agent.sh
성공하면 다음과 같은 메세지가 뜬다
2019-10-25 16:51:50,718 INFO starter: ***************************************************
2019-10-25 16:51:50,718 INFO starter: Start nGrinder Agent ...
2019-10-25 16:51:50,718 INFO starter: ***************************************************
2019-10-25 16:51:50,719 INFO starter: Hey!! JAVA_HOME env var was not provided. Please provide JAVA_HOME env var before running agent.Otherwise you can not execute the agent in the security mode.
2019-10-25 16:51:50,719 INFO starter: JVM server mode is disabled.
2019-10-25 16:51:50,727 INFO starter: connecting to controller 127.0.0.1:16001
2019-10-25 16:51:50,737 INFO agent controller daemon: The agent controller daemon is started.
2019-10-25 16:51:51,284 INFO agent controller: Connected to agent controller server at /127.0.0.1:16001
2019-10-25 16:51:51,284 INFO agent controller: Waiting for agent controller server signal
2019-10-25 16:52:01,238 INFO agent controller: Received a start agent message
2019-10-25 16:52:01,239 INFO agent controller: Agent start message is received from controller net.grinder.messages.agent.StartGrinderMessage@2a1f7aef
2019-10-25 16:52:01,239 INFO agent controller: Starting agent... for test_47
2019-10-25 16:52:01,239 INFO agent daemon: Agent daemon connecting to port 12002 is started.
2019-10-25 16:52:01,240 INFO agent controller: Agent is started. Waiting for agent controller signal
2019-10-25 16:52:01,247 INFO agent daemon: The Grinder 3.9.1
2019-10-25 16:52:01,257 INFO agent daemon: Connect to console at /127.0.0.1:12002
2019-10-25 16:52:01,258 INFO agent daemon: Waiting for console signal
2019-10-25 16:52:06,739 INFO agent daemon: received a stop message
2019-10-25 16:52:06,743 INFO agent daemon: communication shut down
2019-10-25 16:52:06,744 INFO agent daemon: Test shuts down.
2019-10-25 16:52:06,745 INFO agent controller: Send log for test_47
만약 여기서 에러가 발생한다면 아래 참조. 아니라면 건너뛴다
# Agent 실행 중 에러가 발생한 경우
java.lang.ClassCastException: class jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to class java.net.URLClassLoader (jdk.internal.loader.ClassLoaders$AppClassLoader and java.net.URLClassLoader are in module java.base of loader 'bootstrap')
at org.ngrinder.infra.ArchLoaderInit.getSigarNativePath(ArchLoaderInit.java:74) ~[ngrinder-core-3.4.3.jar:na]
at org.ngrinder.infra.ArchLoaderInit.init(ArchLoaderInit.java:41) ~[ngrinder-core-3.4.3.jar:na]
at org.ngrinder.NGrinderAgentStarter.init(NGrinderAgentStarter.java:67) ~[ngrinder-core-3.4.3.jar:na]
at org.ngrinder.NGrinderAgentStarter.main(NGrinderAgentStarter.java:205) ~[ngrinder-core-3.4.3.jar:na]
0 [main] DEBUG Sigar - no libsigar-universal64-macosx.dylib in java.library.path: [/Users/user/Library/Java/Extensions, /Library/Java/Extensions, /Network/Library/Java/Extensions, /System/Library/Java/Extensions, /usr/lib/java, .]
org.hyperic.sigar.SigarException: no libsigar-universal64-macosx.dylib in java.library.path: [/Users/user/Library/Java/Extensions, /Library/Java/Extensions, /Network/Library/Java/Extensions, /System/Library/Java/Extensions, /usr/lib/java, .]
at org.hyperic.sigar.Sigar.loadLibrary(Sigar.java:172)
at org.hyperic.sigar.Sigar.<clinit>(Sigar.java:100)
at org.ngrinder.NGrinderAgentStarter.checkDuplicatedRun(NGrinderAgentStarter.java:273)
at org.ngrinder.NGrinderAgentStarter.main(NGrinderAgentStarter.java:213)
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.hyperic.sigar.Sigar.getPid()J
at org.hyperic.sigar.Sigar.getPid(Native Method)
at org.ngrinder.NGrinderAgentStarter.checkDuplicatedRun(NGrinderAgentStarter.java:288)
at org.ngrinder.NGrinderAgentStarter.main(NGrinderAgentStarter.java:213)
로그를 읽다보면 libsigar-universal64-macosx.dylib 파일을 참조하는데 참조하는 폴더에 파일이 없어 발생한 에러다.
다음은 참조하는 폴더 목록
/Users/user/Library/Java/Extensions
/Library/Java/Extensions
/Network/Library/Java/Extensions
/System/Library/Java/Extensions
/usr/lib/java
그래서 인터넷을 살펴보니 다운로드 한 다음 특정 폴더에 넣어주면 된다. 과정은 다음과 같다
# to find it later because you will need it ...
cd ~/Downloads/
# or whatever the latest one at the time of reading is ...
wget https://netix.dl.sourceforge.net/project/sigar/sigar/1.6/hyperic-sigar-1.6.4.zip
# unpack the package to the tmp dir
sudo unzip -o ~/Downloads/hyperic-sigar-1.6.4.zip -d /tmp/
# copy the libsigar-universal64-macosx.dylib to your class path dir
sudo find /tmp/ -name libsigar-universal64-macosx.dylib \
-exec cp -v {} /Library/Java/Extensions/ ;
# this cmd might be obsolete ...
# copy the sigar.jar to your class path dir
sudo find /tmp/ -name sigar*.jar \
-exec cp -v {} /Library/Java/Extensions/ \;
...
참조사이트
http://cn.voidcc.com/question/p-qqnkcwcs-yw.html
agent 여러개 실행
host id 별로 1개만 실행되서 중복실행이 안된다. 다행히 옵션에서 이름을 지정할 수 있는데, 이를 이용해 여러개를 한 컴퓨터에서 띄울 수 있다.(비추천, 어차피 자원을 나눠쓰는 거라서 컴터가 더 버벅인다)
1. agent 폴더를 여러개 만든다 (ngrinder-agent-1, ngrinder-agent-2 ... 등)
2. 명령어 옵션으로 host ip를 변경하여 실행한다.
그래서 내 경우 다음과 같이 실행했다.
./run_agent.sh --agent-home [설치경로]/ngrinder-agent-1 --host-id first
./run_agent.sh --agent-home [설치경로]/ngrinder-agent-2 --host-id second
./run_agent.sh --agent-home [설치경로]/ngrinder-agent-3 --host-id third
이후 과정이 더 있는데(환경변수 설정이라든지 등) 여기서는 무의미해서 생략했다.
다시 브라우저로 돌아와 admin > Agent Management 를 클릭한다.
다음과 같은 화면이 보인다면 성공.
만약 1개의 컴퓨터에서 Agent를 늘리고 싶다면 다음처럼 실행하면 된다.
./run_agent.sh --agent-home ~/.ngrinde-agent-1 --host-id agent-1
./run_agent.sh --agent-home ~/.ngrinde-agent-2 --host-id agent-2
다만 내 경우 2개이상 띄워서 테스트를 실행하면 에러가 발생하면서 안되었다.
아래는 Agent를 설정하는 방법이 적힌 Github 주소
https://github.com/naver/ngrinder/wiki/Agent-Configuration-Guide
Script 작성
좌측 상단에 Script 버튼을 클릭한다.
Create a Script 를 클릭한다.
여기선 groovy 를 이용해 만들었다.
만들면 다음처럼 자동으로 URL을 입력해준다.
test_sample.groovy 파일
...
@Test
public void test(){
HTTPResponse result = request.GET("http://localhost:8080/test", 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));
}
}
...
파라미터 등을 넣으려면 코드를 수정해야 하는데 여기서는 생략한다.
수정 후엔 꼭 우측 상단 스크립트 검증을 클릭하자. 그래야 테스트 전에 문제여부를 파악할 수 있다.
클릭하면 다음과 같은 결과를 볼 수 있다.
...
2019-10-25 17:17:28,442 INFO http://localhost:8080/test -> 200 , 15 bytes
2019-10-25 17:17:28,458 INFO finished 1 run
2019-10-25 17:17:28,459 INFO elapsed time is 59 ms
2019-10-25 17:17:28,460 INFO Final statistics for this process:
2019-10-25 17:17:28,464 INFO
Tests Errors Mean Test Test Time TPS Mean Response Response Mean time to Mean time to Mean time to
Time (ms) Standard response bytes per errors resolve host establish first byte
Deviation length second connection
(ms)
Test 1 1 0 36.00 0.00 16.95 15.00 254.24 0 1.00 8.00 16.00 "localhost"
Totals 1 0 36.00 0.00 16.95 15.00 254.24 0 1.00 8.00 16.00
Tests resulting in error only contribute to the Errors column.
Statistics for individual tests can be found in the data file, including
(possibly incomplete) statistics for erroneous tests. Composite tests
are marked with () and not included in the totals.
NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
2019-10-25 17:17:28,341 INFO validation-0: Starting threads
2019-10-25 17:17:28,464 INFO validation-0: Finished
URL을 변경하여 일부로 에러를 유도해보자.
실패한다면 다음과 같이 에러 발생하면서 이유를 알려준다.
...
2019-10-25 17:18:14,772 INFO http://localhost:8080/test1 -> 404 , 126 bytes
2019-10-25 17:18:14,789 ERROR
Expected: is <200>
got: <404>
java.lang.AssertionError:
Expected: is <200>
got: <404>
at TestRunner.test(test_sample.groovy:72) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at net.grinder.scriptengine.groovy.junit.GrinderRunner.run(GrinderRunner.java:170) ~[ngrinder-groovy-3.4.3.jar:na]
at net.grinder.scriptengine.groovy.GroovyScriptEngine$GroovyWorkerRunnable.run(GroovyScriptEngine.java:147) ~[ngrinder-groovy-3.4.3.jar:na]
at net.grinder.engine.process.GrinderThread.run(GrinderThread.java:118) ~[grinder-core-3.9.1.jar:na]
2019-10-25 17:18:14,790 INFO finished 1 run
2019-10-25 17:18:14,791 INFO elapsed time is 54 ms
2019-10-25 17:18:14,791 INFO Final statistics for this process:
2019-10-25 17:18:14,795 INFO
Tests Errors Mean Test Test Time TPS Mean Response Response Mean time to Mean time to Mean time to
Time (ms) Standard response bytes per errors resolve host establish first byte
Deviation length second connection
(ms)
Test 1 0 1 NaN 0.00 0.00 NaN 0.00 0 NaN NaN NaN "localhost"
Totals 0 1 NaN 0.00 0.00 NaN 0.00 0 NaN NaN NaN
Tests resulting in error only contribute to the Errors column.
Statistics for individual tests can be found in the data file, including
(possibly incomplete) statistics for erroneous tests. Composite tests
are marked with () and not included in the totals.
NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
2019-10-25 17:18:14,687 INFO validation-0: Starting threads
2019-10-25 17:18:14,795 INFO validation-0: Finished
이제 성능 테스트를 하자
좌측 상단에 'Performance Test'를 클릭한 후 화면 중간에 파란색 버튼인 Create Test 를 클릭한다.
테스트 이름은 test_url
- Agent 는 1개(띄운게 많으면 최대치도 늘어난다)
- Vuser는 10명
- 사용할 스크립트 test_sample.groovy (위에서 생성한 스크립트)
- 1분동안 실행
이렇게 설정했다. 시간대신 횟수로 하려면 Run Count 를 클릭하면 된다
우측 상단에 Save and Start를 클릭하고, 아래 팝업이 나오면 Run now 를 클릭한다
아래 화면은 테스트가 끝난 모습
총 요청횟수는 413,463 번
Errors 는 0 번
평균 TPS 는 7,942
최고 TPS 는 9,425
보인다. 로그를 보고 싶다면 좌측 하단에 agent- 로 시작하는 것을 클릭하면 다운로드 받는다.
Detailed Report 를 클릭하면 더 많은 정보를 볼 수 있다.
메인 화면에 가면 테스트를 실행한 날짜가 기록된다.
끝.
'공부 > 프로그래밍' 카테고리의 다른 글
[spring, jpa] Could not build ClassFile 에러 (0) | 2019.11.27 |
---|---|
[docker] 공유된 volume 에 접근이 안될 때 (0) | 2019.11.02 |
[spring] @Value 활용(Field, Method, SqEL) (0) | 2019.10.20 |
[java] 빌더 패턴(Builder Pattern) 주의점과 사용이유 (0) | 2019.10.18 |
[intellij] mybatis autowired mapper 빨간불 없애기 (0) | 2019.10.17 |
댓글