Guicorn + Uvicorn worker process 수 조절로 부하테스트 진행해보기

김영상 (dudtkd1221)·2024년 12월 24일
0
post-thumbnail

개요

부하 테스트를 통해 FastAPI 웹 애플리케이션의 성능 최적화를 목적으로 진행한 내용입니다. 본 테스트는 Guicorn으로 Uvicorn의 워커 프로세스수를 조절하며 응답 속도를 비교하는 실험으로, 테스트느 AWS t2.medium instance 에서 진행했습니다.

테스트 목적

Guicorn으로 워커 프로세스(uvicorn) 수를 조정하여 응답 속도를 확인.

uvicorn 자체적으로도 workers수를 지정하여 multi-processing을 지원하지만 제공하는 기능들이 제한적이라 공식문서에서 gunicorn과 함께 사용할 것을 권장합니다.
https://www.uvicorn.org/#running-with-gunicorn

테스트 환경

환경

  • Framework: FastAPI
  • Web Server: Gunicorn, Uvicorn
  • Database: mongodb atlas
  • 서버: AWS t2.medium (2vCPU, 4GiB)
  • 부하 테스트 도구: k6
  • 데이터 시각화: Grafana, InfluxDB (Local 환경에서 Docker로 실행)

Docker Compose 설정

아래는 InfluxDB와 Grafana를 실행하기 위한 docker-compose.yml입니다.

version: "3.7"

services:
  influxdb:
    image: bitnami/influxdb:1.8.5
    container_name: influxdb
    ports:
      - "8086:8086"
      - "8085:8088"
    environment:
      - INFLUXDB_ADMIN_USER_PASSWORD=bitnami123
      - INFLUXDB_ADMIN_USER_TOKEN=admintoken123
      - INFLUXDB_HTTP_AUTH_ENABLED=false
      - INFLUXDB_DB=myk6db
  granafa:
    image: bitnami/grafana:latest
    ports:
      - "3000:3000"

대시보드 구성

Grafana 대시보드는 해당 링크에 있는 부하 테스트 템플릿을 사용했습니다.

테스트 구성

k6

k6의 options 객체를 사용해 테스트를 구성했습니다.
150명의 사용자가 동시에 요청하며, 요청은 20초간 지속됩니다.
(vus: 150, duration: 20s)

export const options = {
    vus: 150,
    duration: '20s',    
};

조회한 API

사용자가 소유한 책 목록을 토큰기반으로 조회하는 API입니다.

export default function() {
    // 그룹핑된 API 요청 테스트
    group('Books API Performance', () => {
        const params = {
            headers: {
                'Authorization': `Bearer ${USER_TOKEN}`,
                'Content-Type': 'application/json'
            }
        };

        const url = baseUrl + '/api/books';
        // 책 목록 조회 API 호출
        const bookResponse = http.get(url, params);

        // 응답 검증
        const checkResult = check(bookResponse, {
            'status is 200': (r) => r.status === 200,
        });


        // 약간의 대기 시간 (실제 사용자 행동 시뮬레이션)
        sleep(1);
    });
}

테스트 결과

Gunicorn의 worker process를 1부터 5까지 늘리면서 테스트를 진행한 결과값입니다.

gunicorn main:app -w "Number of workers"  -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000

1 worker process

2 worker process

4 worker process

5 worker process

워커 수평균 응답 시간 (mean)최대 응답 시간 (max)중앙값 응답 시간 (med)
11.87s3.29s1.93s
21.78s4.14s1.95s
41.50s2.28s1.27s
51.36s2.22s1.16s

분석 및 결론

워커 수를 증가시킬수록 평균 응답 시간(mean) 및 중앙값 응답 시간(median)이 점진적으로 감소하는 경향을 보였으며, 응답시간이 최적화되는 워커 설정은 4~5개가 나타남을 볼 수 있었습니다. 이는 권장되는 worker 개수인 (2 x $num_cores) + 1 과 유사합니다.

위 테스트를 통해 Guicorn의 워커 프로세스를 적절히 설정하면 응답 시간을 단축할 수 있다는 것을 알 수 있게 되었습니다.

profile
아직 배고프다

0개의 댓글