본문 바로가기
공부/프로그래밍

[test] nGrinder 설치 및 테스트환경 구축(mac)

by demonic_ 2019. 10. 26.
반응형

nGrinder 는 네이버에서 만든 오픈소스다. 관련 코드는 아래 Github에 있다.

https://github.com/naver/ngrinder/releases

 

naver/ngrinder

enterprise level performance testing solution. Contribute to naver/ngrinder development by creating an account on GitHub.

github.com

 

접속해서 파일을 다운로드 받는다. 여기서는 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

 

Hyperic Sigar Mac Osx错误 - 没有库 - VoidCC

我得到了解决方案, 解决方案是添加一个jar文件(在我的情况下)到我的项目。 每当我们使用第三方库(如java的mysql驱动程序)时,它的概念是相同的。 所以在我的情况下, 我需要添加log4j.jar和sigar.jar到我的路径。 右键单击您的eclipse项目,然后转至 构建路径>配置构建路径> Java构建路径>添加外部JAR 并将sigar.jar添加到您的项目中。 来源 2012-10-12 07:59:24 Chris

cn.voidcc.com

 

 

 

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

 

naver/ngrinder

enterprise level performance testing solution. Contribute to naver/ngrinder development by creating an account on GitHub.

github.com

 

 

 

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 를 클릭하면 더 많은 정보를 볼 수 있다.

 

메인 화면에 가면 테스트를 실행한 날짜가 기록된다.

 

끝.

반응형

댓글