Home 선착순 쿠폰 발급 시스템 (3) LOCUST 부하 테스트 구축
Post
Cancel

선착순 쿠폰 발급 시스템 (3) LOCUST 부하 테스트 구축

부하 테스트 LOCUST 구축

LOCUST ?

로커스트는 HTTP 및 기타 프로토콜을 위한 오픈 소스 성능/부하 테스트 도구로 사용하기 편하며, 스크립트로 작성 및 확장 가능하다.

  • 테스트 시나리오를 파이썬 코드로 작성이 가능하다.

  • 분산환경에서 확장이 가능하다. (많은 부하를 테스트 할때 부하를 발생시키는 서버를 여러대로 해서 테스트 가능)

  • 웹 기반 UI를 제공해서 테스트 결과나 진행 사항을 차트나 표로 볼 수 있다.

구현 방법

  1. /coupon-management-system/load-test/docker-compose.yml로 구성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version: '3.7'
services:
  master:
    image: locustio/locust
    ports:
      - "8089:8089"
    volumes:
      - ./:/mnt/locust
    command: -f /mnt/locust/locustfile-hello.py --master -H http://host.docker.internal:8080

  worker:
    image: locustio/locust
    volumes:
      - ./:/mnt/locust
    command: -f /mnt/locust/locustfile-hello.py --worker --master-host master

서비스

Locust 컨테이너를 실행하는 두 개의 서비스가 있다.

1. master

  • image: locustio/locust: 분산 로드 테스트를 위한 공식 Locust 이미지를 사용함.

  • ports: - "8089:8089": 컨테이너의 포트 8089를 호스트 머신의 동일한 포트에 노출함. 이를 통해 웹 브라우저에서 Locust 웹 인터페이스에 접근할 수 있다.

  • volumes: - ./:/mnt/locust: 현재 디렉토리(docker-compose.yml 파일이 있는 디렉토리)를 컨테이너 내의 /mnt/locust에 연결. 이를 통해 컨테이너는 Locust 테스트 파일에 접근할 수 있다.

  • command: -f /mnt/locust/locustfile-hello.py --master -H http://host.docker.internal:8080

    :

    • -f /mnt/locust/locustfile-hello.py - 제공된 Locust 파일을 실행한다.
    • --master - 이 컨테이너를 Locust 클러스터의 마스터 노드로 지정.
    • -H http://host.docker.internal:8080 - 로드 테스트의 대상 URL을 설정. (host.docker.internal에 대한 중요한 참고 사항은 아래를 참조.)

2. worker

  • image: locustio/locust: 마스터와 동일한 Locust 이미지.

  • volumes: - ./:/mnt/locust: Locust 테스트 파일에 대한 접근 권한을 위해 동일한 디렉토리를 연결.

  • command: -f /mnt/locust/locustfile-hello.py --worker --master-host master

    :

    • -f /mnt/locust/locustfile-hello.py - 동일한 Locust 파일을 실행.
    • --worker - 이 컨테이너를 작업자 노드로 지정.
    • --master-host master - 작업자가 ‘master’라는 이름의 마스터 노드(master 서비스에서 정의됨)에 연결하도록 지시.

핵심 포인트

  • 분산 로드 테스트: 이 설정을 통해 마스터가 조율하는 여러 작업자 노드에서 대규모 부하를 시뮬레이션할 수 있다.
  • Locustfile: 현재 디렉토리에 locustfile-hello.py라는 이름의 파일이 있어야 하며, 이 파일은 Locust가 실행할 실제 테스트 케이스를 포함해야 한다..
  • UI에 접근: 웹 브라우저에서 http://localhost:8089를 열면 Locust 제어판에 접근할 수 있다.
  • host.docker.internal: 이 특정 호스트 이름은 일반적으로 Docker 컨테이너 내에서 호스트 머신에 접근하도록 합니다. 운영 체제에 따라 조정이 필요할 수 있다.
  1. locustfile-hello.py 생성 부하 테스트 작성
1
2
3
4
5
6
7
8
9
from locust import task, FastHttpUser

class HelloWorld(FastHttpUser):
    connetcion_timeout = 10.0
    network_timeout = 10.0

    @task
    def hello(self):
        self.client.get("/hello")

Locustfile 분석

임포트

  • from locust import task, FastHttpUser

    Locust 라이브러리에서 필수 구성 요소를 가져옴.

    • task: 함수를 Locust 작업(시뮬레이션된 사용자가 수행하는 작업)으로 표시하는 데코레이터.
    • FastHttpUser: HTTP 사용자 행동을 시뮬레이션하기 위한 전문 클래스.

클래스 정의

  • class HelloWorld(FastHttpUser): HelloWorld라는 Locust 사용자 클래스를 정의함. 이 클래스는 FastHttpUser로부터 동작을 상속받는다.

타임아웃 설정

  • connection_timeout = 10.0: 대상 서버에 대한 새 연결을 설정할 때 최대 대기 시간(10초)을 설정함.
  • network_timeout = 10.0: 연결이 설정된 후 서버 응답을 기다리는 최대 시간(10초)을 설정함.

작업 정의

  • @task: 이 데코레이터는 hello 함수를 Locust 작업으로 지정.
  • def hello(self):: hello라는 작업 함수를 정의함. self 인수는 시뮬레이션된 사용자 인스턴스를 나타낸다.
  • self.client.get("/hello"): 작업 내에서 사용자는 대상 서버의 /hello 엔드포인트에 GET 요청을 한다. 이것은 FastHttpUser가 제공하는 내장 client 객체를 사용하여 수행됨.

요약

이 Locust 파일은 다음과 같은 간단한 사용자 동작을 시뮬레이션함.

  1. 사용자 인스턴스화: Locust가 시작되면 HelloWorld 클래스의 인스턴스를 생성함. 각 인스턴스는 가상 사용자를 나타낸다.
  2. 작업: 각 가상 사용자는 hello 작업을 반복적으로 실행한다.
  3. HTTP 요청: hello 작업은 사용자에게 대상 시스템의 /hello 엔드포인트에 GET 요청을 보내도록 지시한다.
  4. 타임아웃: 연결 및 네트워크 타임아웃은 서버에 문제가 있는 경우 테스트가 무한정 중단되지 않도록 함.

Locust가 이 파일을 사용하는 방법

  • Locust 테스트를 실행하면 Locust는 이 파일을 읽고 시뮬레이션된 사용자 동작을 이해함.
  • Locust는 HelloWorld 사용자의 많은 인스턴스를 생성.
  • 이러한 가상 사용자는 /hello에 지속적으로 GET 요청을 보내 대상 시스템에 부하를 가한다.

LOCUST 실행

  • localhost:8089로 접속하여 로커스트를 실행한다.

image

Number of Users는 최대 사용자 수를 말한다.

Ramp Up은 초당 증가하는 사용자 부하 사용자 수 이고, Host는 부하를 수행할 주소이다.

테스트 전 부하 서버를 늘리기 위해(부하 서버 분산 환경 설정) 아래와 같이 도커 컴포즈의 워커수를 스케일 해준다.

1
$ docker-compose up -d --scale worker=3

image

  • 부하 워커가 3개가 되면서 총 1000명의 유저에 대해 3/1로 분담하여 부하를 주고 있다. (단일 워커 일때 cpu가 100이상 사용되어 제대로 된 부하를 주지 못한다.)

부하 테스트 결과

image

  • Type : HTTP 메소드
  • Name: 호출한 URL
  • Requests: URL 호출 요청 횟수
  • Fails: URL 호출 후 실패 횟수
  • Median(ms): 응답에 대한 중앙 시간 값
  • 95%lie (ms): 95% 하위 느린 응답 시간 값
  • Average (ms): 평균 응답 시간 값
  • Min (ms): 최소 응답 시간 값
  • Max (ms): 최대 응답 시간 값
  • Current RPS: 현재 초당 몇건의 요청을 처리하는지 나타내는 지표
  • Current Failures/s: 현재 초당 실패 횟수

차트 지표

image

image

위 내용을 차트로 보게되면 시간에 따른 RPS와 실패 내역을 알수 있고, 평균 응답 시간 값과 95% 하위 응답 시간 값 마지막으로 시간에 따른 사용자 수를 한 눈에 볼수 있다.

Locust Report

  • 부하 테스트 결과를 리포트 형식으로 다운로드 가능하다.

image

  • 간단히 보면 언제 부터 언제까지 실행한 결과이며, 어떤 호스트를 타켓으로 했는지, 스크립트는 어떤 스크립트를 사용하였는지를 알려준다.
  • 또한 관련된 statistics 정보와 차트를 보여준다.

번외

  • 만약 요청한 target의 웹서버에서 초당 처리량을 제한을 둔다면 어떻게 될까?
  • 예를 들어 초당 요청에 대해 threads.sleep(500) 즉, 초당 2건의 요청을 처리하도록 제한을 둔다면
  • 아래는 총 사용자 5000명에 대해 초당 100명의 사용자가 증가할때 그래프이다.

image

  • 그래프를 보면 사용자가 증가하면서 어느순간 실패가 증가하면서 응답시간이 10000ms로 증가하는 걸 볼수 있다. 즉 사용자가 증가함에 따라 타임아웃이 발생하면서 서버가 터진걸 볼 수 있다.
  • 따라서 사용자 수에 따라 처리량을 제안하는 방법은 위험하고 대규모 시스템에서는 사용자 대비 처리량을 증가 시키는 방법에 대한 고민이 필요하다.

선착순 쿠폰 발급 시스템 (2) 환경 구성

쿠키, 세션, 토큰, 캐시, CDN