우리가 서비스를 운영하면서, 업데이트를 하거나 새롭게 버전을 올려야 할 때가 있다.
모바일 앱이나 프로그램같은 경우에는 이를 설치하면 끝이겠지...(넥슨이 매주 목요일에 불타는 이유...)
그렇다면 웹 서비스는 어떨까?
웹 서비스, 그 중에서 백엔드에서는 배포를 할 때 어떻게 동작하는지 생각해봐야 한다.
서버에서 단순히 프로젝트를 실행시킨다면, 해당 프로젝트를 끈 다음, 프로젝트를 업데이트시켜야 한다.
업데이트 후 프로젝트를 다시 실행시킨다.
도커를 이용한 배포를 한다면, 그나마 쪼오금 쉬워진다.
배포해야 할 버전의 도커 컨테이너를 클라우드에 올려준다.
올려둔 버전의 컨테이너를 서버가 다운로드받는다.
실행중인 컨테이너를 종료시켜준 후, 받아온 새로운 컨테이너를 실행시켜주면 된다.
이 때, 빈 시간이 존재한다.
새로운 버전의 프로젝트를 받아오고, 이를 실행시키기까지는 새로운 버전이 적용되지 않으며,
프로젝트 혹은 컨테이너를 내리고, 새로운 프로젝트나 컨테이너를 로드할 때 까지는 공백이 발생한다.
만약 우리가 그렇게 차냥하는 네카라쿠배가 이렇게 한다면 어떨까?
만약 롤 웹 페이지를(사실 비밀번호 찾을때나 들어가지만..) 배포되는 20초동안 못쓴다면 어떨까?
정말 불행하게 그 20초동안 요청을 보낸 모든 사용자는 계속해서 아무것도 할 수 없는 상태가 된다.
이런 상황을 방지하기 위해서 우리는 무중단 배포를 사용한다.
How 무중단 배포?
무중단 배포는 크게 블루/그린, 카나리, 롤링이 있다.
세 전략을 모두 간단하게 훑어봐야겠다.
블루/그린(Blue/Green)
블루/그린 전략을 생각할 때, 나 같은 경우에는 각개전투가 생각났다.
분대장조가 진격했을 때, 부분대장조는 엄호를 한다.
분대장조가 더 앞에 있을 때에는, 부분대장조가 진격하고 분대장조는 엄호를 한다.
이런 식으로 더 앞에 있는 팀은, 뒤에있는 팀이 더 앞으로 갈 때 까지 서포트를 해주며, 뒤의 팀은 더 앞으로 나아가는 방식이다.
우리는 이 분대장조와 부분대장조를 블루팀, 그린팀으로 생각해보면 조금 더 쉬워진다.
위의 그림처럼 그린팀이 기존 버전이고, 블루팀이 새 버전이라고 가정해보자.
그린팀은 블루팀이 새로운 버전을 가지고 다 실행될 때 까지 트래픽을 받아주어야 한다.
이후에, 블루팀이 새로운 버전을 가지고 트래픽을 받을 준비가 되었다면,
로드 밸런서가 블루팀이 가져온 새로운 버전에 포트를 연결해준다. 이 때 그린팀은 대기하게 된다.
이런 식으로, 서로 한번 씩 새로운 버전을 가지고 앞으로 나가는 것을 블루그린 전략이라고 한다.
이렇게 배포를 했을 때,
앞으로 나간 블루팀이 문제가 발생했다면 바로 그린팀에 포트를 연결해주어 빠른 롤백이 가능하다.
또한, 바로 새 버전에 포트를 연결하는게 아닌, 블루 버전에서 충분한 테스트를 한 후 포트만 연결해줄 수 있다는 장점이 있다.
블루팀, 그린팀은 역할이 끝난다고 서버 자체를 꺼버릴 수도 있겠지만, 재사용을 할 수 있다는 장점도 있다.
하지만, 단점도 분명하다.
내가 단일 서버로 무중단 배포를 포기한다면 n만큼의 인스턴스가 필요한다고 가정할 때,
블루/그린 배포를 위해서는 2n만큼의 인스턴스가 필요하다(블루/그린이 결국 둘 다 켜져있는 순간이 필요하기 때문이다)
즉 비싸다
카나리(Canary)
카나리 배포는, 이슈에 대한 빠른 대응을 위할 때 자주 사용되는 방법이라고 한다.
일정 비중의 사용자만큼을 새 버전으로 보내 실행을 시키는 방식이다.
내가 학습을 위해 찾아본 포스트에서는 해당 트래픽을 사내 QA나 다른 사람들이 사용하며, 문제가 없을시 사용자 비율을 점차적으로 늘리는 방식으로 이야기했다.
실제로 내가 사용하던 인스턴스의 개수가 n개라면, x/n만큼을 새로운 버전으로 업그레이드할 수 있겠다는 생각이 들었다.
나처럼 토이프로젝트나, 가볍게 학습의 용도로 사용하는 프로젝트라면 신 버전에 트래픽을 주고, 에러가 발생했을 때 이를 클라이언트단에서 기존 버전으로 다시 요청을 보내게 할 수 있겠다는 생각이 들기도 했다.
카나리 배포는 블루그린처럼, 신 버전을 바로 로드밸런서로 달기 전에 테스트를 해볼 수도있다.
신 버전의 점유율(?)이 점진적으로 늘어나는 방식으로, 블루그린보다 롤백이나 이슈에 대한 대응이 더 빠르다.
하지만, 신/구 버전의 배포에 대한 버전관리가 능숙해야한다. 신 버전이 얼마나 점유되었는지, 이걸 어떻게 롤백시킬지 등을 정확히 알고 행동해야 한다.
롤링(Rolling)
어떻게 보면 위의 방식들보다 먼저 설명하는게 나을 수 있다고 싶을 정도로 단순한 방식이다.
나에게 2개의 애플리케이션 인스턴스와 로드밸런서가 있다고 생각해보자.
하나의 애플리케이션을 로드밸런서에서 뗀 다음, 버전을 업그레이드 시킨다.
이후 업그레이드된 버전의 인스턴스를 로드밸런서와 연결하고, 이전 버전의 다른 하나를 뗀다.
해당 버전을 업그레이드한 후 로드밸런서와 달아준다.
이런 방식으로 하나씩 업그레이드를 진행하는 방식이다.
자원이 일정한 상태로 무중단 배포가 수월하기 때문에 관리가 편한 장점이 있다.
또한, 인스턴스 하나씩 배포가 되기 때문에, 이슈가 있을 때 빠르게 롤백할 수 있다.
하지만, 만약 정말로 인스턴스가 딱 두개라면 문제일 수 있다.
기존에 모든 트래픽을 2개의 인스턴스가 감당하고 있었는데,
배포중에는 하나의 인스턴스가 모든 트래픽을 감당해야하기 때문이다.
또한, 구/신 버전이 동시에 존재하기 때문에 호환성 이슈가 존재할 수 있다.
Then, Which one?
그래서 뭐가 좋을까? 이게 제일 중요하다.
나 포함 한국인 특 : 그래서 뭐가 좋은데?
사실 잘 모르겠다는 생각이 들기도 한다.
학습을 위해 찾아본 TechTarget에서는 카나리 배포가 고정된 인스턴스 자원 내에서 동작하기 더 수월하겠다는 이야기를 한다.
확실히 빠른 대응, 블루/그린과는 다르게 고정자원 내에서 동작한다는 점은 충분한 장점으로 보인다.
하지만, 카나리 배포를 위해서는 서버 관리에 충분한 경험과 지식이 수반되어야한다는 생각이 든다.
이를 위해서 어떤 부분들이 필요할지 더욱 찾아보아야 겠다.
또한, 지식이 없는 현재 상태에서는 차라리 블루/그린을 사용하는 것이 더 나을 수 있겠다는 생각이 든다.
로드밸런서로 8080/8081포트의 애플리케이션을 관리하게 한 후, 블루를 8080/그린을 8081에 두어서 이를 상태관리해서 둘중 살아있는 녀석이 있다면 그 포트를 구 버전으로, 다른 포트를 신 버전으로 실행시킨 후 밸런서를 연결하고, 기존에 동작하던 포트를 닫는 방법도 생각해볼만하다고 생각한다.
어떻게 보면, 각자 자신의 서버에서 각 상황에 따른 트래픽을 다 보고 정리해보는 것도 방법일 것 같다.
나도 부스트캠프에서 진행중인(부스트캠프는 끝났지만 팀플은 아니다..ㅋㅋ) 프로젝트에서 이를 테스트해보고 최종적인 결과를 골라야겠다는 생각이 든다.
그럼...twenty thousand...🔥