스레드(Thread)

[Test] HTTP 부하 테스트 도구 'hey'를 사용한 성능 측정

Stark97 2024. 9. 29. 23:31
반응형


 

 

http 테스팅 툴 hey 사용하기

 

1. hey가 뭘까?

hey는 Go 언어로 개발된 간단한 HTTP 부하 테스트 도구다. 원래 rakyll/boom으로 알려졌지만, 이후에 hey로 이름이 변경되었다. 이 도구는 웹 서버의 처리 능력을 테스트하고 성능 병목 현상을 식별하는 데 유용하다.

 

깃허브 주소

  • 아래 깃허브에 소스코드가 공개되어 있다. README를 읽어보는 것도 도움이 될 것이다.
 

GitHub - rakyll/hey: HTTP load generator, ApacheBench (ab) replacement

HTTP load generator, ApacheBench (ab) replacement. Contribute to rakyll/hey development by creating an account on GitHub.

github.com

 

hey의 주요 특징

  • 간편한 설치: Go 언어로 작성되어 있어 설치가 간단하다.
  • 사용하기 쉬운 명령어: 직관적인 CLI 인터페이스를 제공한다.
  • 높은 성능: 다수의 동시 연결을 효율적으로 처리할 수 있다.
  • 결과의 가시성: 상세한 응답 시간과 에러율 등의 통계를 제공한다.

 

2. hey 설치방법

macOS에서 설치

  • brew를 사용해서 설치 가능하다. (brew 설치가 되어있어야 사용 가능하다.)
brew install hey

Linux에서 설치 (Go)

  • Go 언어가 설치되어 있는 경우
go install github.com/rakyll/hey@latest

Linux에서 설치 (wget)

  • Go 언어가 없는 경우, 바이너리를 직접 다운로드하여 사용할 수 있다.
// 최신 릴리스를 확인하여 적절한 바이너리를 다운로드합니다.
wget https://hey-release.s3.us-east-2.amazonaws.com/hey_linux_amd64

// 다운로드한 파일에 실행 권한을 부여합니다.
chmod +x hey_linux_amd64

// 실행 파일을 시스템 경로에 이동시킵니다.
sudo mv hey_linux_amd64 /usr/local/bin/hey

// 설치 확인
hey -help

Windows에서 설치 (Go)

  • Windows에서는 WSL(Windows Subsystem for Linux)을 사용하거나, Go 환경을 구성한 후 설치할 수 있다.
  • Go 언어를 설치하고 명령 프롬프트나 PowerShell에서 다음 명령어를 실행한다.
go install github.com/rakyll/hey@latest
  • 이후 Go의 bin 디렉터리가 시스템 PATH에 포함되어 있는지 확인한다.

Windows에서 설치 (wget)

  • 최신 릴리스의 Windows용 바이너리를 다운로드한다.
wget https://hey-release.s3.us-east-2.amazonaws.com/hey_windows_amd64

 

3. hey 사용법

기본 명령어 구조

hey [옵션] [URL]

주요 옵션 설명

  • -n: 총 요청 수를 지정하며 기본값은 200이다.
-n 1000
  • -c: 동시에 실행할 worker의 수를 지정하며 설정하지 않으면 기본값은 50이다.
    • 주의할 점은 -n이 -c보다 커야 한다.
-c 100
  • -z: 테스트 지속 시간(duration)을 지정하며, 해당 시간이 도달하면 자동으로 종료한다.
    • 만약 -z 옵션이 주어지면 -n 옵션은 무시된다. (중요하다)
-z 30s  # 30초 동안 테스트 실행
  • -q: 초당 요청 수를 제한한다 (QPS).
-q 50
  • -m: HTTP 메서드를 지정한다 (GET, POST 등).
-m POST
  • -d: 요청 바디 데이터를 지정한다.
-d '{"key":"value"}'
  • -H: 추가 HTTP 헤더를 설정한다.
-H "Content-Type: application/json"

 

주의 사항: -n과 -c의 관계

  • 총 요청 수(-n)는 동시 워커 수(-c)의 배수 중에서 -n보다 작거나 같은 최대값으로 자동 조정된다. 이는 각 워커가 균등하게 요청을 분담하기 때문이다. 예시를 통해 알아보자.

    1. -n 100, -c 9인 경우:
      • 가장 가까운 9의 배수는 9 × 11 = 99이므로 총 99개의 요청이 전송된다.

    2. -n 100, -c 12인 경우:
      • 가장 가까운 12의 배수는 12 × 8 = 96이므로 총 96개의 요청이 전송된다.

    3. -n 250, -c 17인 경우:
      • 가장 가까운 17의 배수는 17 × 14 = 238이므로 총 238개의 요청이 전송된다.

    4. -n 500, -c 60인 경우:
      • 가장 가까운 60의 배수는 60 × 8 = 480이므로 총 480개의 요청이 전송된다.

    5. -n 1000, -c 33인 경우:
      • 가장 가까운 33의 배수는 33 × 30 = 990이므로 총 990개의 요청이 전송된다.

 

여기서 참고한 내용들이 있으니 한번 읽어보는 것을 추천한다.

 

간단한 커맨드 라인용 web 부하 테스트 프로그램 hey

 

www.lesstif.com

 

4. 부하 테스트 결과 해석 방법

부하 테스트의 결과 해석 방법을 알아보자.

  • hey로 요청을 보내면 아래와 같은 결과표를 받아볼 수 있다.
hey -n 100 http://localhost:8080/

Summary:
  Total:	5.2266 secs
  Slowest:	5.2260 secs
  Fastest:	0.0002 secs
  Average:	1.7883 secs
  Requests/sec:	19.1330

  Total data:	4500 bytes
  Size/request:	45 bytes

Response time histogram:
  0.000 [1]	|■
  0.523 [59]	|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
  1.045 [1]	|■
  1.568 [0]	|
  2.091 [2]	|■
  2.613 [0]	|
  3.136 [4]	|■■■
  3.658 [0]	|
  4.181 [8]	|■■■■■
  4.703 [0]	|
  5.226 [25]	|■■■■■■■■■■■■■■■■■


Latency distribution:
  10% in 0.0005 secs
  25% in 0.0011 secs
  50% in 0.0087 secs
  75% in 5.0122 secs
  90% in 5.2189 secs
  95% in 5.2243 secs
  99% in 5.2260 secs

Details (average, fastest, slowest):
  DNS+dialup:	0.0028 secs, 0.0002 secs, 5.2260 secs
  DNS-lookup:	0.0013 secs, 0.0000 secs, 0.0028 secs
  req write:	0.0000 secs, 0.0000 secs, 0.0001 secs
  resp wait:	1.7844 secs, 0.0002 secs, 5.2177 secs
  resp read:	0.0000 secs, 0.0000 secs, 0.0002 secs

Status code distribution:
  [200]	100 responses

1. Summary: 테스트의 전반적인 성능 지표를 제공한다.

  • Total: 전체 테스트 소요 시간.
  • Slowest/Fastest: 가장 느린/빠른 요청의 응답 시간.
  • Average: 평균 응답 시간.
  • Requests/sec: 초당 처리된 요청 수(RPS).

2. Response time histogram:

  • 응답 시간 분포를 히스토그램으로 나타낸다.

 

3. Latency distribution:

  • 응답 시간의 백분위수를 보여준다.

 

4. Details: 각 단계별 시간 측정.

  • DNS+dialup: DNS 조회와 연결 설정 시간.
  • DNS-lookup: DNS 조회 시간.
  • req write: 요청 전송 시간.
  • resp wait: 서버 응답 대기 시간.
  • resp read: 응답 읽기 시간.

5. Status code distribution:

  • 응답된 HTTP 상태 코드의 분포.

 

5. hey를 활용한 부하 테스트 예제

1. 단일 URL 테스트

  • 총 100개의 요청을 순차적으로 전송한다.
hey -n 100 http://localhost:8080/
  • 결과는 다음과 같다.
hey -n 100 http://localhost:8080/

Summary:
  Total:	5.2266 secs
  Slowest:	5.2260 secs
  Fastest:	0.0002 secs
  Average:	1.7883 secs
  Requests/sec:	19.1330

  Total data:	4500 bytes
  Size/request:	45 bytes

Response time histogram:
  0.000 [1]	|■
  0.523 [59]	|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
  1.045 [1]	|■
  1.568 [0]	|
  2.091 [2]	|■
  2.613 [0]	|
  3.136 [4]	|■■■
  3.658 [0]	|
  4.181 [8]	|■■■■■
  4.703 [0]	|
  5.226 [25]	|■■■■■■■■■■■■■■■■■


Latency distribution:
  10% in 0.0005 secs
  25% in 0.0011 secs
  50% in 0.0087 secs
  75% in 5.0122 secs
  90% in 5.2189 secs
  95% in 5.2243 secs
  99% in 5.2260 secs

Details (average, fastest, slowest):
  DNS+dialup:	0.0028 secs, 0.0002 secs, 5.2260 secs
  DNS-lookup:	0.0013 secs, 0.0000 secs, 0.0028 secs
  req write:	0.0000 secs, 0.0000 secs, 0.0001 secs
  resp wait:	1.7844 secs, 0.0002 secs, 5.2177 secs
  resp read:	0.0000 secs, 0.0000 secs, 0.0002 secs

Status code distribution:
  [200]	100 responses

결과 해석

  • Total: 전체 테스트 시간은 약 5.22초다.
  • Average: 평균 응답 시간은 약 1.78초로 다소 높은 편이다.
  • Requests/sec: 초당 약 19건의 요청이 처리되었다.
  • Latency distribution: 응답 시간의 분포를 나타내며, 75% 이상의 요청이 5초 이상의 응답 시간을 보였다.
  • 이 결과는 서버의 성능이 낮거나 부하가 높은 상황일 수 있음을 시사한다.

 

2. 동시 연결 테스트

  • 총 1000개의 요청을 100개의 동시 연결로 전송한다.
hey -n 1000 -c 100 http://localhost:8080/
  • 결과는 다음과 같다.
hey -n 1000 -c 100 http://localhost:8080/

Summary:
  Total:	6.8861 secs
  Slowest:	6.8826 secs
  Fastest:	0.0001 secs
  Average:	0.4651 secs
  Requests/sec:	145.2199

  Total data:	45000 bytes
  Size/request:	45 bytes

Response time histogram:
  0.000 [1]	|
  0.688 [910]	|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
  1.377 [0]	|
  2.065 [2]	|
  2.753 [4]	|
  3.441 [0]	|
  4.130 [8]	|
  4.818 [16]	|■
  5.506 [11]	|
  6.194 [32]	|■
  6.883 [16]	|■


Latency distribution:
  10% in 0.0002 secs
  25% in 0.0002 secs
  50% in 0.0003 secs
  75% in 0.0006 secs
  90% in 0.0096 secs
  95% in 5.0190 secs
  99% in 6.8707 secs

Details (average, fastest, slowest):
  DNS+dialup:	0.0008 secs, 0.0001 secs, 6.8826 secs
  DNS-lookup:	0.0002 secs, 0.0000 secs, 0.0035 secs
  req write:	0.0000 secs, 0.0000 secs, 0.0015 secs
  resp wait:	0.4643 secs, 0.0001 secs, 6.8748 secs
  resp read:	0.0000 secs, 0.0000 secs, 0.0002 secs

Status code distribution:
  [200]	1000 responses

결과 해석

  • Total: 전체 테스트 시간은 약 6.88초다.
  • Average: 평균 응답 시간은 약 0.46초로 개선되었다.
  • Requests/sec: 초당 약 145건의 요청이 처리되었다.
  • Latency distribution: 대부분의 요청이 빠르게 처리되었지만, 일부 요청은 최대 6초 이상의 응답 시간을 보였다.
  • 동시 연결 수를 늘렸을 때 서버의 처리 능력이 향상되었음을 알 수 있다.

3. 지속 시간 기반 테스트

  • 1분 동안 지속적으로 요청을 전송한다.
hey -z 1m http://localhost:8080/
  • 결과는 다음과 같다.
hey -z 1m http://localhost:8080/

Summary:
  Total:	60.0035 secs
  Slowest:	0.1647 secs
  Fastest:	0.0001 secs
  Average:	0.0054 secs
  Requests/sec:	9185.0400

  Total data:	24801075 bytes
  Size/request:	45 bytes

Response time histogram:
  0.000 [1]	|
  0.017 [539789]	|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
  0.033 [11241]	|■
  0.049 [91]	|
  0.066 [5]	|
  0.082 [0]	|
  0.099 [2]	|
  0.115 [1]	|
  0.132 [2]	|
  0.148 [1]	|
  0.165 [2]	|


Latency distribution:
  10% in 0.0010 secs
  25% in 0.0024 secs
  50% in 0.0045 secs
  75% in 0.0075 secs
  90% in 0.0110 secs
  95% in 0.0135 secs
  99% in 0.0190 secs

Details (average, fastest, slowest):
  DNS+dialup:	0.0000 secs, 0.0001 secs, 0.1647 secs
  DNS-lookup:	0.0000 secs, 0.0000 secs, 0.0070 secs
  req write:	0.0000 secs, 0.0000 secs, 0.0015 secs
  resp wait:	0.0054 secs, 0.0001 secs, 0.1647 secs
  resp read:	0.0000 secs, 0.0000 secs, 0.0024 secs

Status code distribution:
  [200]	551135 responses

결과 해석

  • Total: 테스트는 정확히 60초 동안 진행되었다.
  • Average: 평균 응답 시간은 약 0.0054초로 매우 빠르다.
  • Requests/sec: 초당 약 9,185건의 요청이 처리되었다.
  • Latency distribution: 거의 모든 요청이 0.02초 이내에 처리되었다.
  • 서버가 높은 부하에서도 안정적으로 작동함을 보여준다.

 

참고사항 : 테스트 결과

  • 마지막의 'hey -z 1m http://localhost:8080/' 명령을 실행했을 때 성능이 압도적으로 높게 나타나는 이유는 요청 수의 제한 없이 지정된 시간 동안 최대한 많은 요청을 보내기 때문이다. 반면에 이전 테스트에서는 -n 옵션으로 요청 수를 제한했고, 동시 실행되는 워커 수(-c)도 상대적으로 적게 설정되어 있었다.

  • hey -n 100 http://localhost:8080/의 경우
    • 총 요청 수(-n): 100으로 제한되어 있다.
    • 동시 워커 수(-c): 명시적으로 지정하지 않으면 기본값인 50이 사용된다.
    • 각 워커가 처리하는 요청 수: 총 요청 수를 워커 수로 나눈 값으로, 각 워커는 2개의 요청을 처리한다.
    • 테스트 지속 시간: 총 100개의 요청을 모두 처리하면 테스트가 종료되므로 테스트 시간이 매우 짧다.
    • 결과적으로, 초당 처리량(RPS)과 총 데이터 전송량이 상대적으로 낮게 나타난다.

  • hey -z 1m http://localhost:8080/의 경우
    • 테스트 지속 시간(-z): 1분 동안 지속된다.
    • 총 요청 수: 제한이 없으며, 지정된 시간 동안 최대한 많은 요청을 보낸다.
    • 동시 워커 수(-c): 설정한 값이 없으므로 기본값인 50이 사용된다.
    • 각 워커가 처리하는 요청 수: 워커들은 1분 동안 지속적으로 요청을 전송한다.
    • 결과적으로, 총 요청 수와 초당 처리량(RPS)이 매우 높게 나타난다.

 

 

내 생각에는 locust 말고 이걸로 간단하게 테스트하는 것도 나쁘지 않은 것 같다. 이번에 인프런의 밋업을 보며 조쉬 롱이 사용하는 것을 보며 배우게 된 테스트 tool인데 한 번 제대로 사용해 보고 다시 그 사용 후기를 작성하도록 하겠다.

반응형