박아윤
LIFE BALANCE
Published in
6 min readSep 1, 2017

--

서버가 없는 서비스 개발기.

안녕하세요. 요새 핫한 Serverless 컨셉을 이용한 서비스 개발기를 포스팅하고자합니다. 개발 기행문이라 따로 코드나 Step-by-Step 형식의 튜토리얼 글은 아닙니다.

서비스는 구직자가 회사에 지원하는 방식이 아닌 회사가 구직자에 지원하는 역채용 서비스입니다.

서비스의 기본 스택으로 언어는 Python 3.6을 이용하였습니다. 웹 프레임워크는 Flask를 ORM인 SQLAlchemy과 같이 사용하였습니다. 위 스택들을 이용하여 빠르게 MVP를 개발을 마쳤습니다. 그리고 AWS EC2(이하 EC2)를 AWS ALB(이하 ALB)에 물려 배포하였습니다. Database는 MySQL을 Naver Cloud Platform에 올려 사용하다가 자꾸 커넥션이 끊기는 현상이 있어 결국 AWS RDS(이하 RDS)로 옮겼습니다.

배포까지 마치고나서 중요한 문제가 발생하였습니다. EC2와 RDS를 사용하였더니 아무것도 안해도 월 기본 4만원 이상이 지출되었습니다. 아직 가설을 검증하는 단계인지라 이 비용 조차도 아끼고 싶었습니다. 이걸 아껴서 Bitbucket말고 Github을 쓰고싶었습니다. (Bitbucket 이슈 트래커가 너무 안좋아요…) 그래서 파일 입출력이나 sqlite를 Database로 사용할 수 는 없어서 RDS는 무조건 써야했습니다. 그래서 대신 EC2위에서 구동되고 있는 웹 어플리케이션만이라도 AWS Lambda(이하 Lambda)로 대체하여 구동하기로 했습니다. Lambda는 리퀘스트 단위로 어플리케이션 기능을 수행 해주는 AWS의 서비스입니다. 이 특징들로 보았을 때 실시간성이나 기타 이유가 없는 한 웹 어플리케이션은 충분히 Lambda를 통해 서버 없이 운용 될 수 있습니다. (제일 중요한 가격도 매우 저렴합니다.)

예전과 달리 Lambda가 Python 2뿐만 아닌 Python 3도 지원해서 문제가 되지 않았습니다. 그리고 리서치를 해보고 나서는 Zappa를 선택하기로 했습니다. Zappa는 예전과 달리 버그도 많이 해결되고 기능도 많아져 사용하게 되었습니다. 특히 Zappa는 Lambda에 직접 콘솔을 통해 어플리케이션을 올리거나 boto같은 패키지로 코드를 짜 어플리케이션을 올려야하는 일을 손쉽게 도와줍니다. 특히 Lambda는 AWS API Gateway(이하 API Gateway)와 같이 사용해야하는 데 Zappa가 알아서 다 해주니 더 할 나위가 없습니다.

Zappa를 통해 시험 배포를 하고 나니 AWS cloudfront(cloudfront)로 된 웹 주소를 줍니다. 이를 접속해보았더니, MySQL 관련된 패키지를 제대로 임포트하지 못하는 것입니다. 관련하여 몇시간동안 수정하고 한숨을 쉬고 검색을 해본끝에 안되겠다는 결과를 도출해낼 수 있었습니다. Python 3는 MySQL Database Driver를 Python 2의 것과 호환되지않아 프로젝트가 포크되여 재작성되거나 기타 대체안들이 있었습니다. 허나 이 Driver들은 Lambda와 호환성 이슈들이 있었습니다. 그래서 이를 해결하기 위해 3가지 정도의 방법을 생각할 수 있었습니다. 일단 Driver를 포크하여 호환되게 마개조하는 방법이 있습니다. 그러나 이는 시간 비용이 너무 클 것 같아 포기하였습니다. 그래서 코드도 별로 적은데 Python 2로 내릴까 생각이 들었습니다. 그러나 이 역시도 후에 큰 기술 부채로 남을게 뻔하여 포기하였습니다. 그래서 마지막 방법을 이용하였습니다. 그냥 MySQL에서 PostgreSQL로 마이그레이트 하였습니다. MySQL을 고집할 이유도 딱히 없고 PostgreSQL Driver는 호환성 이슈도 없어 차악을 선택하였습니다.

결국 Database를 마이그레이트 하면서 시험 배포까지 성공하였습니다. 모든 기능이 정상적으로 작동됨을 확인하였습니다. 이제 마지막 관문이 남았습니다. 바로 도메인을 연결하는 것 이였습니다. 도메인 같은 경우 기존에 AWS Certificate Manager(이하 Certifcate Manager)를 통해 https 인증서를 받고 AWS Route 53(이하 Route 53)을 EC2에 물려있는 ALB와 연결하였습니다. 그리고 EC2 인스턴스 내에서 nginx를 설치하여 도메인을 설정해주었습니다. 특히 http나 서브 도메인이 붙지 않는 apex 도메인일 경우 자동으로 https://www 를 붙여서 리다이렉션을 설정해놓았습니다. 이와 똑같이 설정하기 위하여 API Gateway의 Custom Domain 기능을 이용하였습니다. 이 역시 Zappa를 통해 설정만 하면 손쉽게 할 수 있습니다. https를 위한 SSL 인증서 역시 할 수 있습니다. 허나 Cetificate Manger를 이용하려면 미국 리전을 이용해야만 되었습니다. 그러나 Zappa는 Let’s Encrpyt를 이용한 인증 기능까지 제공하고 있습니다. Zappa를 이용하여 도메인과 인증서를 설정하였습니다. 그리고 Route 53에서 A레코드를 설정하기전에 주어지는 cloudfront 주소로 접속하였습니다. 근데 {message: forbidden}이라면서 자꾸 forbidden 메시지를 리턴하는 거였습니다. 그래서 아니 도대체 무엇이 문제지 하면서 또 다시 삽을 들었습니다. 그러다가 어떻게 해서 A레코드를 설정해보고 접속 했었습니다. 정말 잘 작동하였습니다. 제일 허탈한 순간이였습니다. 이제 마지막으로 apex 도메인으로 접속시 www 리다이렉션 시키기 위해 AWS S3(이하 S3)를 이용하였습니다. S3에서 정적 웹 사이트 호스팅 기능을 이용하였습니다. 접속시 설정한 주소로 리다이렉션 하도록 하였습니다. 그리고 Route53에서 apex도메인에 alias로 A 레코드를 S3에서 설정한 주소로 지정하였습니다. 모든것이 제대로 작동하는 순간이였습니다.

개인적인 소감으로는 서비스가 비대해지는 경우 모놀리식에서 마이크로로 넘어가는 경향이 많은데 이 때 사용하면 참 좋을 것 같다고 느꼈습니다.

여기까지 AWS의 Lambda와 API Gateway 그리고 Zappa를 이용한 서버가 없는 서비스 개발기였습니다. 굳이 말하자면 AWS의 물리적인 서버가 존재하긴 하지만요…

만약 이 글을 보시고 Serverless로 하시려거든 아래 사항만 유의 해주세요.

  • AWS Lambda에서 언어와 버전을 지원하는가?
  • Database Driver가 잘 호환이 되는가?

--

--