기록하며 성장한다 - 개발, 회고

개발 회고록

[ 개발 회고록 ] 서버 구조 설계 과정과 JMeter 를 활용한 성능 테스트

전대홍 2024. 1. 24. 20:29

드디어 서버 구축을 해보자 !

 


서론

현재 배달과 관련 된 토이프로젝트를 진행하고 있다.

토이 프로젝트 링크 <<<

필요한 개발을 마치고 ( 물론 또 공부하여 추가하면 좋을 내용들은 계속 추가할 예정이다. ) 이제 서버에 올려서 동작이 제대로 되는지를 확인해보고 싶어졌다.

무엇보다 개발자가 되어서, 코드만 작성하고 서버를 만져보지 않는다면, 너무 큰 마이너스가 될 거 같았다.

필자는 이전에 AWS 를 통해서 서버를 만들어 본적이 있다. ( 한 번 )

그러나 그 때는 학원에서 공부를 하며 따라하듯 만들어 본 경험이고, 이전에 다녔던 회사에서도 서버 관리는 개발 이사님이 직접 구축하시고, 필자는 로그를 확인하고 오류를 수정해서 파일질라를 통해 업데이트 하는 작업 정도만 해보았다.

그래서 직접 공부하고, 알아보며 서버를 설정해 보는 경험은 지금이 처음이라 할 수 있다.

그래서 더욱 두근거렸다.

 

 


본론

1. 필자가 사용한 서버 목록

* WAS 서버 (  Java + Spring + Docker ) : 2대 --> 3대

* MySQL 서버 : 1대

* Redis 서버 : 2대

* Nginx 서버 : 1대

 

 

2. 프로젝트 서버 구조

사용자 중심으로 구조를 보면 다음과 같다.

사용자 ( User, Owner, Rider ) 들은 Nginx IP 를 통해서 Http Request 를 보낸다.

그러면, Nginx 에서는 Reversed Proxy 기능을 통해, 필자가 만든 WAS 서버 2대 중 하나로 요청을 보낸다. ( 부하 분산 )

그 안에서 여러 작업을 진행하게 될 텐데, 데이터에 대한 접근이 있을 경우, WAS 서버는 MySQL 서버와, Redis 서버를 통하여 데이터에 접근한다.

 

개발자 중심으로 구조를 보면 다음과 같다.

개발자가 코드를 짜고, GitHub 를 통해 버전 관리를 한다.

그러다가 서버에 기능을 올려야 할 경우, Docker 를 활용하여 이미지를 만들고, Docker Hub 에 Push 를 한다.

이후 WAS 서버에 접근하여, 해당 Docker 이미지를 Pull 하고, Run 을 시킨다.

원래는 이러한 Build 작업이 수동으로 이루어지는 것이 아니라, Jenkins 와 같은 CI/CD 툴을 통해 동작해야 하지만, 필자는 아직 Jenkins 에 대한 공부가 되지 않아 아직 이용하지 않았다.

 

 

3. 서버 구축 과정

사용하고 있는 서버들은 AWS S3 를 제외하고, 전부 Naver Cloud 를 활용하였다.

Naver Cloud 에도 AWS S3 와 같은 역할을 하는 Object Storage 가 존재하지만, 필자가 이미 개발을 하면서 AWS S3 로 연결을 해둔 이유도 있고, 실제로 이미지 저장은 AWS S3 를 활용해보고 싶다는 생각을 개발 이전부터 해왔었기 때문에, 이 부분은 그대로 진행하였다.

또한, AWS 의 경우 기존에 필자가 GPT 를 가지고 Node.js 프로젝트를 연습삼아 만들었을 때 좀 사용했던 이력이 있어서 무료 기간이 거의 끝나가고 있었다.

그런데 Naver Cloud 는 최초 가입자에게 10만 크레딧을 무료로 제공해준다고 하여, 최종적으로 Naver Cloud 를 선택하게 되었다. ( AWS 도 지원은 해주는데, 학생만 지원해 준다는 이야기가 있다. )

또한 Naver Cloud Platform ( 이하 NCP 로 칭함. ) 은 MySQL 이나, Redis, Jenkins 등이 이미 설치 되어있는 Application 서버를 제공해준다.

필자는 학습 목적을 위해 리눅스 서버를 만들어 설치하고 진행을 하였는데, 이후에 이렇게 제공 되는 서버는 어떤면이 다른지, 그리고 어느정도의 편의성이 제공되는지 궁금하여 기존 서버를 삭제하고, 제공해주는 서버로 다시 만들어보았다.

 

WAS 서버는 2vCPU, 4GB Mem 를 2대를 구매하였다.

1대부터 시작해서 성능을 확인하며 천천히 늘려갈 것을 고려하였으나, 일단 Nginx 를 사용해서 로드밸런싱을 해보고 싶어, 2대로 시작을 하였다.

목표는 매장 검색 기준으로 500개의 스레드가 동시에 접근 하였을 때, 1초안에 처리하는 TPS 500을 목표로 하였다. 그리고, 1,000 명까지는 Read time out 으로 인한 응답 실패가 없도록 하는것을 목표로 하였다.

( 참고로, 매장 데이터 개수는 100개이다. )

TPS 가 500이면 높은편이 아니기는 하나, MySQL 서버가 한 대이며, 비로그인 상태로 매장을 검색하는 것으로 테스트를 진행하기 때문에, 캐싱이 이루어지지 않으므로 TPS 500을 목표로하였다. 이렇게 되면 이후 캐싱되는 걸 고려하면 더 성능이 좋아질 거라고 생각하고 이렇게 목표를 잡았다.

해당 테스트는 필자가 멀티스레드 테스트를 할 때 종종 사용해왔던 JMeter 를 사용하였다.

그런데 놀랍게도 딱 필자가 예상한 만큼의 결과가 나왔다.

300 개의 스레드를 동시에 던졌을 때는 1초안에 성공하였고,

500 개의 스레드를 동시에 던졌을 때도 TPS가 494가 나오며 1초안에 성공하였다.

1,000 개의 스레드를 동시에 던졌을 때는, 갑자기 TPS 가 230으로 낮아지며, 시간이 걸리기 시작하였다.

이후 2,000 개까지는 버텼으나 2,000 개 이상의 스레드로 넘어가니 Read time out 으로 인한 응답 실패가 생기게 되었다.

일단, 예상한 만큼의 결과가 나오긴했지만, 그래도 성능이 다소 아쉬운게 느껴져서 2vCPU, 4GB Mem 스펙을 1 대 더 구매하였다.

그랬더니 1,000 개의 스레드를 동시에 던졌을 때, TPS 가 500까지 올라가며 2초안에 완료가 되고, 응답 실패도 없었다. 확실히 서버 개수에 따라 성능의 차이는 꽤 컸고, 3대를 유지하기로 하였다.

 

Nginx 서버는

WAS 서버와 동일하게  2vCPU, 4GB Mem 를 1대 구매하였다. 일단 서버에 들어오는 요청을 분산시켜주기 위한 역할을 하기 때문에, 그렇게 고스펙의 서버가 필요하지는 않다고 판단하였다. Nginx는 Revered Proxy 기능을 이용해 부하를 분산 시켰다.

 

MySQL 서버도  2vCPU, 4GB Mem 로 1대를 구매하였다. 데이터 스토리지 용량은 기본 10GB를 구매하였고, 용량이 늘어날수록 자동으로 추가되게끔 하였다.  

 

Redis 서버는 1.5G MEM 짜리로 2대를 구매하였다. 한 대는 Session 용이고, 한 대는 Cache 용으로 구매하였다.

 

 

 


결론

무료 크래딧을 주는 네이버 클라우드를 통하여, 서버를 구축할 수 있는 귀중한 경험을 하였다.

이를 통해 서버가 어떻게 이루어져있고, 어떻게 구축을 해야하는지 깊이 이해할 수 있었으며,

네트워크의 이해가 부족했던 필자가 공인IP, 내부IP 등 여러가지를 경험하면서 네트워크에 대한 지식도 얻을 수 있었다.

프로젝트의 질과 필자의 실력이 올라가는 결과를 얻을 수 있었다.