보통 가벼운 애플리케이션을 개발하다보면 대부분의 서버 구조는 다음과 같다.
Cient - Backend Server - DB Server
기능을 개발하고 배포까지 하더라도 문제는 전혀 없는 구조이다. 하지만 개발을 진행하다보면 예상치 못한 오류가 발생하여 서버가 다운되기도 하고 사용자의 수가 급격히 증가하여 속도가 매우 느려지기도 한다. 아무리 애플리케이션 및 DB 서버의 성능을 높이더라도 서버가 다운되는 것은 막을 수 없다.
이는 각 역할을 하는 서버가 단 한개씩만 존재하기 때문에 발생하는 일인데, 이를 SPOF
라고 부른다. SPOF 란, single point of failure 의 약자로 단일 장애점이라는 의미이다. 백엔드 서버와 디비 서버의 역할을 하는 서버들이 각각 하나씩만 존재한다. 버그가 발생하여 백엔드 서버가 다운되거나 디비 서버에서 큰 성능 이슈가 발생하여 속도가 매우 느려진다면 이를 대체할 서버가 존재하지 않는다. 초기의 욜로가 서버도 이에 대응하지 못하는 구조를 가지고 있었다.
초기의 욜로가 서버 구조도
SPOF 를 제거하려면 어떻게 해야할까? ‘단일’ 서버였기 때문에 발생했던 문제였으므로 문제를 없애려면 ‘복수’ 의 서버를 구축하면 된다. 애플리케이션이 동작하는 서버를 여러 개 구축하여 요청들을 분산하는 것을 로드 밸런싱
이라고 한다. 따라서 각각의 서버를 더 구축하면 된다.
문제의 해결법은 간단하지만 언제나 간단한 해결법에는 비용이 든다.. 서버를 더 구축하려면 AWS 의 인스턴스를 늘려야 하는데 AWS 의 프리티어를 사용하는 입장에서, 2개의 서버를 4개로 증가시키는것은 큰 부담이다. (이미 2개를 구축해놓았기 때문에 프리티어 제공 시간을 넘긴다.)
따라서 서버 자체의 구축을 줄이기 위해 두벅스 서버와 욜로가 서버를 각각 분리했던 것에서 하나의 서버에 포트로 분리되도록 구조를 변경하였다. 그 후 남은 서버에도 동일하게 두 개의 애플리케이션을 띄웠다.
(위의 이미지도 Route53 과 Load Balancer 가 있었지만 생략되었다..)
로드 밸런싱을 구현하기 위한 알고리즘도 다양하다. 가장 기본적인 알고리즘은 라운드 로빈 알고리즘이다. 로드 밸런서에 연결되어 있는 서버들을 순서대로 선택하는 알고리즘이다. 가장 단순하며 일반적인 상황에서 많이 사용한다. 그 외에 라운드 로빈 방식에 가중치를 더하는 방식(가중 라운드 로빈 방식), IP 에 따라 매핑하는 방식(IP 해시 방식), 해당 시점에 요청이 가장 적은 서버를 선택하는 방식(최소 연결 방식) , 가장 응답 시간이 빠를 것 같은 서버를 선택하는 방식(최소 응답 시간 방식) 등 다양하다.
로드 밸런서로 AWS EC2 의 ALB 를 사용하고 있는데, 여기에서 제공하는 알고리즘은 라운드 로빈과 최소 연결 방식 두 가지가 있다. 애초에 구축해둔 백엔드 서버가 두 개 밖에 되지 않기도 하고, 서버에 응답이 특별하게 길어질만한 기능도 없기 때문에 기본으로 설정되어 있는 라운드 로빈 방식을 선택하였다.
사실 어떻게보면 성능자체는 비슷하거나 조금 더 안좋아졌을 수도 있다. 결국은 두 개의 인스턴스를 사용하는 것은 마찬가지이니 말이다. 하지만 초기의 구조와 다른 점은 하나의 인스턴스가 안타까운 사유로 다운되더라도 동작하는 서버가 더 존재하다는 것이다.
로드 밸런싱은 보통 성능을 높이기 위해 사용한다. 트래픽이 몰릴 경우 이를 수행할 서버 개체의 수를 늘려 트래픽을 분산시키는 것이다. 성능도 높이고 장애 발생률도 줄이는 가장 좋은 방법은 자원을 많이 소비하여 하나의 역할만을 수행하는 인스턴스를 많이 구축하는 것이다. 하지만 개인 프로젝트를 진행하는 입장에서 예산을 고려하지 않고 수많은 인스턴스를 마구잡이로 생성할 수는 없다. 따라서 최대한 예산 내에서, 안전한 서버를 구축해보았다.