Taurus
타우르스는 애플리케이션 부하 테스트를 자동화 하는데 도움을 주는 오픈소스 프레임워크 입니다. 다양한 executor(jmeter, selenium, gatling, junit 등등)를 지원하며 각자의 환경과 시나리오에 적합한 executor를 자유롭게 선택하여 사용할 수 있습니다.(https://gettaurus.org/docs/ExecutionSettings/) docker를 지원하여 쉽고 빠르게 테스팅 환경을 구성할 수 있으며 테스트 결과 Metric을 Blazemeter와 연동하여 멋진 보고서도 제공 받을 수 있습니다.
테스트 환경 구성
docker를 이용하여 테스트를 수행하므로 docker를 사용할 수 있는 환경이라면 어디서든 부하 테스트가 가능합니다. 실습에서는 mac 환경에서 테스트를 수행하였습니다. 아래와 같이 테스트를 진행할 작업 디렉터리를 생성하고 하위에 docker-compose.yml을 생성 합니다. 서버에서 실행할 경우 docker-compose내의 volumes directory를 환경에 맞게 수정하여 사용하면 됩니다.
작업 디렉터리 생성
artifacts – 테스트에 의해 런타임에 생성되는 파일(로그, 테스트결과 등..)이 위치하는 디렉터리 입니다.
script – 테스트 시나리오가 위치하는 디렉터리 입니다.
./taurus ├── artifacts ├── docker-compose.yml └── script
docker-compose.yml 생성
version: '3.7' services: taurus: # service name image: blazemeter/taurus # image 설정 # network_mode: host ulimits: # 프로세스의 자원 한도를 설정 nproc: 65535 # User당 사용할 수 있는 프로세스 최대 개수 nofile: # User당 오픈할 수 있는 파일 개수 soft: 90000 # soft 설정 hard: 90000 # hard 설정 sysctls: net.ipv4.ip_local_port_range: 1025 65000 # port 범위 설정 volumes: - /Users/happydaddy/taurus/script:/bzt-configs # bizt-configs 볼륨 설정 - /Users/happydaddy/taurus/artifacts:/tmp/artifacts # artifacts 볼륨 설정 (테스트 로그 및 결과)
테스트 시나리오 작성
script 디렉터리 하위에 테스트 시나리오를 작성합니다.
execution: - concurrency: 10 ramp-up: 1m hold-for: 1m scenario: quick-test scenarios: quick-test: requests: - http://blazedemo.com
테스트 실행
docker-compose를 실행하면 taurus docker 환경이 자동으로 구성되며 sample-test.yml에 작성한 시나리오가 실행됩니다. -report 인자를 추가하면 테스트 완료 후에 blazemeter로 metric을 전송하여 웹 보고서를 생성 할 수 있습니다.
$ docker-compose run --rm taurus sample-test.yml -report Creating network "taurus2_default" with the default driver Creating taurus2_taurus_run ... done 11:04:03 INFO: Taurus CLI Tool v1.15.3 11:04:03 INFO: Starting with configs: ['sample-test.yml'] 11:04:03 INFO: Configuring... 11:04:03 INFO: Artifacts dir: /tmp/artifacts 11:04:03 INFO: Preparing... 11:04:12 INFO: Waiting for finish...r updates 11:04:21 INFO: Changed data analysis delay to 5s, will upload anonymously 11:04:39 INFO: Changed data analysis delay to 4s 11:04:40 INFO: Changed data analysis delay to 5s 11:04:47 INFO: Changed data analysis delay to 4s 11:06:17 WARNING: Please wait for graceful shutdown...ter.com/app/?public-token=BV7LKqoYmNaMlu7GRTNmz7ggKxSW5M9msegKtxi7MPR43u2xnm#reports/r-ext-6194e1abbf84d654189135/11:06:17 INFO: Shutting down... 11:06:17 INFO: Post-processing... in browser: could not locate runnable browser 11:06:17 INFO: Test duration: 0:02:06 11:06:17 INFO: Samples count: 546, 0.00% failures 11:06:17 INFO: Average times: total 1.669, latency 0.297, connect 0.036 11:06:17 INFO: Percentiles: ┌───────────────┬───────────────┐ │ Percentile, % │ Resp. Time, s │ ├───────────────┼───────────────┤ │ 0.0 │ 1.387 │ │ 50.0 │ 1.661 │ │ 90.0 │ 1.847 │ │ 95.0 │ 1.948 │ │ 99.0 │ 2.1 │ │ 99.9 │ 2.382 │ │ 100.0 │ 2.382 │ └───────────────┴───────────────┘ 11:06:17 INFO: Request label stats: ┌──────────────────────┬────────┬─────────┬────────┬───────┐ │ label │ status │ succ │ avg_rt │ error │ ├──────────────────────┼────────┼─────────┼────────┼───────┤ │ http://blazedemo.com │ OK │ 100.00% │ 1.669 │ │ └──────────────────────┴────────┴─────────┴────────┴───────┘ 11:06:17 INFO: Sending remaining KPI data to server... 11:06:18 INFO: Ending data feeding... 11:06:19 INFO: Online report link: https://a.blazemeter.com/app/?public-token=BV7LKqoYmNaMlu7GRTNmz7ggKxSW5M9msegKtxi7MPR43u2xnm#reports/r-ext-6194e1abbf84d654189135/summary 11:06:19 INFO: Artifacts dir: /tmp/artifacts 11:06:19 INFO: Done performing with code: 0
테스트 결과 확인
console log에 간략하게 테스트 결과가 표시됩니다. artifacts 디렉터리 하위에는 테스트 결과물이 생성되므로 필요한 내용을 열어서 확인할 수 있습니다.
$ cd artifacts $ ls -lt | more total 328 -rw-r--r-- 1 happydaddy staff 30554 11 17 20:06 bzt.log -rw-r--r-- 1 happydaddy staff 6256 11 17 20:06 effective.json -rw-r--r-- 1 happydaddy staff 5053 11 17 20:06 effective.yml -rw-r--r-- 1 happydaddy staff 9347 11 17 20:06 jmeter.log -rw-r--r-- 1 happydaddy staff 308 11 17 20:06 jmeter.out -rw-r--r-- 1 happydaddy staff 83 11 17 20:06 error.jtl -rw-r--r-- 1 happydaddy staff 62066 11 17 20:06 kpi.jtl -rw-r--r-- 1 happydaddy staff 0 11 17 20:04 jmeter.err -rw-r--r-- 1 happydaddy staff 6023 11 17 20:04 modified_requests.jmx -rw-r--r-- 1 happydaddy staff 322 11 17 20:04 jmeter-bzt.properties -rw-r--r-- 1 happydaddy staff 23 11 17 20:04 system.properties -rw-r--r-- 1 happydaddy staff 4056 11 17 20:04 requests.jmx -rw-r--r-- 1 happydaddy staff 148 11 17 20:04 sample-test.yml -rw-r--r-- 1 happydaddy staff 213 11 17 20:04 merged.json -rw-r--r-- 1 happydaddy staff 152 11 17 20:04 merged.yml
BlazeMeter Report
console에 출력된 Online report link를 브라우저에서 실행하면 상세한 내용을 담고 있는 blazemeter 보고서를 확인 할 수 있습니다. blazemeter url은 일정기간만 유지되므로 필요한 데이터는 백업해 두도록 합니다.
Online report link: https://a.blazemeter.com/app/?public-token=BV7LKqoYmNaMlu7GRTNmz7ggKxSW5M9msegKtxi7MPR43u2xnm#reports/r-ext-6194e1abbf84d654189135/summary
테스트 환경 구성과 테스트 실행 그리고 보고서 작성까지 taurus를 사용하면 정말 빠르고 간단하게 부하 테스트를 수행할 수 있습니다. 개발자는 테스트 시나리오 작성에만 신경을 쓰고 집중할 수 있게 됩니다.
Taurus Script 작성
실습에서는 yaml을 이용하여 test script를 작성하는 방법에 대해서 간략히 알아보겠습니다.
https://gettaurus.org/docs/ExecutionSettings/
Execution
테스트 시나리오 실행 방법을 정의합니다.
- concurrency: 동시 사용자 수
- ramp-up: concurrency 설정에 도달하는 시간
- hold-for: 동시 사용자 수 유지 시간
- throughput: 처리량 제한
example
총 테스트시간 : 대략 3분30초 = ramp-up(1분) + hold-for(2분30초)
ramp-up 시간 : 1분 동안 사용자 수를 concurrency 10까지 증가시킨다.
hold-for 시간 : 설정한 concurrency 수까지 되면 2분 30초간 테스트를 유지한다.
execution: - concurrency: 10 hold-for: 2m30s ramp-up: 1m scenario: requests: - url: http://blazedemo.com/
10명의 가상 사용자는 초당 40개 미만의 요청을 제공합니다
throughput 설정 추가하면 초당 요청 속도를 제한 할 수 있습니다.
execution: - concurrency: 10 hold-for: 2m30s ramp-up: 1m throughput: 5 scenario: requests: - url: http://blazedemo.com/
- 60초에 걸쳐 부하를 1에서 5 RPS로 증가(램프 업)
- 150초 동안 5RPS로 하중 유지(hold-for)
Scenarioes 구성
여러개의 시나리오를 구성하여 수행할 수 있습니다. Data-Source 설정으로 동적 데이터를 설정할 수 있습니다.
input-data.csv
컴마(,)로 구분된 데이터 셋을 준비합니다.
40,-EPISODE_UPDATE,appId-1,Z2luU3RhdHVzIjoiQUNUSVZFIn0.cV4Nn7HAZyZE1CtaWvSQQObed4EbGXAKbdOWC0-2Gfc 31,-CONTENT_SUBSCRIBE,appId-2,jAuMSIsImxvZ2luU3RhdHIn0.RqFDk-5DhmnZqQ8SfQBW1cpWsmFdh1fu84ZUizouLLo 31,-CONTENT_SUBSCRIBE,appId-3,OTIuMTY4LjAuMSIsISVZFIn0.TkKl12UsSZvKreKPwNHtfASP3Z7LpcSZJhAr-wTK__o 48,-EPISODE_UPDATE,appId-4,vZ2luU3RhdHVzIjoiQUNUSVZFIn0.YNgpMeZPUyth_HwVsCWQTMiA6afrs33CR7I0OgIDCbI 32,-CONTENT_SUBSCRIBE,appId-5,LuU3RhdHVzIjoiQUNUSVZFIn0.r1GIzwUCKe12A4cqyHqmt8D3wLAHW_QgytrZUvy6tFE 42,-CONTENT_SUBSCRIBE,appId-6,luU3RhdHVzIjoiQUNUSVZFIn0.7XpgjXbXClmyIjpu7w0uAe1oMC-KJ3AIET5nyo7VeHg
execution: - concurrency: 10 ramp-up: 1m hold-for: 1m scenario: Review-Read - concurrency: 10 ramp-up: 1m hold-for: 1m scenario: Review-Update scenarios: Review-Read: default-address: http://localhost:8080 requests: - url: /v1/my-review?episodeId=${content_id} headers: Authorization: ${token} data-sources: - path: input-data.csv delimiter: ',' quoted: false encoding: "utf-8" loop: true variable-names: content_id,direction,appId,token random-order: true Review-Update: default-address: http://localhost:8080 requests: - url: /v1/reviews method: PUT headers: Authorization: ${token} Content-Type: application/json body-file: data/review.json data-sources: - path: input-data.csv delimiter: ',' quoted: false encoding: "utf-8" loop: true variable-names: content_id,direction,appId,token random-order: true
Jmeter 사용하는 경우 Function을 이용하여 동적으로 데이터를 생성할 수도 있습니다.
Apache JMeter – User’s Manual: Functions and Variables
execution: - concurrency: 10 ramp-up: 1m hold-for: 1m scenario: Subscription-Read - concurrency: 10 ramp-up: 1m hold-for: 1m scenario: Subscription-Read-Random-Offset scenarios: Subscription-Read: default-address: http://localhost:8080 requests: - url: /v1/subscriptions?offset=${__jexl2(30 * ${__counter(TRUE)})}&limit=10&sort=${direction} headers: Authorization: ${token} data-sources: - path: input-data.csv delimiter: ',' quoted: false encoding: "utf-8" loop: true variable-names: content_id,direction,appId,token random-order: true Subscription-Read-Random-Offset: default-address: http://localhost:8080 requests: - url: /v1/subscriptions?offset=${__Random(00000,10000)}&limit=10&sort=${direction} headers: Authorization: ${token} data-sources: - path: input-data.csv delimiter: ',' quoted: false encoding: "utf-8" loop: true variable-names: content_id,direction,appId,token random-order: true
artifacts에 생성되는 결과 디렉터리 형식 지정
taurus 기본 설정으로 테스트를 수행하면 artifacts 디렉터리에 날짜로 디렉터리가 생성되고 하위에 관련 결과들이 저장됩니다.
$ cd artifacts $ ls 2021-05-22_14-16-34.949830 2021-05-20_09-33-23.239777 2021-05-22_13-20-49.508754 2021-05-20_09-32-06.374985 2021-05-21_08-56-01.344775 2021-05-20_09-29-45.010591 2021-05-21_08-24-38.006128 2021-05-20_09-28-25.643505 2021-05-20_15-36-37.393026 2021-05-20_09-16-35.951538
서비스별로 인지하기 쉽도록 결과 디렉터리 형식을 지정할 수 있습니다.
execution: // 이하 생략 scenarios: // 이하 생략 settings: artifacts-dir: /tmp/artifacts/subscription-%Y-%m-%d_%H-%M-%S.%f
$ cd artifacts $ ls subscription-2021-05-22_14-16-34.949830 subscription-2021-05-20_09-33-23.239777 subscription-2021-05-22_13-20-49.508754 subscription-2021-05-20_09-32-06.374985 subscription-2021-05-21_08-56-01.344775 subscription-2021-05-20_09-29-45.010591 subscription-2021-05-21_08-24-38.006128 subscription-2021-05-20_09-28-25.643505 subscription-2021-05-20_15-36-37.393026 subscription-2021-05-20_09-16-35.951538