진행 했던 프로젝트에서 대용량 트래픽 처리에 대한 고민을 하게 되었는데, 검색해보니 HTTP 요청에 대한 테스트 툴은 많이 있었습니다.

그런데 WebSocket 요청에 대한 성능 테스트 툴은 많지 않았고, Apahce JMeter가 유일해 보였습니다.

더군다나 JMeter에 대한 국내 자료는 대부분 socket.io 기반으로 작성되어 있어서 저의 서버 환경과 맞지 않았습니다.


어찌저찌 하여 JMeter 툴을 익히게 되었고,  HTTP와 WS 요청에 대한 테스트를 마쳤으며, 이 글을 통해 그 방법을 공유하고자 합니다.

JMeter에는 많은 기능들이 있는데, 제가 테스트 했던 부분만 간단히 다루도록 하겠습니다.

참고로 JMeter 버전은 4.0입니다.




1. JMeter 설치 및 실행

먼저 Apahce JMeter 사이트( 링크 )에서 Binaries의 apache-jmeter-4.0.zip을 다운로드 하여 압축을 풉니다.

보시는 바와 같이 시스템에 Java 8 또는 9 버전이 설치되어 있어야 합니다.




다음으로 JMeter에서 여러 플러그인을 설치할 수 있도록 도와주는 JMeter Plugin Manager( jar 파일 )를 다운 받습니다. ( 링크 )

다운 받은 jar 파일을 압축을 해제한 JMeter 폴더인 apache-jmeter-4.0/lib/ext 폴더로 옮깁니다.

그리고 apache-jmeter-4.0/bin/jmeter.bat 파일을 클릭하여 JMeter를 실행합니다.



이제 HTTP 성능 테스트를 진행하고, 이어서 WebSocket 성능 테스트를 해보겠습니다.




2. Thread Group 생성
JMeter를 실행하면  기본적으로 Test Plan이 있을 것입니다.
Test Plan은 말 그대로 테스트를 진행할 계획을 작성하면 되는데, 넘어가도록 하겠습니다.

Test Plan에 추가해야 할 것은 Thread Group입니다.
JMeter 테스트는 쓰레드를 생성하여 요청을 하게 되는데, Thread Group은 쓰레드 생성 규칙에 대한 정의를 하는 공간이며, 여러 테스트에 대한 그룹 단위입니다.
예를 들어 HTTP 요청과 WS 요청은 다른 Thread Group을 갖는 것이 좋을 것입니다.
그렇지 않으면 HTTP와 WS 요청이 번갈아가면서 실행되기 때문에 올바른 테스트 결과를 얻을 수 없습니다.


이제 Thread Group을 생성하고, 쓰레드 생성 규칙을 작성해보도록 하겠습니다.
JMeter에서 Test Plan 우클릭 -> add -> Thread( Users ) -> Thread Group을 하여 Thread Group을 생성합니다.

그리고 Thread Group에 아래와 같이 작성합니다.


여기서 속성에 대한 이해가 중요한데, 각 속성의 의미는 다음과 같습니다.
1) Number of Threads
쓰레드 개수, 즉 가상 유저의 수라고 생각하면 됩니다.

2) Ramp-Up Period
쓰레드 당 생성시간을 의미합니다.
예를 들어 Number of Threads = 1000이고, Ramp-Up = 10일 때,
1000명의 유저를 생성할 때 까지 10초가 걸린다는 것인데, 다시 말하면 1초 동안 100명의 유저가 요청을 한다는 뜻입니다.
따라서 Ramp-Up = 0으로 설정하면, 동시 접속 자 수는 1000 명이 될 것입니다.
( 저는 동시 접속 자 수에 대한 테스트를 할 목적으로 Ramp-Up = 0으로 설정했습니다. )

3) Loop Count
하나의 Thread가 수행할 작업 수를 의미합니다.
예를 들어 Number of Threads = 1000이고, Loop Count = 10일 때,
1000명의 유저는 동일한 작업을 10번 수행하게 됩니다.
따라서 총 10000번이 수행되며, 이는 총 요청 횟수로 생각하면 됩니다.

위의 속성 값을 정의할 때 주의 할 점은 쓰레드 수가 지나치게 많을 경우 CPU가 과부하 되는데, 그러면 올바른 테스트 결과를 얻을 수 없기 때문에 적절하게 값을 조정해야 한다는 것입니다.
따라서 테스트를 하면서 작업 관리자를 통해 CPU와 메모리 상태를 확인하는 것이 좋습니다.




3. HTTP Reqeust 생성
요청에 대한 쓰레드 생성 규칙을 정의 했으니, 이제 실제로 어떤 경로에 요청을 보낼 것인지 정의해야 하는데, 이를 작성하는 곳이 HTTP Reqeust 입니다.
위에서 생성한 ThreadGroup - add - Sampler - HTTP Request 클릭하여 HTTP Request를 생성합니다.

작성도 간단합니다.
프로토콜, 도메인 이름 또는 IP 주소, 포트 번호를 작성하고 HTTP 요청 메서드와 경로를 작성하면 됩니다.





4. 응답 결과 데이터 조회
다음으로 요청에 대한 응답 결과를 분석을 하기 위해 여러 가지 결과 데이터가 필요합니다.
무엇을 테스트 할 것이냐에 따라 추가하는 Listner가 다른데, 저는 응답 시간을 그래프로 나타내는 데이터가 필요했습니다.
그 밖에 참고할 만한 여러 Listener도 추가했습니다.

Listener를 추가하는 방법은 Thread Group - add - Listner - ??? 를 클릭하면 됩니다.

1) View Results Tree

Reuqest, Response data 등 요청에 대한 정보를 볼 수 있습니다.


2) Summary Report
요청 결과를 파일로 저장할 수 있습니다.
하단의 Save Table Data 버튼을 클릭하면 되는데, 데이터를 바탕으로 엑셀에서 그래프를 그릴 수 있습니다.

3) Response Time Graph
응답 시간 결과를 그래프로 볼 수 있습니다. ( settings에서 x축 간격을 좁힐 수 있습니다. )



지금까지 파일 생성 결과는 다음과 같습니다.




5. 테스트
이제 HTTP 요청 테스트를 진행해보겠습니다.

상단의 start 버튼을 누르면 Thread가 생성되면서 요청을 하게 됩니다.
주의할 점은 start를 하기 전에, 빗자루 버튼을 눌러서 이전 테스트 내용을 모두 지운 후에 테스트를 하도록 합니다.



테스트를 해보면 Response Time Graph에 다음과 같이 그래프가 출력됩니다.







6. WebSockeet Sampler 플러그인 설치
이제 WebSocket 테스트를 위한 WebSocket Sampler 플러그인을 설치할 것입니다.

JMeter 상단의 options 탭 -> Plugins Manager를 클릭하고,
Plugin Manager에서 상단의 Available Plugins 탭을 클릭 하여 WebSocket Sampler by Peter Doornbosch를 체크한 후,
우측 하단의 Apply Changes and Restart JMeter버튼을 클릭합니다.


WebSocket 플러그인을 설치하기 위해 직접 빌드 하여 jar 파일을 apache-jmeter-4.0/lib/ext 경로에 놓아도 되지만,

Plugin Manager를 사용하면 이렇게 간단하게 플러그인을 설치할 수 있습니다.





7. WebSocket 테스트

다음으로 웹 소켓 성능 테스트를 위한 Sampler를 작성하겠습니다.

HTTP 요청 테스트를 할 때 사용했던 Thread Group을 우클릭하여 disabled 시키고, 새로운 Thread Group을 생성합니다.


Thread Group - add - Sampler - WebSocket Single write Sampler 클릭하여 WebSocket Sampler를 생성합니다.


Sampler를 작성하는 방법도 간단합니다.
요청할 때 마다 Connetion을 새로 생성하도록 setup new connections을 클릭하고,
프로토콜, 도메인 이름 또는 IP, 포트번호와 경로를 작성합니다.
그리고 Reqeust data에 메시지를 작성합니다.


테스트 방식은 마찬가지로 상단의 start 버튼을 누르면 되고, Response Graph를 통해 응답 결과를 확인할 수 있습니다.





이상으로 Apahce JMeter를 사용하여 HTTP, WS 성능 테스트를 해보았습니다.

HTTP 성능을 높이기 위해서는 웹 서버의 Worker 조정, 캐시 등의 방법이 있을 것이고,

WS 성능을 높이기 위해서는 WS 요청을 처리하는 서버를 늘려서 load balancing하는 방법이 있을 것입니다.


load balancing 성능을 측정할 때 주의할 것은 JMeter에서 제공하는 Response Graph를 확인하는 것이 아니라, 서버의 CPU와 메모리를 확인하는 것이 맞습니다.

저는 load balancing을 해놓고 클라이언트 단에서 응답 시간을 비교하는 뻘짓을 했었습니다...


댓글 펼치기 👇
  1. homekeeper89@gmail.com 2019.04.20 11:40

    감사합니다. 개념 잡는데 도움이 되었습니다

  2. Favicon of https://unoday.tistory.com 유노s 2019.07.17 16:50 신고

    안녕하세요. 글 잘보았는데 질문 하나 드립니다.

    1.Number of Threads : 100
    2.Ramp up Period : 10
    3.Loop Count : 10

    제가 블로그 보고 이해하기로는
    위와 같은 값을 지정하게되면
    ----------------------------------------------
    10초동안 100명의 유저가 요청하는데,
    이 작업을 10번 한다.
    ---------------------------------------------

    여기서 제가 궁금한건,
    10초동안 100명의 유저 요청을 하는데,
    Loop Count가 10일 경우(10회 반복을 해야하니)
    10초 * 10번 = 100초(1분40초) 동안 실행되어야 하는데,
    실제 실행시켜보면 턱없이 실행이 금방 끝나네요..ㅠㅠ

    제가 잘못 이해한건가요?

    • Favicon of https://victorydntmd.tistory.com victolee 우르르응 2019.07.26 12:45 신고

      실제 10초를 의미하는 것이 아닐겁니다.
      10초 동안 100명의 유저가 요청을 한다는 절대적인 의미가 아니라 그러한 속도로 유저가 요청을 한다는 의미입니다.
      초당 동시접속자 수 정도로 이해하면 되지 않을까 싶네요.

      그리고 10회 요청을 하는 것은 내부적으로 어떻게 구현이 되어 있는지는 모르나, 한 쓰레드가 요청을 보내고 응답을 받을때까지 다른 쓰레드가 요청을 보낼 수 없는 상황이 아닐 것입니다.
      즉, 멀티쓰레드로 구현이 되어 있지 않을까 싶네요
      따라서 실지 실행 시간은 10초도 아닌 더 빠른 시간에 끝날 것으로 예상됩니다.

      실행, 끝 시간 조정 및 쓰레드간 딜레이를 설정할 수도 있는 것 같네요.
      http://2min2code.com/articles/jmeter_intro/multiple_threads

      제가 전문적으로 다뤄본게 아니라 정확하지 않을 수 있습니다.. ㅎㅎ