# k8s 환경에서 golang 서버를 pod 로 만들어 stress test(부하 테스트)를 했다.
# 부하 테스트 툴은 vegeta 를 사용
# 1개의 pod 를 운영하고 1000/1s 로 부하를 주면
echo "GET http://ysofman.test.com:9999/test" | vegeta attack -duration=10s -rate=1000/1s -timeout=500ms | tee results.bin | vegeta report
# 다음과 같이 17% 성공한다.
# 1000*0.17 = 170tps
Requests [total, rate] 10000, 1000.05
Duration [total, attack, wait] 10.151548026s, 9.999496s, 152.052026ms
Latencies [mean, 50, 95, 99, max] 51.131863ms, 0s, 379.564354ms, 480.801383ms, 561.313466ms
Bytes In [total, mean] 20482436, 2048.24
Bytes Out [total, mean] 0, 0.00
Success [ratio] 17.42%
Status Codes [code:count] 0:8258 200:1742
# 부하 테스트 중 해당 pod pprof 를 refresh 하면서 확인해 보면
# goroutine 수가 최대 50개 정도로 부하에 비해 많이 늘어 나지 않는다.
http://ysofman.test.com:9999/debug/pprof
# 그냥 로컬 환경으로 서버를 띄워 부하 테스트 하면 100%성공으로 1000tps 가 나온다.
# pprof 를 확인하면 goroutine 이 200 개 이상으로 늘어났다 줄어든다.
# 원인은 k9s deployment 설정에서 container resource 부분에
# pod가 있는 실제 node 의 리소스가 충분하면 pod 의 컨테이너가 사용할 수 있는
# cpu 리소스가 100m 0.1core 이상 사용할 수 있도록 허용하고 (requests)
# 최대 cpu 리소스가 250m 0.25core 까지만 사용하도록 제한돼 있었다.(limits)
# 참고로
# requests 를 사용할 수 있는 node 에 스케줄링 된다.
# limits 를 넘어가면 OOM(Out Of Memory)에러와 함께 종료시킨다.
# m은 milli 단위로 1000m = 1 = 1core 를 사용할 수 있다.
resources:
limits:
cpu: 250m
requests:
cpu: 100m
# goroutine 을 core 개수만큼 goroutine 을 동시에서 처리할 수 있는데
# runtime.NumCPU() 가 8 이고,
# runtime.GOMAXPROCS(8) 로 8개 코어(프로세서)를 사용할 수 있도록 설정해도
# k8s 차원에서 pod core 를 1/4core 로 제한해서
# 부하처리를 위한 goroutine 들이 pending 되어 대다수 응답이 타임아웃된다.
# cpu limits 를 8 로 늘리면 1000tps (100%성공률) 성능이 나온다.
comments:
댓글 쓰기