# 학습 목표
- k6 도구 활용법을 학습합니다.
- 성능 테스트 유형별 스크립트를 작성할 수 있습니다.
- aws ec2 인스턴스를 모니터링할 수 있습니다.
- aws에서 제공하는 버스트 크레딧을 이해할 수 있습니다.
# 해결 과제
1. aws ec2 인스턴스 생성
- 각자의 aws 계정에서 EC2 인스턴스를 생성합니다.
- 버스트 기능이 있는 t2micro를 생성하세요
- ubuntu 20.04
- ssh 접속 생성한 ec2에 접속을 합니다.
- install docker on EC2
#업데이트 및 HTTP 패키지 설치
sudo apt update
sudo apt-get install -y ca-certificates #공인 인증서를 관리하기 위한 패키지
curl
software-properties-common #소프트웨어 저장소 관리 도구
apt-transport-https #HTTPS 프로토콜을 통해 APT 패키지 관리자를 사용할 수 있게 해주는 패키지
gnupg #암호화 및 디지털 서명 도구인 GNU Privacy Guard를 설치
lsb-release #현재 운영 체제의 릴리스 정보를 확인하는 데 사용되는 패키지
# GPG 키 및 저장소 추가
sudo mkdir -p /etc/apt/keyrings
#Docker의 GPG 키를 다운로드하고 파일로 저장합니다. GPG 키는 패키지 관리자가 Docker 저장소에서 제공하는 패키지의 무결성을 확인하는 데 사용
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
#Docker 저장소를 시스템의 패키지 소스 목록에 추가
echo
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 도커엔진 설치
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io
- run container
- 성능 테스트를 위한 타깃 서버를 컨테이너로 배포합니다.
sudo docker run --name <이름> -d -p 8080:8080 sebcontents/cozserver:1.0
- 서버 배포 확인
curl http://localhost:8080
2. install k6
- 공식 홈페이지를 이용하여 k6를 설치합니다. (트러블 슈팅 주의)
- 클라우드 상에 빠른 설치를 위해서 snapd도 추천합니다. https://snapcraft.io/install/k6/ubuntu
sudo apt update
sudo apt install snapd
sudo snap install k6
- 리포지토리에 유형별 테스트 스크립트가 작성되어 있습니다. 앞에서 설명한 내용과 비교하면서 코드의 구조를 잘 살펴보시기 바랍니다.
- run the tests 각각의 스크립트를 실행해 보고 ec2 인스턴스의 CPU 사용률 대시보드를 확인해 보세요. 학습했던 내용의 그래프와 유사하게 관찰되는 지 확인하세요.
k6 run basic_test.js
k6 run load_test.js
k6 run stress_test.js
k6 run spike_test.js
k6 run soak_test.js
- inspect aws burst credit 대시 보드의 CPU 크레딧 사용량(개수) 와 CPU 크레딧 밸런스(개수)를 관찰합니다.
# 실습 자료
# 과제 항목별 진행 상황
인스턴스 시작
CPU 사용률이 5%이하로 credit 사용이 거의 없음

basic test
import http from 'k6/http'; // 부하 테스트 유형 http request
import { sleep } from 'k6'; // sleep 함수 가져오기
export let options = {
insecureSkipTLSVerify: true, // HTTPS 연결에서 TLS 인증서를 확인하지 않도록 하는 기능
noConnectionReuse: false, // 재사용 연결 사용
vus: 10, // 가상사용자 수
duration: '30s' // 실행시간
};
export default () => {
http.get('http://localhost:8080') // get 요청
sleep(1); // 1초 동안 대기 (실제 사용자 처럼 요청하기 위함)
};
ubuntu@ip-172-31-4-230:~/k6_test$ k6 run basic_test.js
/ |‾‾| /‾‾/ /‾‾/
/ / | |/ / / /
/ / | ( / ‾‾
/ | | | (‾) |
/ __________ |__| __ _____/ .io
execution: local
script: basic_test.js
output: -
scenarios: (100.00%) 1 scenario, 10 max VUs, 1m0s max duration (incl. graceful stop):
* default: 10 looping VUs for 30s (gracefulStop: 30s)
data_received..................: 134 kB 4.4 kB/s
data_sent......................: 24 kB 796 B/s
http_req_blocked...............: avg=1.55ms min=3.65µs med=5.11µs max=47.65ms p(90)=9.3µs p(95)=15.02µs
http_req_connecting............: avg=177.11µs min=0s med=0s max=6.54ms p(90)=0s p(95)=0s
http_req_duration..............: avg=2.19ms min=703.53µs med=1.28ms max=38.84ms p(90)=2.73ms p(95)=4.25ms
{ expected_response:true }...: avg=2.19ms min=703.53µs med=1.28ms max=38.84ms p(90)=2.73ms p(95)=4.25ms
http_req_failed................: 0.00% ✓ 0 ✗ 300
http_req_receiving.............: avg=64.28µs min=20.88µs med=38.12µs max=365.33µs p(90)=149.41µs p(95)=161.75µs
http_req_sending...............: avg=32.65µs min=9.44µs med=12.97µs max=1.16ms p(90)=28.58µs p(95)=81.05µs
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=2.1ms min=642.17µs med=1.17ms max=38.46ms p(90)=2.66ms p(95)=4.08ms
http_reqs......................: 300 9.953435/s
iteration_duration.............: avg=1s min=1s med=1s max=1.08s p(90)=1s p(95)=1s
iterations.....................: 300 9.953435/s
vus............................: 10 min=10 max=10
vus_max........................: 10 min=10 max=10
running (0m30.1s), 00/10 VUs, 300 complete and 0 interrupted iterations
default ✓ [======================================] 10 VUs 30s

load_test.js
평균 부하 테스트는 프로덕션 환경의 평균 동작을 반영하는 초당 동시 사용자 및 요청 수를 시뮬레이션합니다.
import http from "k6/http"; // 부하 테스트 유형 http request
import { sleep } from 'k6'; // sleep 함수 가져오기
export let options = {
insecureSkipTLSVerify: true, // HTTPS 연결에서 TLS 인증서를 확인하지 않도록 하는 기능
noConnectionReuse: false, // 재사용 연결 사용
stages: [ // 단계별 시나리오를 설정
{ duration: '5m', target: 100 }, // 5분 동안 100개의 가상 사용자를 유지
{ duration: '10m', target: 100 }, // 10분 동안 100개의 가상 사용자 유지
{ duration: '5m', target: 0 }, // 5분 동안 가상 사용자를 0으로 줄임
],
thresholds: { // 부하 테스트 결과를 평가하는 임계값을 설정
http_req_duration: ['p(99)<150'], // 지표의 99%가 150ms 이하를 유지
}
};
export default () => {
let respose = http.get('http://localhost:8080');
sleep(1);
};
ubuntu@ip-172-31-4-230:~/k6_test$ k6 run load_test.js
/ |‾‾| /‾‾/ /‾‾/
/ / | |/ / / /
/ / | ( / ‾‾
/ | | | (‾) |
/ __________ |__| __ _____/ .io
execution: local
script: load_test.js
output: -
scenarios: (100.00%) 1 scenario, 100 max VUs, 20m30s max duration (incl. graceful stop):
* default: Up to 100 looping VUs for 20m0s over 3 stages (gracefulRampDown: 30s, gracefulStop: 30s)
data_received..................: 40 MB 33 kB/s
data_sent......................: 7.2 MB 6.0 kB/s
http_req_blocked...............: avg=7.02µs min=3.39µs med=5.28µs max=4.27ms p(90)=7.49µs p(95)=10.07µs
http_req_connecting............: avg=239ns min=0s med=0s max=4.06ms p(90)=0s p(95)=0s
✓ http_req_duration..............: avg=1.47ms min=511.37µs med=1.17ms max=22.66ms p(90)=2.25ms p(95)=2.79ms
{ expected_response:true }...: avg=1.47ms min=511.37µs med=1.17ms max=22.66ms p(90)=2.25ms p(95)=2.79ms
http_req_failed................: 0.00% ✓ 0 ✗ 90017
http_req_receiving.............: avg=106.64µs min=18.66µs med=72.59µs max=20.13ms p(90)=195.81µs p(95)=213.94µs
http_req_sending...............: avg=28.43µs min=8.68µs med=13.86µs max=15.95ms p(90)=39.54µs p(95)=72.99µs
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=1.33ms min=425.17µs med=993.04µs max=22.6ms p(90)=2.13ms p(95)=2.64ms
http_reqs......................: 90017 74.952428/s
iteration_duration.............: avg=1s min=1s med=1s max=1.3s p(90)=1s p(95)=1s
iterations.....................: 90017 74.952428/s
vus............................: 1 min=1 max=100
vus_max........................: 100 min=100 max=100
running (20m01.0s), 000/100 VUs, 90017 complete and 0 interrupted iterations
default ✓ [======================================] 000/100 VUs 20m0s

soak_test.js
- 장기간에 걸친 시스템의 성능 저하 및 리소스 소비.
- 확장된 기간 동안 시스템의 가용성 및 안정성.
import http from "k6/http"; // 부하 테스트 유형 http request
import { sleep, check } from 'k6'; // sleep 함수 가져오기
export let options = {
insecureSkipTLSVerify: true, // HTTPS 연결에서 TLS 인증서를 확인하지 않도록 하는 기능
noConnectionReuse: false, // 재사용 연결 사용
stages: [ // 단계별 시나리오를 설정
{ duration: '2m', target: 400 }, // 2분동안 400개의 가상 사용자를 유지
{ duration: '3h56m', target: 400 }, // 3시간 56분동안 400개의 가상 사용자를 유지
{ duration: '2m', target: 0 }, // 2분동안 가상 사용자를 0으로 줄임
],
};
export default function () {
const res = http.get('http://localhost:8080');
//check 함수를 사용하여 응답을 검사합니다.
//이 경우, 응답의 상태 코드가 200인지 확인합니다.
//검사 결과가 false인 경우 오류가 발생
check(res, { 'status was 200': (r) => r.status == 200 });
sleep(1);
};

stress_test.js
스트레스 테스트는 사용량이 많은 조건에서 시스템의 안정성과 신뢰성을 확인합니다. 시스템은 처리 기한, 월급날, 출퇴근 시간, 근무 종료 및 고부하 이벤트를 생성하기 위해 결합될 수 있는 기타 많은 격리된 동작과 같은 비정상적인 순간에 평소보다 높은 작업 부하를 받을 수 있습니다.


spike_test.js
시스템이 갑작스럽고 대량의 사용 급증에서 살아남고 성능을 발휘하는지 확인

# TROUBLE SHOOTING LOG
문제 내용
원인
해결 방안
#References
내용