서버 증설 및 감축은 유동적인 유저 트래픽을 대비하기 위해 필요합니다. 이를 Scale out, Scale in 이라고 하죠. 유저 트래픽의 임계치에 대비한 서버를 항시 올려놓고 있다면 걱정이 없겠지만 오버스펙은 오버된 스펙만큼의 자원의 낭비를 의미하기도 하기에 , 트래픽이 유동적인 웹서비스에서 서버 증설 및 감축은 꼭 필요한 스펙입니다.
예를 들어 티켓팅 사이트에서는 티켓팅 오픈 시점에 맞추어 서버를 증설할 필요가 있습니다.
그럼 우리가 흔히 말하는 증설 및 감축은 어떻게 이루어질까요?
서버 증설 전의 모습입니다. 다수의 클라이언트가 하나의 서버에 요청을 보내고 있습니다.
예를 들어 보겠습니다. 티켓팅 이벤트가 한 시간 뒤에 시작한다고 가정해 보겠습니다. 이벤트를 대비하여 서버가 증설되어야 합니다. 서버를 3대 증성하여 총 4대로 늘려보겠습니다.
3대가 추가되었습니다. 하지만 client에서는 새로 증설된 서버에 요청을 보낼 수가 없습니다. 도메인은 하나이지만 각 서버의 IP가 다르기 때문입니다. 그래서 우리는 IP를 하나로 관리해 줄 필요가 있고 로드밸런서가 등장합니다.
모든 client 는 같은 load balancer 에 요청을 보냅니다. load balancer 는 받는 요청을 server 에 그대로 전달하고 server 의 응답값을 client 에 그대로 전달합니다. 일종의 Gateway 인 셈이죠. 하지만 그림에서는 로드밸런서가 하나의 서버와 통신하고 있습니다. 아직 새로 증설된 서버를 검증하지 않았기 때문인데요. Docker, AWS AMI 등 새로운 머신에서 기존 환경의 불변성을 보장해 주기도 합니다만 Software 혹은 Hardware 이슈를 대비하기 위해서라도 최소한의 Healty Check 는 필요합니다. Healty Check가 완료되면 이제 아래 그림과 같아집니다.
로드 밸런서에서는 유저의 요청을 각 서버에 고르게 분산시켜줍니다. 단순히 리니어하게 생각해봤을때 4배의 가용성이 확보된셈이죠! 물론 '고르게 분산시켜 준다' 에 대한 이슈도 있습니다. Server 에서 세션을 직접 관리하는 경우 (중앙 집중식 스토리지를 사용하지 않는) 에는 Sticky Session 이 필요할 수도 있습니다
Stick Session
client A 의 요청은 로드밸런서를 거쳐 항상 Server A 로만 가도록 처리해 주는 것인데요. 자세한 내용은 위 링크를 참조해주세요!
이제 티켓팅 이벤트가 끝났습니다. 현재 4대의 서버를 운용중이지만 티켓팅이 끝난 유저들이 빠져나가 다시 서버를 감축해야 하는 상황입니다. "그냥 역순으로 하면 되는거 아니야?" 라고 생각할 수 있는데 거의 맞지만 주의해야할 부분이 있습니다. 계속 알아볼게요!
다시 증설한 서버를 load balancer 의 대상으로부터 제외하겠습니다. 이 같은 Action 을 Target Group 에서 제외시켰다고 표현하겠습니다. Target Group 에서 제외시킬 때는 고려해야할 점이 있습니다. 아래의 상황을 예로 들어보겠습니다.
1 : client 는 서버에 요청을 합니다.
2 : 서버는 요청을 수행하고
3 : 응답합니다.
1번이 실행된 이후, 3번이 실행되기 전, 즉 요청은 보냈으나 응답을 하지 않은 상태에서 타겟 서버가 사라진다면 유저는 응답을 받을 수 없습니다. 유저 입장에서는 서버의 응답을 기다리다가 request timeout 이 되겠죠. 이는 간단히 해결할 수 있습니다.
서버의 입구를 막고 출구만 열어놓는 것이죠. 그리고 이미 수신된 요청에 대한 모든 응답을 마무리 한 뒤 서버를 제거하면 되는 것입니다! '모든 응답을 마무리' 했다는 것을 확인하기 위해 프로세스 동작 확인 혹은 별도의 이벤트 리스너 로직을 구축함으로써 응답을 마무리 했음을 확인할 수 있으나, 일반적인 웹 서비스에서 응답 시간이 10초를 넘어가는 경우도 잘 없기에 유휴시간을 적당히 설정하는 식으로 간단히 만들어 줄 수도 있습니다. 이렇게 Scale out and in 과정이 모두 마무리 되었습니다.
만약 세션 문제로 스티키 세션을 사용하고 있다면 세션 정보를 마이그레이션 혹은 유저의 재요청 등의 과정이 필요할테고 웹소켓을 사용하고 있다면 서버 감축은 생각보다 훨씬 복잡한 문제가 될 수 있습니다.
이 포스트에서 설명한 모든 내용은 AWS console 작업만으로도 모두 구현이 가능합니다! 추후에는 AWS ELB 를 사용해 실제로 어떻게 구현할 수 있는지 알아보도록 하겠습니다.