티스토리 뷰
개요
Helparty를 클라우드에 배포하고 다른 클라우드 서버에 띄어놓은 여러 어플리케이션들을 연결시켜 대략적인 서비스를 제공하기 위한 기반을 완성했습니다. 네이버 클라우드에서 크레딧을 지급해줘서 비용 문제로 부터 자유로울 수 있었습니다.
이제 ngrinder를 통해 서버에 부하를 걸어보고 난뒤 pinpoint와 어플리케이션들의 cpu 사용률을 보고 모니터링을 진행한 뒤 프로그램을 개선시킬 여지가 있는지 확인해보겠습니다.
WAS 서버 증설에 따른 성능 비교
먼저, WAS 서버 1개를 사용할 때와 WAS 서버 2개를 사용할 때를 비교하여 WAS 서버를 Scale Out 방식으로 증설하는 Helparty에서 WAS를 하나씩 늘릴 때마다 얼마나 큰 성능 향상이 있는지 확인해보겠습니다.
WAS 1대를 사용하는 환경
처음에 제가 테스트한 환경은 아래의 서버들로 구성되어 있습니다.
was
redis-session
redis-cache
mysql-master
mysql-slave
nginx
그리고 제가 부하를 건 요청은 http://xxx.xxx.xx.xx:8000/gymboards/42 입니다.
단순하게 MySQL에 하나의 데이터만 요청하는 작업입니다.
요청 보내는 서버의 구성도는 위의 그림과 같습니다.
그림에는 master db에 접근한 것처럼 나와있지만 실제로는 readOnly 트랜잭션만을 사용하였기에 slave MySQL에만 접근하였습니다.
1000명의 Vuser
처음에는 1000명의 Virtual User와 10개의 프로세스를 설정하고 각 프로세스에는 100개의 스레드를 사용하여 부하를 걸어보았습니다.
결과는 아주 빠른 에러로 인한 테스트 중지였습니다.
WAS의 cpu는 시작하자마자 사용률 100%를 찍었지만
NginX의 사용률과 Mysql의 사용률은 20%이하로만 유지되었습니다.
따라서 1000명의 가상 사용자가 요청을 보내는 환경에서는 하나의 WAS서버로는 감당이 되지 않음을 알 수 있었습니다.
500명의 Vuser
이제 수를 확 줄여 500명의 Vuser를 사용하여 부하를 걸어보겠습니다.
결과는 1000명의 Vuser를 사용할 때 보다는 더 오래 테스트가 진행되었지만 이것 또한 중간에 너무 많은 에러로 인해 테스트가 중단되었습니다.
ngrinder 결과 화면입니다.
성공 테스트보다 실패 테스트가 더 많습니다.
WAS cpu 사용률을 보겠습니다.
1000명의 Vuser를 사용할 때와 같이 100%입니다.
NginX를 보겠습니다.
1000명의 요청을 처리할 때보다는 cpu 사용률이 증가하였습니다.
하지만 사용률이 50% 이내로 안정되어 테스트에서 오류를 뿜어내는 지점이 될 것 같지는 않습니다.
마지막으로 MySQL을 확인해보겠습니다.
20%의 사용률을 보이면서 MySQL 또한 프로그램의 성능 저하를 유발하는 지점이 아니었음을 알 수 있습니다.
따라서 500명의 가상 사용자가 요청을 보내는 환경에서 한대의 WAS 서버만을 운용하는 것은 안정적인 서비스를 제공하는데 부족하다는 것을 알 수 있습니다.
마지막으로 WAS 1대의 감당할 수 있는 임계값을 알기 위해 300명의 Vuser를 사용하여 부하를 걸어보겠습니다.
300명의 Vuser
300명을 입력했지만 296으로 자동으로 바뀌네요. ngrinder에서 300명은 맞아떨어지지 않는 수인가 봅니다.
296명의 Vuser를 사용자를 사용하여 부하를 걸어보았습니다.
이번에는 오류 없이 테스트가 정상적으로 끝났습니다.
각 서버들의 cpu 사용률을 알아보겠습니다.
WAS의 cpu 사용률은 여전히 100%입니다.
NginX의 cpu 사용률은 26%로 안정된 모습입니다.
이전에는 MySQL CPU 사용률 차트를 캡쳐를 해놓지 못해 이렇게 그래프로 보여주지 못하고 간단히 표로만 보여드렸지만 지금 부턴 차트를 보여드리겠습니다.
MySQL의 CPU 사용률은 20이하입니다.
부하 강도에 따라서 큰 차이가 없어보입니다.
따라서 현재 프로젝트의 가장 큰 병목 지점은 WAS 서버 대수이고 하나의 서버 대수의 부하를 감당할 수 있는 임계치는 약 300명의 사용자가 되겠습니다.
이제 서버를 한대 더 늘리겠습니다.
WAS 2대를 사용하는 환경
먼저 500명의 가상 사용자를 사용하여 부하를 걸어보았습니다.
잘 작동할거라는 예상과 다르게 너무 많은 에러로 테스트가 중단되었습니다.
원인을 알아보기 위해 어플리케이션들의 CPU 사용률을 확인해보겠습니다.
WAS1의 CPU 사용률입니다.
100%를 찍고 있는 걸로 보아 병목지점이 될 가능성이 농후해보입니다.
WAS2의 CPU 사용률입니다.
이상하게 WAS1보다 CPU 사용률이 현저하게 낮습니다.
NginX의 CPU 사용률은 29%정도로 많은 에러의 원인은 아닐 것 같습니다.
원인 추정
WAS1과 WAS2의 큰 차이가 나는 CPU 사용률을 보았을 때 현재 NginX의 로드밸런서가 제 역할을 잘 해내지 못하고 대부분의 트래픽이 WAS1을 향하고 있는 걸로 생각됩니다. 그래서 500정도의 요청에도 에러를 발산하고 테스트가 중단되지 않았나 싶습니다.
해결 방안
이 문제를 해결하기 위해 NginX의 로드밸런싱 정책을 변경했습니다.
현재 제가 사용하고 있던 로드밸런싱 알고리즘은 '라운드 로빈' 이었습니다.
라운드 로빈은 선점형 스케줄링의 하나로서, 프로세스를 사이에 우선순위를 두지 않고 일정한 시간을 기준으로 CPU를 순서대로 할당받게 됩니다.
컴퓨터 자원을 프로세스들에게 공정하게 부여하기 위해서 사용되는 스케줄링 기법인데 왜 제 프로젝트에서는 이렇게 불공정을 유발했는지 의문입니다.
일단은 시간을 기준으로 자원을 분배하는 것은 현 상황에서 프로젝트에 자원을 제대로 분배해주지 못하고 있다고 판단하였습니다. 따라서 커넥션의 양을 기준으로 부하를 분배하는 least_conn으로 로드 밸런싱 정책을 수정하였습니다.
해결 방안 도입 후 변화
테스트의 오류가 현저히 줄어들고 테스트는 정상적으로 끝났습니다.
TPS 또한 2557로 로드밸런싱을 하기 전보다 약 3배 정도 수가 올랐습니다.
WAS1의 CPU 사용률을 보겠습니다.
여전히 100%입니다.
WAS2의 CPU 사용률을 보겠습니다.
원래 50%였는데 100%로 수치가 훨씬 높아졌습니다.
투자한 만큼 자원을 잘 사용하게 되었습니다.
NginX의 CPU 사용률을 보겠습니다.
CPU사용률이 증가하였습니다.
전에는 WAS1에 트래픽이 쏠려있어서 대기하는 오버헤드가 발생했고 그에 따른 CPU 사용률 저하가 발생했다고 해석됩니다.
MySQL 또한 CPU 사용률이 급격하게 상승하였습니다.
전에는 20% 전후를 유지했는데 이번에는 50%전후로 바뀌면서 약 2배 이상 CPU 사용률이 상승하였습니다.
결론
저의 프로젝트에 WAS 하나당 감당할 수 있는 스레드 임계값을 300이라는 대략적인 수로 확인할 수 있었습니다.
또한 서버 증설을 통한 서비스의 성능 향상 효과를 눈으로 직접 확인할 수 있었습니다.
그리고 NginX의 로드밸런싱 알고리즘을 수정하여 서버 성능을 향상 시켰고 제가 서버에 투자한 자원들을 보다 더 효율적으로 사용할 수 있게 되었습니다.
'Project 'HELPARTY'' 카테고리의 다른 글
부하 분산을 위한 데이터베이스 이중화 작업 (feat. MySQL Replication) (1) | 2021.06.22 |
---|---|
ngrinder를 이용한 성능 테스트 및 서버 설계 (0) | 2021.06.21 |
MySql 쿼리 성능 분석 및 튜닝 (0) | 2021.06.14 |
프로젝트에 적용할 Log 라이브러리 정하기 (0) | 2021.06.07 |
프로젝트에서 부가 로직 분리하기 [AOP_AspectJ, HandleMethodArgumentResolver] (0) | 2021.05.07 |
- Total
- Today
- Yesterday
- nGrinder
- 성능 향상
- logback
- AOP
- 유틸클래스
- devops
- redis
- MySQL
- 로그
- Filter
- scale Out
- 선언적 트랜잭션
- log4j2
- AWS
- scale in
- interceptor
- UTIL
- 성능 테스트
- memcached
- 쿼리 튜닝
- Declarative Transaction
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |