본문 바로가기

엔지니어링(TA, AA, SA)/성능과 튜닝

[JMeter] JMeter를 이용한 성능 테스트

소프트웨어 개발 초창기에는 기술을 습득하고 요구사항을 분석하고 이를 설계/구현하는 것만으로도 바쁘기 때문에 성능을 고려해서 개발하기가 쉽지 않다. 최근의 개발 환경이 스프링과 같은 개발 프레임워크 기반으로 많은 부분이 공통화되어 있기 때문에 성능과 관련해서 개발자가 직접 통제할 수 있는 영여깅 매우 제한적이기 때문이기도 하다.

 

이러한 제약 사항과 패러다임의 변화에도 불구하고 성능은 소프트웨어나 서비스에 있어서 매우 중요한 요소이며 아무리 기능이 좋고 잘 만들어졌을지라도 원하는 성능이 나오지 않으면 서비스를 개통할 수 없게 되며 실제로 성능 문제가 발생해서 개통한 서비스를 다시 취소하는 경우도 많이 있다.

 


성능 테스트는 개발한 소프트웨어 혹은 서비스가 특정한 조건에서 얼마나 서비스의 수행이 가능한지를 확인하는 과정이라고 할 수 있다. 수치를 측정하는 테스트 작업으로 이해하는 것이 좋다. 성능 테스트와 함께 고려할 것은 성능 튜닝과 부하 테스트이다.

 

성능 테스트

특정 업무 애플리케이션 혹은 특정 트래잭션의 성능 수치를 측정한다. 트랜잭션별(주로 하나의 요청이 응답할 때까지의 단위) 진행되는 각 구간의 성능값을 측정한다. 편의상 부하 테스트의 의미를 포함하는 경우도 있다.

 

성능 튜닝

성능 테스트에서 도출된 성능 병목 구간을 튜닝한다. 일반적으로 데이터베이스 튜닝, 애플리케이션 튜닝과 같이 개발된 코드를 개선하는 작업과 운영체제, 미들웨어, 데이터베이스 등 솔루션 관점의 파라미터 튜닝도 함께 진행한다. 이러한 튜닝 괒어을 거치고 다시 성능 테스트를 수행해서 튜닝 전/후의 데이터를 비교하면서 개선해 나가는 활동이다.

 

부하 테스트

부하 테스트는 성능 테스트와 성능 튜닝이 어느 정도 완성되면 해당 소프트웨어 혹은 서비스를 대표할 수 있는 기능을 선정하여 해당 하드웨어 및 네트워크 환경에서 얼마나 많은 사용자가 동시에 사용할 수 있는지 테스트하는 것이다. 간단히는 10분에서 1시간 정도 테스트해서 초당 평균 TPS와 하드웨어 및 네트워크 사용률을 분석한다. 추가적으로 1일에서 1주일 동안 지속적으로 부하르 발생시켜서 부하가 지속적으로 처리되는지도 확인한다. 장시간 부하 테스트 시 가용성 테스트를 병행한다.

 

성능 테스트, 성능 튜닝, 부하 테스트는 거의 맞물려서 진행되지만 소규모 프로젝트의 경우, 부하 테스트는 하지 않고 성능 테스트와 성능 튜닝 정도로 끝내는 경우도 많다. 성능 테스트라는 의미에 부하 테스트도 포함해서 말하는 경우도 많다.

 

성능테스트를 수행할 경우 얻을 수 있는 이점은 다음과 같다.

 - 개발한 소프트웨어가 특정한 하드웨어에서 얼마나 많은 트랜잭션 혹은 사용자의 요청에 대응할 수 있는지 확인할 수 있다.

 - 성능 테스트를 통해 소프트웨어 혹은 하드웨어상에 존재하는 병목 구간과 문제 구간을 유추할 수 있다.

 - 개발한 서비스를 개통할때 얼마나 많은 사용자에게 서비스가 가능한지 사전에 예측하고 준비한다.

 - 성능 테스트 시 발생하는 각종 로그 데이터, 업무 데이터, 파일 등의 발생량을 고려하여 시스템의 스토리지, 디스크, 데이터베이스, 메모리 등의 사용량을 예측할 수 있고 향후 서비스 운영시 참조할 수 있는 기준값을 산출할 수 있다.

 - 테스트 활동을 통해 서비스를 개발하는 개발자, 기획자 및 관리자에게 항상 성능을 고려해서 기획, 설계, 개발해야 한다는 인식을 심어줄 수 있다.

 

이러한 여러가지 장점에도 불구하고 아직까지 대규모 프로젝트를 제외하고 성능 테스트를 제대로 진해아힞 못하는 이유는 다음과 같다.

 - 성능을 테스트하고 관리할 전담 인력을 별도로 두기 어렵다. 이로 인해 비전문가가 테스트해서 문제를 발견하지 못하거나, 문제가 있더라도 해결하지 않고 넘어가는 경우가 생긴다.

 - 프로젝트 일정이 빠듯해서 기능을 설계. 구현하고 테스트하는 것만으로도 벅차기 때문에 성능까지 고려할 여지가 많지 않다.

 - 성능은 문제가 발생하면 향후 하드웨어 증설로 해결할 수 있을 것이라는 막연한 기대감을 가지고 심각하게 대처하지 않는 경우가 있다.

 - 성능 테스트를 어떻게 해야 하는지 모르는 경우가 많고 설령 테스트를 수행하더라도 나온 결과의 신뢰성이 높지 않거나 결과를 해석할 수 있는 사람이 없는 경우가 많다.

 


성능 테스트 전략 수립

성능 테스트 전략 수립은 성능 테스트에 대한 목표를 정의하는 것부터 시작한다. 목표가 없는 테스트는 흐지부지 끝날 가능성이 많기 때문에 객과적인 기준에 따라 전략을 세우고 그 전략에 따라 지속적이고 반복적으로 성능 테스트를 하는 것 중요하다.

 

1) 목표 수립

성능 테스트 전략 수립 단계 중 가장 핵심은 바로 서비스할 소프트웨어에 대한 명확한 목표를 수립하는 것이다. 이 목표를 달서앟기 위해 성능 테스트와 부하 테스트를 수행하고 튜닝작업을 진행한다. 만일 튜닝을 해도 목표를 달성하지 못한다면 하드웨어 증설이나 아키텍처 변경을 고려해 볼 필요가 있다.

 

목적

성능 테스트의 목적을 명확하게 기술한다 (새로 구축하는 소프트웨어가 목표로 하는 부하 상황에서 원활하게 작동하는지를 확인하거나 신규 도입하는 하드웨어가 개발된 소프트웨어를 기반으로 최대 어느정도까지 서비스가 가능한지 확인한다.)

 

목표

목적이 정의되었다면 목적에 기반한 목표를 정의한다. 목표는 매우 상세하게 기록하는 것이 좋은데 동시 사용자 수, 동시 사용자가 발생시키는 요청수 등의 예측치를 기술하는 것이 좋다. (화면 로그인의 최대 피크 타임을 오전 8시부터 9시 사이로 예상한다면 해당 시간 동안 초당 100번의 SSO 서비스가 가능해야 한다.)

 

대상

성능 테스트는 가능한 한 모든 서비스에 대해서 최대한 많이 하면 좋지만, 시간이 많이 들고 노력도 많이 필요한 작업이다. 때문에 성능 테스트의 목적과 목표를 검증할 수 있는 대표 서비스를 도출해서 수행하는 것이 좋다.

소프트웨어에서 제공하는 서비스 중 대표적으로 많이 사용하는 것과 반드시 검증해야 하는 서비스를 도출하되 전체 서비스의 20%를 넘지 않는 선에서 수행하는 것이 좋다 (성능 테스트에서 황금률은 전체 20%의 서비스가 전체 자원의 80%를 소모한다는 법칙이 있는데 많은 서비스를 테스트한다고 해도 성능 검증에 큰 영향을 주지 않는 경우가 많다.)

 

목적/목표/대상을 수립했다면, 이에 대한 기준을 세워야 하는데 가장 좋은 기준은 이미 해당 서비스를 하고 있는 경우이다. 이 경우 현재 서비스의 상태와 총 사용자 수, 특정 시간대의 동시 사용자수, 그리고 초당 평균 요청 수 등을 뽑고 이 값을 기준으로 향후 어느 정도의 부하를 감당해야 하는지 정의하면 좋다.

 

총 사용자수

서비스를 사용하고 있느 혹은 사용할 예정인 전체 사용자 수를 정의한다. 사용자는 잠재적으로 서비스에 부하를 발생시키고 성능에 영향을 주는 주요한 항목이다. 현재 서비스의 가입자 항목, 가입은 하지 않았지만 '손님'과 같은 형태로 사용하는 경우도 모두 도출하는 것이 좋다.

 

동시 사용자수

총 사용자 수보다 더 중요한 항목이 바로 동시 사용자 수다. 동시 사용자 수에 대한 정의는 다소 애매한 부분이 있는데, 주로 특정 시간 동안 서비스를 요청하는 사용자 수를 의미한다.

대부분 특정 시간대(피크 타임)의 1초 동안 서비스를 요청하는 사용자 수로 정의하며 정확한 집계가 어렵다면 웹서버나 WAS의 ACCESS 로그에 찍히는 IP 정보와 시간을 분석해서 도출한다.

 

평균 TPS

TPS는 초당 요청 횟수를 의미하며 성능 테스트시 가장 보편적으로 사용하는 수치이다.

이 역시 동시 사용자수와 마찬가지로 피크 타임 때의 로그를 분석해서 평균 TPS를 수집하는데, 이때 주의할 것은 단순한 HTML이나 이미지 파일 등 미들웨어나 데이터 베이스에 큰 영향을 주지 않는 요청은 제외시키는 것이 좋다.

 

현행 성능 기준 정보를 바탕으로 목표에 대한 값과 대상을 산출하게 되며 향후 5년간 서비스의 발전을 고려해서 최종 성능 테스트 도달 목표를 정의하는 것이 좋다. 예를 들어 현재 동시 사용자가 100명이고 평균 TPS가 2000인데 해당 비즈니스가 매년 20%씩 증가한다고 가정한다면 이를 기준으로 5년 후의 동시 사용자와 평균 TPS를 산정하는 것이다.

 

위 설명들은 이미 서비스가 제공되고 있어서 서비스 업그레드나 하드웨어 업그레이드, 혹은 개편 시에 기존 서비스를 기반으로 성능 테스트 기준 정보를 산출하는 것이다. 그런데 신규로 만들고 있는 서비스라면 이를 도출하기가 매우 어렵다. 이러한 경우는 목표를 잡을때 다소 추상적으로 잡을 수 밖에 없고 테스트할 대상도 좀 더 많이 정의해야 한다.

 


2) 구간별/대상별 목표 수립

앞서 설정한 목표는 성능 테스트에 사용할 상위 수준의 목표이며 해당 항목들이 정의되면 이제 상세 목표를 수립해야 한다. 상세 목표를 수립할 때는 구간별 목표와 대상별 목표를 정의해야 한다. 일반적인 웹기반 프로젝트에서는 미들웨어에서의 성능 수치, 데이터베이스의 성능 수치, 대내/대외 연계를 위한 성능 수치, 최종적으로 네트워크의 성능 수치를 고려해야 한다. 이러한 구간별 목표는 클라이언트의 요청부터 응답까지 수행되는 각 구간을 사전에 정의하고 구간에 따른 누적 수치를 산출하게 되는데 중요한 것은 구간별로 수치값을 측정할 수 있는 환경이 마련되어 있어야 한다는 점이다.

 

JMeter에서의 성능 테스트는 클라이언트의 요청과 응답을 기준으로 측정하기 때문에, 구간별 측정 방법이 제공되지 않으면 어떤 서비스의 어떤 구간에서 문제가 발생했는지 알 수가 없다.

 

구간별 목표가 정의되었다면 성능 테스트 대상 서비스별 목표 수립이 필요하다. 동일한 소프트웨어에서 제공하는 서비스라도 서비스의 성격에 따라 목표가 달라지기 때문이다.

 

로그인 업무

주로 업무가 시작되는 시간에 집중적으로 부하가 발생한다. 아침 출근 한시간 전부터 출근 후 한 시간이 가장 피크타임이다. 그리고 점심시간 이후 오후 근무 시작 시점붙터 한시간 역시 로그인이 가장 많은 부하를 받는다.

 

공통 업무

업무마다 공통적으로 호출되는 기능의 경우 응답 시간은 매우 빠르지만 워낙 호출되는 트랜잭션 수가 많기 때문에 최대한의 성능 튜닝 및 사전 검증이 필요하다.

 

통계 업무

통계 화면은 주로 오전 시간대에 많은 부하가 발생한다. 전날 혹은 전월 통계를 기반으로 금일 작업 계획을 세우기 때문이다. 상대적으로 오후에는 부하가 급격히 떨어진다.

 

최근에는 글로벌 기업이 늘고 글로벌 서비스가 많아지면서 부하가 발생하는 특정 시간대를 규정하기가 어려운 경우도 많다. 그러므로 목표로 하는 서비스 상황을 고려해서 성능을 테스트할 서비스를 도출하고 각각에 대한 목표 수치를 수립할 필요가 있다. 

 


테스트 환경 구축

성능 테스트를 하기 위해서는 테스트를 할 수 있는 환경을 마련해야 한다. 성능 테스트는 어떻게 환경을 구성하느냐에 따라 결과의 차이가 크고, 잘못된 환경은 성능 테스트 자체에 대한 신뢰성을 훼손하기 때문에 통상적으로 특정 환경과 전제 조건을 바탕으로 테스트를 수행한다.

 

1) 성능 테스트 소프트웨어

여러 명의 사용자가 동시에 다른 데이터를 요청해서 처리하는 시나리오를 실행시키는 소프트웨어다. 다양한 애플리케이션 수행을 위해 다양한 프로토콜을 지원해야 하며 테스트 결과를 시각적으로 보여준다.

 

2) 네트워크 환경

성능 테스트하는 소프트웨어는 가급적 테스트할 서버와 같은 네트워크 환경에 존재하는 것이 좋다. 그렇지 않으면 네트워크의 성능 차이때문에 성능 측정 결과가 변질될 소지가 있다.

 

3) 테스트 데이터

제대로 된 성능 테슽트를 수행하기 위해서는 충분한 테스트 데이터가 확보되어야 한다. 특히 데이터베이스의 경우 축적된 데이터의 양에 따라 성능 결과가 크게 다를 수 있기 때문에 실제 운영환경을 고려해서 데이터를 준비해야 한다.

 

4) 다양한 요청 데이터

각각의 사용자들이 동일한 파라미터로 요청하는 경우는 극히 드물다. 그러므로 실제 서비스 환경을 고려해서 사용자들의 요청 데이터를 다양하게 준비할 필요가 있다.

특히 요즘 미들웨어나 데이터베이스는 동일한 요청값으로 들어온 데이터는 캐시 기능을 이용해서 상당히 빠르게 처리하는데 이를 보고 성능이 좋다고 오판할 수 있다.

 

5) 구간 모니터링 방안

최근 개발되는 애플리케이션은 멀티 티어 환경으로 구현되기 때문에 성능 테스트를 수행한 결과값을 각 구간별로 수집하고 구분할 수 있어야 한다. 예를 들어 A라는 요청은 데이터베이스 처리를 20번하고 파일 처리를 1번 한다면 각각의 항목의 수치값을 뽑을 수 있어야 향후 성능 튜닝에 참조할 수 있다.

 

위 내용은 성능 테스트 전략 수립시 고려해야할 항목의 일부분 이다. 제대로된 성능 테스트와 부하 테스트를 수행하기 위해서는 정확한 수치를 뽑고 이를 기반으로 상세 정보를 분석할수 있어야 한다. 이러한 준비없이 진행한다면 테스트 결과를 이용해서 개선활동이나 분석활동을 할 수 없게 된다.

 


아파치 JMeter란

성능 테스트를 수행할때 중요한 것 중 하나는 어떤 프로토콜을 이용해서 테스트를 진행할지 결정하는 것이다. 요즘 개발되는 대부분의 애플리케이션들이 웹 서비스나 HTTP 프로토콜을 이용해서 클라이언트의 요청을 수행해서 큰 영향은 없지만 웹이 아닌 애플리케이션인 경우 이에 대한 방안을 마련해야 한다.

 

JMeter의 핵심기능은 샘플러(Sampler)이다. 샘플러가 성능 테스트를 위한 부하를 발생시키는 역학을 하며 각각은 샘플러에서 실행할 수 있는 특별한 프로토콜에 맞는 값을 설정할 수 있다. 그리고 샘플러의 실행 결과가 수집되어서 성능 테스트에 대한 결과를 분석할 수 있는데, 요청에 대한 성공/실패, 소요 시간 등에 대한 정보를 기록한다. JMeter에서 제공하는 주요 샘플러는 다음과 같다.

 

Http Request

HTTP/HTTPS 프로토콜을 이용해서 성능 테스트를 수행할 때 사용 (JMeter에서 가장 많이 사용되는 샘플러)

 

JDBC Request

데이터베이스의 특정 SQL의 성능 테스트를 수행할때 사용

HTTP Request Sampler를 이용해서 테스트를 수행한 후 특정 JDBC에 대한 테스트가 필요할때 종종 사용.

JDBC 테스트를 위해서는 별도의 JDBC 드라이버를 JMeter의 클래스 패스에 추가해야 한다.

 


성능 테스트 설정 - 테스트 플랜 작성

JMeter를 실행하면 왼쪽 창에 [Test Plan]과 [WorkBench]라는 항목이 나온다. 성능 테스트를 위한 설정은 우선 [Test Plan] 영역에서 진행한다. 또한 작성한 테스트 플랜은 별도의 파일로 저장해서 관리할 수 있으며 필요시 다시 불러와서 진행할 수 있다. [Test Plan]에는 다음과 같은 항목들을 추가해서 사용할 수 있다.

 

테스트 플랜 항목

1. Thread Group

Thread Group은 모든 테스트 플랜 작성의 시작 지점으로 Thread Group 아래에 모든 컨트롤러와 샘플러가 위치한다. Thread Group에는 실행하는 스레드 수, 램프업 시간, 테스트 수행 시간을 지정한다. 하나의 테스트 플랜에는 여러개의 Thread Group을 지정할 수 있다.

 

2. Samplers

샘플러는 JMeter가 대상 시스템에 요청해야 하는 정보를 설정한다. 예를 들어 HTTP 프로토콜을 이용해서 테스트한다면 "HTTP Request Sampler"를 추가하고 여기에 연결한 URL 정보와 파라미터 값을 설정한다. 각각의 샘플러는 해당 프로토콜에 맞는 속성값들을 저으이하게 되어 있으며 테스트시 해당 프로토콜에 대한 이해없이는 설정이 거의 불가능 하다.

 

3. Logical Controllers

Logical Controller는 JMeter가 언제 서버에 요청을 전달할지를 결정한다. 전체 부하 테스트 중에서 로그인은 한번만 하는 경우, 혹은 HTTP URL 이 2개이고 해당 요청의 순서가 존재한다면 "HTTP Request Sampler"를 2개 등록하고 Logical Controller로 2개의 상관 관계를 정의할 수 있다.

 

4. Listener

JMeter를 통해 테스트하는 결과 정보 및 진행 상태 정보를 표시한다. 일반적으로 [Graph Result]를 이용해서 진행되는 추이를 그래픽하게 확인한다. 또한 수집된 정보는 XML 혹은 CSV로 저장이 가능하다.

 

5. Timers

JMeter의 테스트 플랜에 샘플러를 등록하면 순차적으로 진행이 되지만 현실 세계에서 하나의 사용자가 요청을 순차적으로 매우 빠른 시간내에 수행하는 것은 불가능하다. 이처럼 요청과 요청 사이에 특정한 시간 간격을 두려면 Timers를 이용해서 설정할 수 있다.

 

6. Assertion

JMeter의 HTTP 프로토콜을 이용해서 성능 테스트를 할 경우 요청별 성공/실패 여부는 HTTP 응답 코드의 값을 이용해서 판단한다. HTTP 응답 코드가 200이면 성공을, 그외에 다른 코드 값은 실패로 규약되어 있다. JMeter에서도 이를 그대로 사용하며 200번 코드가 리턴되면 테스트는 성공으로 인식한다.

하지만 업무적으로 200번 코드가 리턴되더라도 실패로 판단해야 하는 경우도 많이 있다. 이 경우 Assertion를 이용해서 응답 정보에 특정한 메시지를 필터링해서 성공/실패 여부를 판단할 수 있다.

 

7. Configuration Elements

Configuration Elements는 샘플러와 밀접한 관련이 있다. 비록 직접적으로 요청을 수해하지는 않지만 샘플러의 요청 정보를 관리할 수 있다. 예를 들어 테스트 플랜이 복잡해서 HTTP Request Sampler 작성을 많이 해야 하는데, 서버 IP나 포트 등 공통적으로 많이 사용되는 부분이 있다면 Configuration Elements의 "HTTP Request Defaults"에 설정하면 된다. 그러면 해당 설정 정보가 관련된 HTTP Request에 모두 적용된다.

 

8. Pre-Processor Elements

샘플러를 실행하기 전에 수행해야 할 내용을 정의한다. 예를 들어 요청을 하기 전에 파라미터 값을 초기화하는 등의 작업에 사용한다.

 

9. Post-Processor Elements

샘플러를 실행한 후에 수행해야 할 내용을 정의한다.

 

위 항목들은 JMeter 실행시 우선순위가 존재하는데, 다음과 같다.

Configuration -> Pre-Processor -> Timer -> Sampler -> Post-Processor -> Assertions -> Listener

 

위 순서가 중요한 이유는, JMeter가 성능 테스트를 수행할 때 작성된 테스트 플랜과 Thread Group에 정의 되어 있는 내용중 위의 순서 규칙을 참조해서 동작하기 때문이다. 이 내용을 이해하지 못하면, 실제 테스트 시에도 정확한 결과를 얻지 못할 수 있다.

 

 

1. Test Plan 설정

성능 테스트에 Test Plan의 이름과 설명이 영향을 주지는 않지만 향후 여러 버전 혹은 여러 대상 애플리케이션을 작업해야 한다면 이름과 설명을 제대로 작성해두는 것이 좋다. 또한 실행에 직접적으로 영향을 주는 옵션이 제공되는데, 일반적으로는 잘 사용하지 않지만 알아두면 좋다.

 

User Defined Variables

변수 선언이 필요할때 사용한다. 테스트 전반에 걸쳐서 선언한 변수와 값을 이용할 수 있다.

 

Run Thread Groups consecutively

Test Plan에 여러 개의 Thread Group이 있는 경우 이 옵션을 선택하면 병렬로 동작하는 것이 아니라 순차적으로 실행된다.

 

Run tearDown Thread Groups after shutdown of main threads

테스트를 종료한 후 후속 테스트를 수행하도록 설정할 수 있다. 이를 위해서는 별도의 "tearDown Thread Group"을 설정해야 한다.

 

Functional Test Mode

이 옵션을 선택하게 되면 테스트 시에 서버로부터 응답받은 데이터를 JMeter가 저장하다. 특히 파일 Listener를 Test Plan에 추가한 경우 응답 데이터를 파일에 저장할 수 있으며 저장된 데이터를 보고 정상적으로 Test Plan이 작성되었는지 확인할 수 있다. 이 옵션은 JMeter의 성능에 큰 영향을 주기 때문에 실제 테스트시에는 절대 선택해서는 안된다.

 

Add directory or jar to classpath

Test Plan에 사용할 JAR 혹은 디렉터리를 클래스 패스에 추가하는 것으로 주로 데이터베이스 드라이버, JMS 클라이언트 등을 사용한다.

 

위의 옵션 중 'Functional Test Mode'는 작성한 성능 테스트 모델을 검증하기 위해서 종종 사요한다. 이 옵션을 통해 응답 데이터를 저장하고 해당 저장된 내용이 원하는대로 처리되고 전달 되었는지 1차적으로 검증할 필요가 있다. 실제 성능 테스트를 수행할 때는 이 옵션을 반드시 해제해야 한다는 점이다.

 

 

2. 부하 발생 시간 및 스레드 설정 - Test Group

Test Group에는 반드시 하나 이상의 Thead Group이 있어야 한다. [First Test Plan]에서 마우스 오른쪽 버튼을 클릭하고 [Add]-[Threads (Users)]-[Thread Group]을 선택하면 된다. Thread Group의 설정 내용은 성능 테스트 시에 진행할 사용자 수라고 생각하면 된다.

 

예를 들어 테스트할 애플리케이션의 동시 사용자가 10명이라면 스레드 숫자는 10을 설정해야 하고 JMeter는 이 수치만큼 스레드를 생성해서 부하를 발생시킨다. 각 항목에 대한 설명은 아래와 같으며, 이 수치는 성능 테스트시에 매우 중요하게 사용되기 때문에 꼭 이해하고 넘어가야 한다.

 

Number of Threads

사용자 수를 의미하며 해당 값만큼 JMeter가 스레드를 생성해서 요청을 수행한다.

 

Ramp-up Period

정확한 테스트를 위해 초기 일정 시간 동안 준비하는 시간을 의미한다. 예를 들어 Ramp-up 시간이 100초이고 스레드 수가 2라면 50초 동안 수행한 요청에 대해서는 결과를 수집하지 않는다.

 

Loop Count(Forever)

스레드당 수행할 테스트 횟수를 의미한다. 만일 스레드 수가 3이고 Loop Count가 1000이라면 3000번 동안 Thread Group을 반복해서 실행한다. 만일 'Forever'에 체크하면 사용자가 종료할때까지 계속 실행한다.

 

Scheduler

테스트에 대한 스케줄링 시간을 설정한다.

 

위 항목에 해당하는 값을 설정한다. 초기에는 스레드 사용자를 1로 시작해서 점차 늘려가는 것이 좋다. 처음부터 너무 큰 값을 설정하면 애플리케이션에 부하도 많이 걸리고 정확한 테스트 수치를 얻기가 힘들기 때문이다. 그러므로 작은 값부터 시작해서 조금씩 늘려가면서 증가시킨 만큼 처리 성능이 늘어나는지 확인하고 만일 더이상 늘어나지 않거나 오히려 줄어들 경우 이를 해당 애플리케이션의 한계라고 생각하면 된다.

 

3. 환경 변수 설정 - Config Element

Config Element는 샘플러와 밀접하게 연관된 것으로, 추가하고자 하는 샘플러에 공통적인 설정 정보를 제공한다. 가장 대표적인 것이 테스트할 애플리케이션의 IP와 포트정보이다. 샘플러가 한두개면 상관없지만 상당히 많은 샘플러를 등록해야 한다면 반드시 Config Element를 통해 공통 정보를 설정해 두는 것이 유용하다.

 

예를 들면, HTTP Request Defaults의 경우, 테스트 플랜에 추가할 수도 있고 스레드 그룹에 추가할 수도 있는데 추가하는 곳의 위치에 따라 "HTTP Request Defaults"의 적용 범위가 결정된다. 예를 들어 스레드 그룹에 추가하였다면 해당 스레드 그룹에 정의되어 있는 "HTTP Request"에만 적용된다.

 

4. 테스트 대상 설정 - Sampler

Thread Group을 생성한 다음 할 일은 샘플러를 추가하는 것이다. 왼쪽의 Thread Group에서 마우스 오른쪽 버튼을 클릭하고 [Add]-[Sampler]-[HTTP Request]를 선택한다. 요청할 Server Name 혹은 IP와 포트번호를 기입하고 요청하고 POST 혹은 GET으로 전달할 파라미터 값을 [Parameters] 탭에 기입한다.

 

이외에 추가적으로 테스트할 내용이 있다면 계속해서 Thread Group에 HTTP Request 샘플러를 추가하면 된다. 샘플러 설정이 완료되었다면 JMeter를 이용해서 바로 성능 테스트를 시작할 수 있지만 이외에도 몇가지 정의할 수 있다.

 

5. 대기시간 설정 - 타이머

성능 테스트 시나리오를 작성할때 실제 동작과 유사하게 모델링을 해야 성능 테스트의 정확도를 높일 수 있다. JMeter에서는 동작사이의 대기시간을 타이머로 설정할 수도 있다. Thread Group에서 마우스 오른쪽 버튼을 클릭하고 [Add]-[Timer]-[Constant Timer]를 선택하면 된다. 이 화면에서 대기에 필요한 시가을 기입하면 실제 성능 테스트시 해당시간만큼 대기하였다가 다음 작업을 진행한다.

 

6. 테스트 상태 수집 - 리스너

리스너는 성능 테스트한 결과를 수집하는 역할을 하며 궁극적으로 리스너를 통해 모든 결과를 분석하고 테스트한 애플리케이션의 성능을 확인할 수 있다. 리스너는 결과 서버에서 응답한 정보를 토대로 결과 정보를 보여주거나 저장하는 역할을 하기 때문에 사전에 각 리스너에 대한 기능을 잘 이해하고 작성한 시나리오에 합당한 리스너를 선택해서 추가해야 한다. 테스트 시에는 Listener에서 보여주는 결과를 해석할 수 있는 능력이 필요하다.

 

7. 변수 설정 - Variable

JMeter에서 변수를 사용하는 방법을 알면 테스트 플랜을 작성할때나 실제 테스트를 수행할때 유용하게 사용할 수 있다. 특히 샘플러를 이용한 테스트에서 변수를 사용하지 않게 되면 POST 혹은 GET으로 전달하는 파라미터 값을 한개 밖에 사용할 수 없다. 이는 성능 테스트에 매우 큰 문제를 발생시키는데 대부분의 미들웨어나 데이터베이스가 같은 값으로 조회하면 캐싱 기능을 통해서 매우 빠르게 응답하기 때문이다.

 

때문에 테스트 수행시 적절하게 파라미터 값을 변경해가면서 성능 테스트를 하는 것이 일반적이다. 이러한 요구를 수횽하기 위해 JMeter는 CSV 파일을 이용해서 여러 개의 파라미터 데이터를 정의해서 사용할 수 있다.

 

JMeter에서 변수명에 대한 값을 참조할 때는 ${변수명} 형태로 사용한다. 여기서 변수명은 [CSV Data Set Config]에서 지정한 변수명과 일치해야 한다. 설정을 완료하면, JMeter 테스트 수행시 스레드가 CSV 파일의 데이터를 한줄씩 읽어가면서 테스트를 수행한다.

 

향후 변경의 소지가 높은 값들을 추가로 변수 처리해서 테스트 플랜을 작성하면 유용하다. 대표적인 것이 서버 주소와 포트 정보인데, 아무리 Config Elements의 HTTP Request Defaults를 이용해서 정의하더라도 이역시 해당 설정이 많으면 변경해야 하는 경우가 많다. 테스트 플랜에서 변수를 지정한 후에 해당 값을 사용하기 위해서 ${host_name}이나 ${service_port} 형태로 설정하면 변수에 설정된 값으로 치환해서 테스트가 실행된다. 

 

이 외에도 [Add]-[Config Element]-[User Defined Variables] 메뉴에서 정의할수도 있고 Random Variables처럼 특정 구간의 숫자 범위에 해당하는 값을 랜덤하게 취해서 사용하는 변수를 정의할 수도 있다.

 


테스트할 플랜을 모두 작성하였다면 이제 테스트를 실행할 수 있다. JMeter에서 테스트를 실행하는 방법은 로컬 테스트와 원격 테스트 2가지가 있다.

 

1. 로컬 테스트

로컬에서 실행한 JMeter에서 바로 대상 애플리케이션의 성능을 테스트하는 경우로 소규모 테스트를 하거나 테스트 플랜을 검증하는 목적으로 사용한다.

 

2. 원격 테스트

성능 테스트시 가급적이면 원격으로 운영되고 있는 서버와 같은 네트워크 내에서 테스트하는 것이 좋다. 그렇지 않으면 네트워크 병목이나 속도로 인해 정확한 수치를 확인하기 어렵기 때문이다. 때무에 좀더 정확한 정보나 대규모 부하 테스트를 할 경우 원격 테스트를 주로 사용한다.

 

성능 테스트는 정확한 전략과 절치 그리고 목표 없이 이루어지면 아무런 의미가 없다. 충분히 사전에 준비하고 고려한 내용을 바탕으로 성능 테스트 소프트웨어를 이용해서 테스트를 수행하고 튜닝을 반복해서 진행할 것을 권장한다.

 

JMeter는 웹기반 애플리케이션의 성능 테스트뿐만 아니라 다양한 프로토콜 기반의 부하를 발생시키고 이에 대한 결과를 그래픽하게 표현해주는 기능을 제공한다. 비록 상용 성능 테스트 도구에 비해서 부하 모델 설정이나 실시간 변경 등의 기능이 부족하지만 성능 테스트를 검증하고 이해하는데 충분히 적합한 도구이며 버전이 올라갈수록 기능이 계속 발전하고있어서 충분히 활용해볼 만한 좋은 도구이다.