백엔드 서비스를 애플리케이션 부하 분산기와 통합하는 동안 부하 분산기가 없는 경우 백엔드 서비스의 성능을 자체적으로 측정하는 것이 중요합니다. 제어된 조건에서 부하 테스트를 실행하면 처리량 및 지연 시간과 같은 다양한 성능 측정기준 간의 용량 계획 절충점을 평가하는 데 도움이 됩니다. 신중하게 용량을 계획하더라도 실제 수요를 과소평가할 수 있으므로 부하 테스트를 사용하여 시스템이 과부하될 때 서비스 가용성이 어떤 영향을 받는지 사전에 확인하는 것이 좋습니다.
부하 테스트 목표
일반적인 부하 테스트는 여러 부하 측정기준에서 백엔드 서비스의 외부에 표시되는 동작을 측정합니다. 이 테스트와 가장 관련성이 높은 측정기준은 다음과 같습니다.
- 요청 처리량: 초당 제공된 요청 수입니다.
- 요청 동시 실행: 동시에 처리되는 요청 수입니다.
- 연결 처리량: 클라이언트에서 시작된 초당 연결 수입니다. 전송 계층 보안(TLS)을 사용하는 대부분의 서비스에는 요청 처리와 관계없이 각 연결과 연결된 일부 네트워크 전송 및 TLS 협상 오버헤드가 있습니다.
연결 동시 실행: 동시에 처리되는 클라이언트 연결 수입니다.
요청 지연 시간: 요청의 시작과 응답 종료 사이에 경과된 총 시간입니다.
오류율: 요청으로 인해 HTTP 5xx 오류 및 조기 종료된 연결과 같은 오류가 발생하는 빈도입니다.
부하가 걸린 서버의 상태를 평가하기 위해 부하 테스트 절차에서는 다음과 같은 내부 서비스 측정항목을 수집할 수도 있습니다.
시스템 리소스 사용: 일반적으로 CPU, RAM, 파일 핸들(소켓)과 같은 시스템 리소스는 백분율로 표시됩니다.
이러한 측정항목의 중요도는 서비스가 구현되는 방법에 따라 다릅니다. 애플리케이션은 리소스를 소진할 때 성능 저하, 부하 분산 또는 비정상 종료를 경험합니다. 따라서 호스트가 과부하 상태일 때 리소스의 가용성을 확인하는 것이 중요합니다.
다른 제한된 리소스 사용: 애플리케이션 레이어와 같이 부하가 걸렸을 때 고갈될 수 있는 비시스템 리소스입니다.
이러한 리소스의 몇 가지 예는 다음과 같습니다.
- 작업자 스레드 또는 프로세스의 제한된 풀입니다.
- 스레드를 사용하는 애플리케이션 서버의 경우 일반적으로 동시에 작동하는 작업자 스레드의 수를 제한합니다. 스레드 풀 크기 한도는 메모리와 CPU 소진을 방지하는 데 유용하지만 기본 설정은 매우 보수적인 경우가 많습니다. 한도가 너무 낮으면 시스템 리소스를 적절하게 사용하지 못할 수 있습니다.
- 일부 서버는 스레드 풀 대신 프로세스 풀을 사용합니다. 예를 들어 Apache 서버는 Prefork 멀티 처리 모델로 설정할 때 각 클라이언트 연결에 프로세스 하나를 할당합니다. 따라서 풀의 크기 한도에 따라 연결 동시 실행의 상한이 결정됩니다.
- 제한된 크기의 백엔드 연결 풀이 있는 다른 서비스에 프런트엔드로 배포된 서비스입니다.
용량 계획과 과부하 테스트 비교
부하 테스트 도구는 다양한 확장 측정기준을 개별적으로 측정하는 데 도움이 됩니다. 용량 계획의 경우 여러 측정기준에서 허용 가능한 성능에 대한 부하 임곗값을 결정합니다. 예를 들어 전체 서비스 요청의 절대 한도를 측정하는 대신 다음을 측정하는 것이 좋습니다.
- 지정된 밀리초 미만의 99번째 백분위수 지연 시간으로 서비스를 제공할 수 있는 요청 비율. 이 값은 서비스의 SLO로 지정됩니다.
- 시스템 리소스 사용률이 최적 수준을 초과하지 않는 최대 요청 비율. 최적의 사용률은 애플리케이션에 따라 다르며 100% 미만일 수 있습니다. 예를 들어 최대 메모리 사용률이 80%인 경우 애플리케이션은 최대 사용률이 99%인 경우보다 사소한 부하 급증을 더 잘 처리할 수 있습니다.
부하 테스트 결과를 사용하여 용량 계획 결정을 내리는 것도 중요하지만 부하가 용량을 초과할 때 서비스 작동 방식을 이해하는 것도 중요합니다. 과부하 테스트를 사용하여 자주 평가되는 일부 서버 동작은 다음과 같습니다.
부하 분산: 서비스에 과도한 수신 요청이나 연결이 수신되면 모든 요청을 지연하거나 일부 요청을 거부하여 나머지 요청에 대해 허용 가능한 성능을 유지할 수 있습니다. 응답을 수신하기 전에 클라이언트 시간 초과가 발생하지 않도록 하고 서버에서 요청 동시 실행을 낮춰 메모리 소진 위험을 줄이는 후자의 방법을 사용하는 것이 좋습니다.
리소스 소진에 대한 복원성: 서비스가 비정상 종료되면 대기 중인 요청이 더 이상 진행되지 않기 때문에 일반적으로 리소스 소진으로 인한 서비스의 비정상 종료는 발생하지 않습니다. 백엔드 서비스에 인스턴스가 많을 경우 개별 인스턴스의 안정성이 서비스의 전체 가용성을 위해 매우 중요합니다. 인스턴스가 비정상 종료 후 다시 시작되는 동안 다른 인스턴스에 더 많은 부하가 발생하여 잠재적으로 연쇄 실패가 발생할 수 있습니다.
일반 테스트 가이드라인
테스트 사례를 정의할 때는 다음 가이드라인을 고려하세요.
소규모 테스트 만들기
서버의 성능 제한을 측정하기 위한 소규모 테스트를 만듭니다. 과도한 서버 용량으로 인해 테스트를 통해 서비스 자체의 성능 제한을 발견할 수는 없겠지만 클라이언트 호스트 또는 네트워크 계층과 같은 다른 시스템의 병목 현상은 발견할 수 있습니다.
최상의 결과를 얻으려면 단일 가상 머신(VM) 인스턴스나 Google Kubernetes Engine(GKE) 포드를 사용하여 서비스를 독립적으로 테스트하는 테스트 사례를 참조하세요. 필요한 경우 서버의 최대 부하를 달성하기 위해 여러 VM을 사용할 수 있지만 성능 데이터 수집이 복잡해질 수 있습니다.
개방형 루프 로드 패턴 선택
대부분의 부하 생성기는 폐쇄형 루프 패턴을 사용하여 동시 요청 수를 제한하고 이전 요청이 완료될 때까지 새 요청을 지연시킵니다. 서비스의 프로덕션 클라이언트가 이러한 제한 동작을 나타내지 않을 수 있으므로 이 방법은 권장되지 않습니다.
반면 개방형 루프 패턴을 사용하면 부하 생성기가 서버 응답이 도달하는 속도와 상관없이 일정한 속도로 요청을 전송하여 프로덕션 부하를 시뮬레이션할 수 있습니다.
권장 부하 생성기를 사용하여 테스트 실행
백엔드 서비스의 부하 테스트에는 다음과 같은 부하 생성기를 사용하는 것이 좋습니다.
Nighthawk
Nighthawk는 Envoy 프로젝트와 함께 개발된 오픈소스 도구입니다. 이를 사용하여 클라이언트 부하를 생성하고 벤치마크를 시각화하며 HTTPS 서비스 부하 테스트 시나리오의 서버 성능을 측정할 수 있습니다.
HTTP/1 테스트
HTTP/1을 테스트하려면 다음 명령어를 사용합니다.
nighthawk_client URI \ --duration DURATION \ --open-loop \ --no-default-failure-predicates \ --protocol http1 \ --request-body-size REQ_BODY_SIZE \ --concurrency CONCURRENCY \ --rps RPS \ --connections CONNECTIONS
다음을 바꿉니다.
URI
: 벤치마킹할 URIDURATION
: 총 테스트 실행 시간(초)REQ_BODY_SIZE
: 각 요청의 POST 페이로드 크기CONCURRENCY
: 총 동시 이벤트 루프 수이 수는 클라이언트 VM의 코어 수와 일치해야 합니다.
RPS
: 이벤트 루프별 초당 대상 요청 비율CONNECTIONS
: 이벤트 루프당 동시 연결 수
아래 예시를 참조하세요.
nighthawk_client http://10.20.30.40:80 \ --duration 600 --open-loop --no-default-failure-predicates \ --protocol http1 --request-body-size 5000 \ --concurrency 16 --rps 500 --connections 200
각 테스트 실행의 출력은 응답 지연 시간의 히스토그램을 제공합니다. Nighthawk 문서의 예시에서 99번째 백분위수 지연 시간은 약 135마이크로초입니다.
Initiation to completion samples: 9992 mean: 0s 000ms 113us pstdev: 0s 000ms 061us Percentile Count Latency 0 1 0s 000ms 077us 0.5 4996 0s 000ms 115us 0.75 7495 0s 000ms 118us 0.8 7998 0s 000ms 118us 0.9 8993 0s 000ms 121us 0.95 9493 0s 000ms 124us 0.990625 9899 0s 000ms 135us 0.999023 9983 0s 000ms 588us 1 9992 0s 004ms 090us
HTTP/2 테스트
HTTP/2를 테스트하려면 다음 명령어를 사용합니다.
nighthawk_client URI \ --duration DURATION \ --open-loop \ --no-default-failure-predicates \ --protocol http2 \ --request-body-size REQ_BODY_SIZE \ --concurrency CONCURRENCY \ --rps RPS \ --max-active-requests MAX_ACTIVE_REQUESTS \ --max-concurrent-streams MAX_CONCURRENT_STREAMS
다음을 바꿉니다.
URI
: 벤치마킹할 URIDURATION
: 총 테스트 실행 시간(초)REQ_BODY_SIZE
: 각 요청의 POST 페이로드 크기CONCURRENCY
: 총 동시 이벤트 루프 수이 수는 클라이언트 VM의 코어 수와 일치해야 합니다.
RPS
: 각 이벤트 루프에 대한 초당 대상 요청 비율MAX_ACTIVE_REQUESTS
: 각 이벤트 루프에 대한 동시 활성 요청의 최대 개수MAX_CONCURRENT_STREAMS
: 각 HTTP/2 연결에 허용되는 최대 동시 스트림 수
아래 예시를 참조하세요.
nighthawk_client http://10.20.30.40:80 \ --duration 600 --open-loop --no-default-failure-predicates \ --protocol http2 --request-body-size 5000 \ --concurrency 16 --rps 500 \ --max-active-requests 200 --max-concurrent-streams 1
ab(Apache 벤치마크 도구)
ab
는 Nighthawk보다 유연성은 떨어지지만 거의 모든 Linux 배포판에서 패키지로 사용할 수 있습니다. ab
는 빠르고 간단한 테스트에만 권장됩니다.
ab
를 설치하려면 다음 명령어를 사용하세요.
- Debian 및 Ubuntu의 경우
sudo apt-get install apache2-utils
를 실행합니다. - RedHat 기반 배포판에서는
sudo yum install httpd-utils
를 실행합니다.
ab
를 설치한 후 다음 명령어를 사용하여 실행합니다.
ab -c CONCURRENCY \ -n NUM_REQUESTS \ -t TIMELIMIT \ -p POST_FILE URI
다음을 바꿉니다.
CONCURRENCY
: 실행할 동시 요청 수NUM_REQUESTS
: 실행할 요청 수TIMELIMIT
: 요청에 소비할 최대 시간(초)POST_FILE
: HTTP POST 페이로드가 포함된 로컬 파일URI
: 벤치마킹할 URI
아래 예시를 참조하세요.
ab -c 200 -n 1000000 -t 600 -P body http://10.20.30.40:80
위 예시의 명령어는 동시 실행이 200개(폐쇄형 루프 패턴)인 요청을 전송하며, 1,000,000(100만)개의 요청 또는 600초 경과 후 중지됩니다. 이 명령어에는 body
파일의 콘텐츠도 HTTP POST 페이로드로 포함됩니다.
ab
명령어는 Nighthawk와 비슷한 응답 지연 시간 히스토그램을 생성하지만 해상도가 마이크로초가 아닌 밀리초로 제한됩니다.
Percentage of the requests served within a certain time (ms) 50% 7 66% 7 75% 7 80% 7 90% 92 95% 121 98% 123 99% 127 100% 156 (longest request)