https://www.artillery.io/docs/get-started/get-artillery
여기서 사용법을 확인하면 된다.
우선, Artillery는 Node.js로 만들어졌기 때문에 노드를 설치해야 한다.
강사님께서는 최신버전보다는
npm install -g artillery@1.7.6
이 버전을 사용하는 게 좀더 좋다고 말씀하셨다.
https://www.artillery.io/docs/get-started/first-test
이걸 보면서 테스트 스크립트를 작성할 수 있다.
test-config.yaml
config:
target: 'http://localhost:8080' //스트레스 테스트를 할 호스트 정보
phases:
- duration: 60 //60초 동안
arrivalRate: 5 //1초동안 5개의 처리량
scenarios:
- flow:
- get:
url: "/hello"
//시나리오에서는 get요청을 첫번째
artillery run --output report.json test-config.yaml
테스트를 진행하는 명령어
테스트를 진행하면 이렇게 json 파일이 생성된다.
이 파일을 html로 만들려면 artillery report report.json --output report.html
를 입력하면 된다.
summary부분을 보면
test duration이 70초로 나온다. 설정은 60초로 했지만
요청이 가고 좀 뒤에 응답이 오는 경우들까지 포함이돼서 테스트의 전체 시간이 늦어진 것이다.
그 아래에는 생성된 시나리오와 응답까지 온 시나리오가 나온다.
응답이 안오면 completed에는 기록이 안될 수 있다.
code에는 200응답이 300개가 나왔다는 기록이 있다.
지연시간에 대한 기록이다. p95는 95%는 저 범위 안에서 들어왔다는 의미다.
아래축은 시간, 위축은 지연시간이다. 각각의 시간대마다 지연시간이 어느정도인지를 보여준다.
초당 5개씩의 요청이 왔다는 걸 보여준다.
테스트 시나리오를 변경해보자.
config:
target: 'http://localhost:8080'
phases:
- duration: 10
arrivalRate: 5
- duration: 10
arrivalRate: 20
- duration: 30
arrivalRate: 100
- duration: 10
arrivalRate: 20
scenarios:
- flow:
- get:
url: "/hello"
부하를 많이 받을 때는 최대 100ms가 넘어가기도 했다.
max값도 크게 올랐다.
config:
target: 'http://localhost:8080'
phases:
- duration: 30
arrivalRate: 3
name: Warm up //이름을 붙여줌
- duration: 30
arrivalRate: 3
rampTo: 30 //처음에는 3으로 했다가 점점 요청횟수를 늘려서 최종 30회까지 요청가게 하는 것
name: Ramp up load
- duration: 60
arrivalRate: 30
name: Sustained load
- duration: 30
arrivalRate: 30
rampTo: 10
name: End of load
scenarios: //한명의 사용자가 어떤 순서대로 요청을 할 것인지
- name: "login and use some functions"
flow: //로그인+펑션 사용
- post:
url: "/login"
- get:
url: "/some-function-one"
- get:
url: "/some-function-two"
- name: "just login" //로그인만 한다.
flow:
- post:
url: "/login"
쉽게 생각하면
phase에서는 초당 몇명의 유저가 들어오는지를 정한다.
그리고 시나리에서 이 유저들이 각각 어떤 행동을 할지 정한다.
숫자가 애매하게 떨어지는건 ramp up, ramp down 기능 때문이다.
부하를 크게 주지는 않았기 때문에 지연시간이 확 튀어오르는 구간은 없다.
config:
target: 'http://localhost:8080'
phases:
- duration: 30
arrivalRate: 3
name: Warm up
# - duration: 30
# arrivalRate: 3
# rampTo: 30
# name: Ramp up load
# - duration: 60
# arrivalRate: 30
# name: Sustained load
# - duration: 30
# arrivalRate: 30
# rampTo: 10
# name: End of load
scenarios:
- name: "login and use some functions"
flow:
- post:
url: "/login"
- get:
url: "/some-function-one"
- get:
url: "/some-function-two"
- name: "just login"
flow:
- post:
url: "/login"
이렇게 요청을 하면 3개 요청이 시나리오 2개로 나눠서 갈까 아니면
시나리오 2개*요청 3개가 될까?
총 요청이 180개가 온 것을 알 수 있다.
초당 3개의 요청이 30초간 갔으니 90개여야 하는데
시나리오별로 요청이 간 것을 확인할 수 있다.
이 csv 파일을 활용해서 테스트를 진행한다.
이러한 userid와 password가 파라미터로 들어가도록 테스트를 진행할 것이다.
config:
target: 'http://localhost:8080'
phases:
- duration: 30
arrivalRate: 3
name: Warm up
payload:
path: "id-password.csv"
fields: //첫번쨰 부분을 id로 두번째 부분을 passoword로 지정한 것
- "id"
- "password"
scenarios:
- name: "just login"
flow:
- post:
url: "/login-with-id-password"
json:
id: "{{ id }}" //공백 생략하면 작동 안함
password: "{{ password }}"
로그에 이렇게 기록이 남도록 했다.
@RestController
public class HighLoadController {
@RequestMapping(value = "/high-load-cpu", method = RequestMethod.GET)
public int highLoadCpu() {
int sum = 0;
// 랜덤한 수를 뽑아서 더하는 연산
for (int i = 0; i < 20_000_000; i++) {
int randomInt = ThreadLocalRandom.current().nextInt();
sum = sum + randomInt;
}
return sum;
}
@RequestMapping(value = "/high-load-memory", method = RequestMethod.GET)
public int highLoadMemory() {
ArrayList<Integer> memoryIntensiveList = new ArrayList<>();
for (int i = 0; i < 500_000; i++) {
// int를 추가하는 과정에서 새로운 Integer 래퍼 클래스 인스턴스 생성
memoryIntensiveList.add(i);
}
return memoryIntensiveList.size();
}
}
테스트를 돌려보니 자그마치 10분이나 걸렸다 ㄷㄷㄷ
리포트를 보면 지연시간이 치솟는 부분들이 보인다.