반응형
http 테스팅 툴 hey 사용하기
1. hey가 뭘까?
hey는 Go 언어로 개발된 간단한 HTTP 부하 테스트 도구다. 원래 rakyll/boom으로 알려졌지만, 이후에 hey로 이름이 변경되었다. 이 도구는 웹 서버의 처리 능력을 테스트하고 성능 병목 현상을 식별하는 데 유용하다.
깃허브 주소
- 아래 깃허브에 소스코드가 공개되어 있다. README를 읽어보는 것도 도움이 될 것이다.
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보다 작거나 같은 최대값으로 자동 조정된다. 이는 각 워커가 균등하게 요청을 분담하기 때문이다. 예시를 통해 알아보자.
- -n 100, -c 9인 경우:
- 가장 가까운 9의 배수는 9 × 11 = 99이므로 총 99개의 요청이 전송된다.
- 가장 가까운 9의 배수는 9 × 11 = 99이므로 총 99개의 요청이 전송된다.
- -n 100, -c 12인 경우:
- 가장 가까운 12의 배수는 12 × 8 = 96이므로 총 96개의 요청이 전송된다.
- 가장 가까운 12의 배수는 12 × 8 = 96이므로 총 96개의 요청이 전송된다.
- -n 250, -c 17인 경우:
- 가장 가까운 17의 배수는 17 × 14 = 238이므로 총 238개의 요청이 전송된다.
- 가장 가까운 17의 배수는 17 × 14 = 238이므로 총 238개의 요청이 전송된다.
- -n 500, -c 60인 경우:
- 가장 가까운 60의 배수는 60 × 8 = 480이므로 총 480개의 요청이 전송된다.
- 가장 가까운 60의 배수는 60 × 8 = 480이므로 총 480개의 요청이 전송된다.
- -n 1000, -c 33인 경우:
- 가장 가까운 33의 배수는 33 × 30 = 990이므로 총 990개의 요청이 전송된다.
- 가장 가까운 33의 배수는 33 × 30 = 990이므로 총 990개의 요청이 전송된다.
- -n 100, -c 9인 경우:
여기서 참고한 내용들이 있으니 한번 읽어보는 것을 추천한다.
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인데 한 번 제대로 사용해 보고 다시 그 사용 후기를 작성하도록 하겠다.
반응형
'스레드(Thread)' 카테고리의 다른 글
[Thread] 코루틴(Coroutine)의 동시성 제어 (0) | 2024.09.22 |
---|---|
[Thread] 코루틴(Coroutine)의 예외처리 (0) | 2024.09.22 |
[Thread] 4. Kotlin의 코루틴(Coroutine)이란? (1) | 2024.09.19 |
[Thread] 3. 일반 스레드 vs 스레드풀 (I/O, CPU 성능 비교) (2) | 2024.09.16 |
[Thread] 2. 스레드풀의 I/O, CPU 성능 비교 (2) | 2024.09.15 |