왜 무중단 배포를 해야하는가?
😰 서비스가 중단되면 안되는데…
스낵게임 서비스를 운영하면서 사용자의 피드백과 더불어 여러 기획들을 시도하다 보니 운영 환경에 배포할 일이 잦아졌습니다.
무중단 배포를 도입하기 이전에는 평균 10초 정도의 다운타임(downtime)이 존재했습니다.
하지만 실제 서비스중인 서버가 10초씩이나 다운되는것은 중대한 문제라고 생각합니다.
게다가 추후에 기능이 더 많아질수록 시간이 늘어날 것이라고 판단해 무중단 배포를 고려하였습니다.
무중단 배포란?
v1의 종료 시점부터 v2 서비스의 시작 전까지 다운타임이 생기게 되는데 이때 사용자들은 서비스를 이용할 수 없게 됩니다.
이 문제를 해결하여 배포 동안 중단이 없도록 하는 것이 무중단 배포입니다.
무중단 배포 방식
이번에 무중단 배포에 대해서 서치해보았는데요 결국 트래픽의 제어(Load Balancing)를 통해 무중단 배포를 한다는 점으로 귀결된다고 생각했습니다. 그리고 그 트래픽의 제어를 구현하는 방식에는 크게 세가지가 있습니다.
- Load Balancing 사용
- AWS ELB
- Nginx 사용
- 네트워크 장치(L4, L7 스위치)
왜 Nginx를 선택하였는가?
저희는 이미 Nginx를 이용하여 웹서버를 구축하였기 때문에 큰 변경사항 없이 무중단 배포를 도입할 수 있을것 같다고 판단하여 선택했습니다. 또한 현재 단일서버로만 운영을 하고 있기에 Nginx가 가장 적합하다고 생각했습니다.
무중단 배포 전략
롤링 배포(Rolling)
롤링은 위의 그림처럼 순차적으로 새로운 버전으로 변경해나가는 방식입니다. 처음에는 3개의 인스턴스에 트래픽을 분산시키다가 배포를 시작하면 State 2 처럼 하나의 인스턴스로의 트래픽은 차단한 후 새로운 버전을 배포하고 다시 트래픽을 연결합니다. 그 후 나머지 인스턴스들도 동일한 방법으로 배포를 진행하게 됩니다.
장점
- 적은 자원
- 추가적인 인스턴스가 필요하지 않아 자원적 이점이 생깁니다.
단점
- 트래픽
- 운영중인 인스턴스가 3개일 때 새로운 버전을 배포하는 인스턴스는 잠시 트래픽을 차단하니 나머지 2개가 모든 트래픽을 감당해야 합니다.
- 호환성
- 순차적으로 배포가 진행되기에 어느 시점에는 새로운 버전을 서비스받는 사용자와 오래된 버전을 서비스받는 사용자가 공존하게 됩니다. 이 문제는 사용자가 호환성으로 인해 피해를 보지 않도록 기술적, 비즈니스적 하위 호환성을 지킴으로써 해결할 수 있을 것이라 생각합니다.
적합한 상황
운영에 필요한 리소스가 최소 2개 이상 있지만 인프라를 훨씬 크게 증축하기 힘들면서 호환성에 큰 영향을 받지 않는 서비스의 경우 적합하다 생각합니다.
블루-그린 배포(Blue-Green)
오래된 버전을 블루, 새로운 버전을 그린으로 구분하여 배포를 진행하는 방식입니다. 오래된 버전과 동일한 환경에 새로운 버전을 배포 후 트래픽을 그린에 연결하여 줍니다.
장점
- 빠른 롤백
- 오래된 버전을 종료시키지 않았다면 새로운 버전이 버그가 많은 경우 단순히 트래픽을 옮기는 것 만으로 빠른 롤백이 가능해집니다.
단점
- 필연적인 자원 증축
- 실제 운영에 필요한 리소스 대비 2배의 리소스를 확보해 둬야 합니다.
적합한 상황
인프라적인 리소스를 충분히 확보할 수 있는 상황에서 어플리케이션의 호환성이 사용자 경험에 큰 영향을 미칠 때 적합하다고 생각합니다.
카나리 배포
점진적으로 구버전에 대한 트래픽을 신버전으로 옮기는 것은 롤링 배포 방식과 비슷합니다. 다만 카나리 배포의 핵심은 새로운 버전에 대한 오류를 조기에 감지하는 것입니다. 카나리 배포는 특정된 사용자 그룹 또는 랜덤 그룹으로 부터 새로운 버전에 대한 응답을 받고 오류가 없다고 판단되면 위의 그림처럼 점진적으로 새로운 버전으로의 유입을 늘려갑니다.
장점
- 에러의 최소화
- 다른 전략들과 달리 카나리 배포는 새로운 버전으로의 트래픽을 직접 통제 가능하기 때문에 에러로 인한 피해를 최소화 할 수 있다는 점이 가장 큰 장점이라고 생각합니다.
- A/B 테스트
- 트래픽을 직접 통제 할 수 있어 새로운 버전과 오래된 버전의 지표차이를 확인 할 수 있는 A/B테스트가 가능해집니다.
단점(?)
- 롤링과 마찬가지로 새로운 버전과 오래된 버전이 공존하게 되어 호환성 문제가 발생할 수 있다고 하는데 위의 두 장점을 생각해보면 카나리 배포 전략을 선택하는 것은 오히려 의도했다고 볼 수 있을 것 같습니다.
적합한 상황
복잡한 구현에도 불구하고 새로운 기능이나 업데이트에 대한 사용자 피드백이나 새로운 버전에 대한 안정성을 확인하고 싶은 경우 선택하면 적합하다고 생각합니다.
호환성에 대한 고찰
사실 호환성을 고려하여 서비스를 만들어야 하는 것은 위의 세방식 모두 똑같습니다. 보기에 블루-그린 배포는 호환성에 대해 큰 문제가 없을 것 같지만 블루-그린 전략 또한 어느 한 시점에는 서로 다른 버전을 사용할 유저들이 존재할 수 있기에 문제가 ‘있다/없다’ 가 아닌 정도의 차이라고 생각합니다.
따라서 위에서는 차이점을 강조하기 위해서 단점으로 기술해두었으나 호환성 문제는 어떤 한 전략의 단점이 아닌 모든 전략이 고려해야할 지점이라고 생각합니다. 버전의 차이가 생기는 시간을 어떻게 다룰것인지 상황에 따라 선택하면 될 것 같습니다.
🤔 그럼 우리는 어떤 전략을 사용해야 할까?
블루-그린 배포
저희는 현재 최소한으로 필요한 서버로만 운영을 하고 있고 추가 서버 증설에 제약이 있기에 롤링 배포는 적합하지 않다고 판단하였습니다. 카나리 배포 또한 현재 저희 서비스에선 A/B테스트가 필요하지 않은 상황이라 제외하였습니다.
저희가 사용자 피드백을 받고 새로운 기획을 계속 시도해보는 만큼 에러가 많을 것이고 그만큼 롤백이 많이 필요할 것 같아서 블루-그린 배포의 장점인 빠른 롤백은 도움이 될 것이라고 판단하였습니다. 일반적인 방식과의 차이점은 현재 트래픽이 많은 서비스가 아니기에 일단 추가적인 인스턴스 개설하지 않고 포트를 통해 구현할 것이기에 커밋을 롤백하여 재배포한다는 점입니다.
그리고 랭킹 시스템이 중요한 게임을 서비스하고 있는 만큼 호환성은 사용자에게 중요한 문제라고 생각하였는데 이 또한 블루-그린 배포가 제일 짧은 시간내에 균등한 서비스를 제공할 수 있다 생각하여 이 전략을 채택하게 되었습니다.