이번 편에선 DigitalOcean 에서 AWS로 서버들을 옮기는 과정을 적어본다.
전에도 말했지만 리뷰리퍼블릭의 어플리케이션은 meteor.js 라는 프레임워크 (조금 더 정확하게는 meteor.js + react.js) 위에서 돌아간다. 이 프레임워크 덕분에 마이그레이션이 두배는 더 어려워졌다. 일단 익숙한 방식 (어디 한 express.js 나 스프링 MVC 정도 사용할 줄 알았는데…)이 아니기에 이 프레임워크의 전체적인 개념부터 어떤식으로 배포가 되는지를 파악해야 했다.
- 서버 배포방식 확인, 배포
그렇다고 지금 이 포스팅에서 meteor.js의 작동방식에 대해 다룰 것은 아니다. 왜냐하면 다행히 리뷰리퍼블릭의 프라이빗 코드저장소에는 간략한(무려 네줄) 서버 실행 및 배포 방법이 적혀있었기 때문이다. (이렇게 문서화가 중요하다.)
서버 실행은 meteor.js 에 setting.js 파일을 참조해서 하면 되고 배포는 mup.js 라는 배포툴을 이용하고 있었다. 그러니 나는 이걸 aws 인프라 위에서 작동이 되는지 확인만 하면 됐다.
먼저 로컬환경에서 테스트를 해봤다. 내 로컬 컴퓨터에서 정상적으로 어플리케이션이 돌아가는지, 돌아가는 어플리케이션은 실 서비스의 동작과 같은지 확인해야했다. 다행히 하라는 대로 하니 서버가 돌아가긴 했다. 다만 환경변수 세팅이 제대로 안되어있어서 db 접속이 안됐다. 환경변수만 조금 세팅해주니 정상적으로 어플리케이션이 돌아갔다. 또 다행히도 실서비스와 같은 동작을 하는 서버 같았다. (아쉽게도 테스트코드 같은것은 없었다.)
AWS에서 올려보려고 했다. 로컬에서와 똑같은 방식으로 실행을 시키려고 하는데 알수없는 이유로 자꾸 meteor가 빌드 중에 죽었다. 정확한 이유를 파악하기 어려웠다. 결국 mup.js를 통해서 다시 시도했다. mup.js 는 해당 meteor 어플리케이션의 도커 이미지를 만들고 그 도커이미지를 통해 원격 서버에서 컨테이너로 실행시켜주는 배포 툴인듯 했다. 몇번의 시도 끝에 EC2 인스턴스 위에 배포하는 데에 성공했다. mup.js에서 미리 세팅해놓은 덕에 환경변수도 깔끔하게 들어가서 db 접속문제도 없었다. 잘 돌아가기에 해당 서버의 AMI를 생성해서 이미지를 저장해놨다.
이렇게 서버 배포는 간단하게 끝이났다. 결국 서버 이전의 방식은 뭐 서버의 이미지를 떠서 새로운 서버를 올리는 방식이 아니라, 그냥 새로운 서버 하나를 생성하고 그 위에 소스코드를 배포하는 방식이 되었다. 그러니깐, Digital Ocean이랑은 아무 상관이 없었다. 그냥 리눅스 가상머신 위에 소스를 배포하기만 하면 되는 일이었다. 다행히 코드저장 및 최소한의 인스트럭션이 남아있었고 이를 토대로 재배포를 정상적으로 수행할 수 있었다. 와… 만약에 그런 최소한의 코드 정리도 안되어 있고 문서화가 안되어있는 상황이었으면… 아마 그냥 포기하지 않았을까.
- 로드밸런서 변경, 오토스케일링 적용.
일단 기존 로드밸런서에 가용성 문제가 있었다. 기존에는 그냥 인스턴스를 하나 띄워서 그 인스턴스가 로드밸런서의 역할을 한다. 그러다 만약 해당 인스턴스가 뻗어버리면? 바로 서비스 장애로 이어진다. 그러니 인스턴스가 뻗지 않게 사양도 높게 잡아줘야 하고 인스턴스의 가용성 관리도 해야하는건데 그게 쉽지 않다. AWS의 로드밸런서 서비스인 ELB는 고맙게도 그런걸 다 해준다(정확히는 AWS가 보장…해준다고 한다.). ELB 로드밸런서가 뻗지 않게 가용성을 보장해주는 관리형 서비스로 트래픽이 몰려도 이에 맞게 로드밸런서가 대응한다. 아무래도 무식하게 좋은서버 한대 올려서 로드밸런서 구성하는것 보다는 구성도 간단하고 요금도 무작정 성능 좋은 서버 하나에 로드밸런서 올려놓는 것보다 저렴하다.
그래서 로드밸런서를 ELB로 교체했다.
그리고 오토스케일링 적용. 트래픽이 늘어났을때 LB만 살아있다고 되는게 아니라 결정적으로 앱 서버가 살아있어야 한다. 은행에서 티켓 발행하는 기계가 아무리 살아있어도 은행원들이 탈진해버리면 은행 서비스가 불가능한 것과 똑같다. 그러니 앱 서버에도 가용성관리가 들어가야 한다. digital ocean은 아쉽게도 이러한 오토스케일링을 적용하려면 haproxy 등을 통해 직접 구성해야한다. AWS는 이 autoscaling 구성이 간편한게 자랑이다.
그래서 autoscaling을 구성했다. 이렇게 함으로써 얻는 이점은 일단은 가용성이다. autoscaling을 통해 인스턴스가 알수없는 이유로 죽더라도 다시 생성된다. 또한 로드밸런서의 가용성도 올라갔다. 구성은 그냥 아까 서버 배포하면서 생성한 ami를 기준으로 시작구성 생성하고 오토스케일링 적용시켜주면 끝.
- 보너스… 싱가폴 -> 서울
다른 얘길 적다보니 얘기 안했는데 digitalocean에서 제일 가까운 서버가 싱가폴에 있다. AWS는 서울리전이 지원된다. 응답속도는 적게는 0.2초, 많게는 거의 0.7초정도 차이난다(물론 테스트 환경마다 다름). 그러니 싱가폴에서 서울로 옮기기만 해도 최소 0.2초 정도는 버는 셈이었다. 근데 그럼 뭐해 사이트 로딩하는데 7~8초 걸리는데… 0.2초 차이 티도 안남.
이 글을 적던 도중 리뷰리퍼블릭이 터져버렸다…