2.Artillery 사용

Alex·2024년 7월 1일
0

성능 개선

목록 보기
1/9

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분이나 걸렸다 ㄷㄷㄷ


리포트를 보면 지연시간이 치솟는 부분들이 보인다.

profile
답을 찾기 위해서 노력하는 사람

0개의 댓글