Monolith to Serverless using AWS Lambda (1)


기존 모노리스 API 서버를 AWS Lambda를 이용하여 서버리스로 변경하기

1편. 서버리스를 하려는 이유

최근 새로 입사한 곳에서 하고 있는 작업이 기존의 모노리스로 운영중이던 API Server를 서버리스로 옮겨가는 작업을 하고 있다. 그 과정에서 겪었던 여러가지 일들과 나의 생각들을 공유하고자 하는 차원에서 포스팅을 결심했다.

요즘 유행중인 단어 중에 Serverless Architecture 란 말이 있다. 위키피디아에는 Serverless computing으로 들어가보면 잘 설명되어 있다. 서버리스가 어떤 장점이 있길래 다들 서버리스, 서버리스 노래를 부를까 ?

서버리스의 장점 = 모노리스의 단점

1. 서버 스케일링이 필요없다.

요즘 서버를 직접 운영하는 경우는 잘 없고 대부분 클라우드 서비스를 이용한다. (ex. AWS의 EC2) 서버가 죽는 대부분의 경우는 서버가 감당가능한 통신 대역폭, 메모리 용량, 컴퓨팅 능력을 넘어서는 요청이 들어오는 경우이다. 대부분의 경우는 그렇게 요청이 많이 들어오는 것에 대해서 어느 정도 알 수 있으므로, 미리 서버를 많이 늘려놓으면 된다. 그리고 요즘은 클라우드 서비스 상에 컨테이너를 이용해서 스케일링해주는 서비스를 대부분 제공해주므로, 오토 스케일링을 설정해 놓으면 해결된다. 그렇게 하더라도 장애가 발생한다.

그럼 언제 엄청난 양의 요청이 갑자기 들어올까 ? 대부분의 경우는 중요한 시점이다. 여기서 말하는 중요한 시점은 서비스에 대한 홍보가 나갔을 경우를 말한다. 지금 접속하면 선착순 몇명에게 쿠폰 증정, PPL을 통해 해당 서비스에 대한 홍보가 방송에 나간 경우, 앱에 푸시를 발송한 경우 등이 있을 것이다. 만약 오늘 밤에 하는 드라마에 PPL로 우리 서비스가 소개될 예정이다. 드라마가 10시에 시작하고, PPL이 나갈 시간이 대략 10시 40분쯤 될것 같다고 한다면 ??? 관련자들은 퇴근을 못한다. 그 시간 이전에 서버를 충분히 늘려놓고, 계속 서버 상태를 모니터링 하고 있다가, 요청수가 줄어들면 서버를 다시 줄이던지 아니면 오토 스케일링 설정을 조정해줘야 한다. 오토 스케일링 ? 그럼 자동으로 되어야 하는것 아닌가 ? 하지만 컨테이너에 서버 이미지를 복사해서 가동하는데 대략 15분의 시간이 걸린다고 가정했을 때, 15분동안 기존에 실행하고 있던 서버들이 죽지않고 요청들을 잘 처리해 준다면 문제가 되지 않지만 그러지 못할 경우에는 바로 장애가 발생하는거다.

그럼 그게 무슨 오토 스케일링이냐 ? 라고 생각할 수 있지만, 그럼 현재 서비스되고 있는 서버수를 어떻게 설정할 것인가 ? 언제 서버를 더 늘릴것인가 ? 에 대한 고민을 서버 관리자는 항상해야하는데, 그 고민에서 어쩌면 가장 중요한 포인트는 비용이다. 서버가 죽지 않으면서 최적의 비용으로 운영을 하는게 최대한의 이익이 나는 것이기에 그 설정을 최대한 타이트하게 하는게 좋다. 만약 설정을 장애에 죽지 않는것이 최고라고 생각하고 늘 많이 띄워놓으면 그만큼 과금은 많이되고 서버는 많은 시간을 놀고 있게 된다. 요청에 대해서 스케일링하는 정책 자체를 느슨하게 하면 평소라도 한순간 요청이 몰릴 경우 바로 서버를 새로 올리게 되고, 올리는데 15분이 걸리는데 막상 15분 뒤에는 그 서버가 필요없게 되는 경우가 많이 발생할 것이다.

서버리스로 간다면 실질적인 서버 운영을 클라우드 서비스 업체에게 완전 넘길수 있으므로, 이런 고통에서 벗어날 수 있다. (하지만, 실제로는 이것도 모니터링해야 한다. 그 이유는 뒤에 따로 설명하겠다. 아주 간략하게만 얘기하자면 클라우드 서비스에게 사용자에게 서버리스에서 사용될 자원을 무한히 주지않고 제한하기 때문이다.)

2. 비용

싸다. 다른 말이 더 필요한가 ? AWS EC2 서버로 운영하는것 보다 Lambda + API Gateway를 이용해서 API를 서비스 해보니 훨씬 더 싸다. EC2의 경우에는 운영중인 서버수 x 서버 인스턴스의 비용 x 서버가 운영중인 기간 (1시간 단위)로 과금이 이루어 진다. Lambda의 경우는 코드가 수행된 시간을 100ms 단위로 올림하여 과금한다. API Gateway의 경우 100만 요청 당 3.5 USD가 과금된다. 이렇게 봐서는 과연 더 싼지 바로 판단이 안되겠지만, 실제로 운영해보니 훨씬 더 싸다. 비교도 안되게 싸다.

일단 이 두가지가 직접 겪었던 큰 이유다. 이것 말고도 여러가지 발표자료들을 찾아보면 다른 장점들이 많다. 하지만 그건 옵션 사항인듯 하다.

3. 폴리그랏이 가능

각 API 기능별로 다른 언어로 개발이 가능하다. 당연히 그렇겠지. 각각 따로 디플로이 되어서 관리되니깐… 하지만 그렇게 각각의 API를 서로 다른 언어로 서로 다른 프레임워크를 써서 만들어 올리면 관리는 누가하나 ? 정말 급하게 서비스해야 되어서 아웃소싱으로 가장 자신있는 언어로 최대한 빨리 해주세요. 가 아닌 이상 한 조직에서 이렇게 했을때 과연 장점이 더 클지 단점이 더 클지… 아니면 개발 조직이 엄청나게 크고, API 개발자가 수십명 있을 경우라면 나름 괜찮을것 같기도 하다. 당장 나의 경우만 보더라도 가장 자신있고 가장 빨리 개발이 가능한 언어는 C# 이다. 하지만 Node.JS 로 API를 개발 중이다. (여기에는 다른 이유도 있긴있다. 아직 AWS Lambda에서 .Net CORE 지원이 믿을만한 수준은 아니라서…)

이 쯤되면 서버리스를 안 할 이유가 없어보인다. 정말로 그렇게 생각이 든다면… 일단 서버리스 약을 파는데 조금은 성공했단 생각이 든다. 으흐흐….

Serverless로 갈아타기 위한 조건

이미 정상적으로 서비스되고 있는 API를 옮겨야 하는 작업이다보니 가장 중요한 것은 서비스에 지장을 주지 않아야 한다는 점이다. 그걸 어떻게 확신 할 수 있을까 ?

  1. 테스트를 완벽하게 꼼꼼하게 잘 해서 기존 API와 똑같이 동작하는 것을 증명해 낸다.
  2. 새로 올린 API가 잘못되었을 때 (한마디로 장애가 났을 때) 다시 되돌리는데 걸리는 시간을 최소화 한다.

이 두 가지 점에 대해서 확실한 계획을 세워서 결정권자를 설득시켜야 한다. 완벽한 테스트는 일단 포기했다. 포기한 가장 큰 이유는 일단 시간이다. 이 작업은 사업적인 측면에서 봤을땐 전혀 필요없는 작업일 수도 있기 때문에 긴 시간을 들여서 작업하기 힘들다. 사실상 회사내의 개발팀이 아닌 다른 사람들이 봤을 땐 그냥 사업적인 영역 하나를 맡아서 진행하는게 아니라서, 그냥 아무것도 안하고 놀고 있는 걸로 보일 수도 있다. 그리고 아무리 테스트를 완벽하게 한다고 한들 그렇다고 장애 대응에 대해서 전혀 생각을 안해도 되는게 아니기 때문에 완벽한 테스트는 포기하고 장애 대응 시간 최소화에 좀 더 촛점을 맞춰서 준비를 시작했다. (실제 작업에 들어간 뒤에 알게된 점이지만, 장애 포인트가 API를 잘못 옮긴 것보다는 AWS 내부적인 문제가 훨씬 더 컸었다. 망할놈의 리미트… 끊임없는 리미트… 리미트 뒤에 숨어있는 다른 리미트…)

장애 대응 플랜에 대해서는 다음 글에서 좀 더 자세히 설명하겠다.

다음글 : 2편. 장애 대응 플랜
다음글 : 3편. Lambda 배포 후 겪게되는 일들

이 글이 도움이 되셨다면 공감 및 광고 클릭을 부탁드립니다 :)