내가 입사할 때 까지만 해도 회사의 백엔드는 Monolithic Architecture로 하나의 거대한 백엔드 시스템에서 여러가지 기능을 담당하고 있었다.

그리고 몇가지 이유로 이제 Monolithic Architecture를 고집할 수 없겠다 싶어 점진적으로 Microservice Architecture화 하기로 결정했다.

1차적으로 백엔드의 특정 기능을 담당하는 API 서버를 분리하기로 결정했는데 이번 기회에 요즘 핫한 Serverless Architecture를 시도해보기로 했다.

AWS의 Lambda, Azure의 Functions 등 여러가지 서버리스 아키텍쳐를 위한 제품들이 나오면서 서버리스 아키텍쳐(Serverless Architecture)가 뜨고 있다.

아니, 이미 꽤나 인기있는 아키텍쳐로 자리잡은 것 같다.

언젠가 서버리스 아키텍쳐를 한번 사용해보고 싶었는데 마침 기회가 왔다.

Microservice와 Serverless

개인적으로 이 둘의 궁합은 매우 잘 맞는다고 생각한다.

마이크로서비스(Microservice)는 하나의 거대한 서비스를 백엔드 시스템으로 사용하는 것이 아닌 여러 개의 작은 모듈처럼 구축한 서비스를 백엔드 시스템으로 연결하여 사용하는 것이다.

각 서비스는 프로그래밍 언어, 프레임 워크 등을 독립적으로 선택할 수 있고, 다른 서비스들과 독립적으로 배포가 될 수 있어서 하나의 서비스로 사용할 수 있어야 한다.

이는 서비스들이 해당 서비스에 특화된 프로그래밍 언어, 프레임워크, 배포환경 등을 선택할 수 있다 는 장점을 가져온다.

또한 기존 다른 서비스들에 의존성이 없기 떄문에 서비스를 배포할 때 고려해야할 것들을 줄일 수 있다.

서버리스(Serverless)는 말 그대로 서버가 없는 환경을 의미한다.

클라우드 서비스가 발전하면서 물리적인 하드웨어 서버가 클라우드 환경의 가상머신으로 대체 된 것처럼, 여러 API들을 수행하는 백엔드 시스템이 각 API들을 수행하는 하나의 코드만을 따로 배포할 수 있게 되었다.

개발자는 그저 비즈니스 로직에 맞는 코드만 작성하면 되고 이를 배포하면 된다. 다른 인프라나 데이터베이스 등의 부가적인 환경에 대해서 신경쓰지 않아도 된다는 것을 의미한다.

Microservice와 Serverless가 공통적으로 추구하는 방향은 비즈니스 로직에 집중하는 것이다.

Microservice를 사용해 서비스를 구축하고 이를 Serverless 환경으로 배포한다면 개발자는 다른 것에는 신경쓰지 않고 오로지 비즈니스 로직을 충실히 수행하는 서비스를 구축하고 배포하면 된다.

자, 그럼 서버리스의 세계로 가봅시다.

회사에서 AWS를 사용하고 있기 때문에 AWS Lambda의 선택은 당연했지만, Lambda를 어떻게 쓰는가에 대한 선택지는 매우 다양했다.

Lambda에서 실행할 코드를 작성해 AWS 콘솔에서 업로드하고 API Gateway도 직접 설정하는 방법도 있지만,

요즘에는 서버리스 프레임 워크도 많이 나와서 매우 쉽게 서버리스 아키텍쳐를 구축할 수 있다.

또한 서버리스를 위한 프레임 워크도 매우 다양한데(Serverless, Apex, Chalice, Zappa 등) CTO님의 제안으로 Zappa라는 프레임 워크를 사용하기로 했다.

Zappa는

AWS Lambda & API Gateway에 Python WSGI Application을 배포해 서버리스 아키텍쳐를 구성해주는 프레임 워크다.

지금까지 사용하며 겪은 바로 Zappa의 (매우 주관적인)장점은 다음과 같다.

  • Python WSGI Application을 배포하기 떄문에 코드의 변경없이 Django, Flask와 같이 WSGI Application을 그대로 배포할 수 있다.(내 생각에 이게 가장 큰 장점이 아닐까 싶다.)
  • 서버리스로 가기 위한 최소한의 셋팅을 다 알아서 해준다. 프로젝트를 압축하여 Lambda에 배포하고 API Gateway에서 Lambda를 사용할 수 있게 알아서 설정해준다. 또한 몇가지 설정만 추가한다면 다른 AWS의 서비스도 사용가능하다.
  • API Gateway의 Stage를 구성하기가 매우 쉽다. 그냥 설정파일에 stage용 설정을 추가하기만 하면 끝이다. 도메인까지 설정해서 쓰면 요긴하기 쓸 수 있다.

하지만 뭐든 그렇듯 물론 장점만 있지는 않다. 내가 생각하는 Zappa의 단점은

  • 모니터링이 힘들다. New Relic을 붙여서 사용하려고 했더니 뭔가 로그가 불규칙적으로 들어온다. 문제가 뭔지 잘 모르겠다.(해결방법을 아시는 분 있다면 공유좀...)
  • 그래서 AWS X-Ray를 쓰려했더니 Node.js, Java, .Net만 지원하다고 한다. 그래서 찾아보니 xrayvision이라는 프로젝트가 있어서 사용 중이다. 하지만 X-Ray가 모니터링 하기에 뭔가 부족한 느낌의 서비스인 것 같다.
  • 아직 성숙한 프로젝트가 아니다. 그렇다고 막 버그 투성이인 프로젝트는 아니다. 그럼에도 단점에 적은 이유는 Zappa로 배포하고 테스트를 진행하던 중 뭔가 안되는 부분이 있었는데, 알고보니 아직 지원을 안하는 것이었다. 하지만 다행히(?) 내가 삽질하던 그즈음에 누군가 PR를 보냈고 머지 되어 지금은 잘 사용하고 있다. 이런것을 보면 오히려 좋은 오픈소스 프로젝트에 기여할 기회가 많다 고 생각할 수도 있다.

자, 그럼 Zappa를 써봅시다.

Zappa Github Page에 가서 보면 알겠지만 매우 간단하다.

3줄로 요약하면

(env) $ pip install zappa
(env) $ zappa init
(env) $ zappa deploy

3줄의 명령어로 Python WSGI Application을 AWS Lambda & API Gateway에 배포할 수 있다.

시작하기 전에

Zappavirtualenv 안에 설치 되어야한다. Zappa가 배포할 때 virtualenv안에 있는 패키지들을 가져와서 압축하기 때문이다.

Zappapip를 사용해서 설치하면 된다.

(env) $ pip install zappa

Zappa를 사용하기 위해 설정파일을 만들어야하는데 zappa init 이라는 명령으로 사용하면 된다.

그럼 다음과 같이 몇가지 입력을 받고 설정파일을 만들어주는데 입력은 그냥 디폴트 값으로 넣어도 무관하다.

(env) $ zappa init

███████╗ █████╗ ██████╗ ██████╗  █████╗
╚══███╔╝██╔══██╗██╔══██╗██╔══██╗██╔══██╗
  ███╔╝ ███████║██████╔╝██████╔╝███████║
 ███╔╝  ██╔══██║██╔═══╝ ██╔═══╝ ██╔══██║
███████╗██║  ██║██║     ██║     ██║  ██║
╚══════╝╚═╝  ╚═╝╚═╝     ╚═╝     ╚═╝  ╚═╝

Welcome to Zappa!

Zappa is a system for running server-less Python web applications on AWS Lambda and AWS API Gateway.
This `init` command will help you create and configure your new Zappa deployment.
Let's get started!

Your Zappa configuration can support multiple production stages, like 'dev', 'staging', and 'production'.
What do you want to call this environment (default 'dev'):

AWS Lambda and API Gateway are only available in certain regions. Let's check to make sure you have a profile set up in one that will work.
Okay, using profile default!

Your Zappa deployments will need to be uploaded to a private S3 bucket.
If you don't have a bucket yet, we'll create one for you too.
What do you want call your bucket? (default 'zappa-8wjmc0weu'):

What's the modular path to your app's function?
This will likely be something like 'your_module.app'.
Where is your app's function?: app.__init__.app

You can optionally deploy to all available regions in order to provide fast global service.
If you are using Zappa for the first time, you probably don't want to do this!
Would you like to deploy this application globally? (default 'n') [y/n/(p)rimary]:

Okay, here's your zappa_settings.json:

{
    "dev": {
        "app_function": "app.__init__.app",
        "aws_region": "ap-northeast-1",
        "profile_name": "default",
        "s3_bucket": "zappa-8wjmc0weu"
    }
}

Does this look okay? (default 'y') [y/n]:

Done! Now you can deploy your Zappa application by executing:

	$ zappa deploy dev

After that, you can update your application code with:

	$ zappa update dev

To learn more, check out our project page on GitHub here: https://github.com/Miserlou/Zappa
and stop by our Slack channel here: https://slack.zappa.io

Enjoy!,
 ~ Team Zappa!

위에 보이는 것처럼 배포는 zappa deploy <stage> 를 사용하면 된다.

최초 배포 후에는 zappa update <stage>를 사용하여 업데이트를 하면 된다.

(env) $ zappa deploy dev
Calling deploy for stage dev..
Creating zappa-dashboard-dev-ZappaLambdaExecutionRole IAM Role..
Creating zappa-permissions policy on zappa-dashboard-dev-ZappaLambdaExecutionRole IAM Role.
Downloading and installing dependencies..
Packaging project as zip.
Uploading zappa-dashboard-dev-1505403223.zip (10.5MiB)..
100%|█████████████████████████████████████████████████| 11.0M/11.0M [00:04<00:00, 2.34MB/s]
Scheduling..
Scheduled zappa-dashboard-dev-zappa-keep-warm-handler.keep_warm_callback with expression rate(4 minutes)!
Uploading zappa-dashboard-dev-template-1505403250.json (1.6KiB)..
100%|█████████████████████████████████████████████████| 1.66K/1.66K [00:00<00:00, 3.32KB/s]
Waiting for stack zappa-dashboard-dev to create (this can take a bit)..
100%|█████████████████████████████████████████████████| 4/4 [00:14<00:00,  5.26s/res]
Deploying API Gateway..
Deployment complete!: https://pqj13rwzi5.execute-api.ap-northeast-1.amazonaws.com/dev

하지만

이렇게 모든일이 일사천리로 끝난다면 매우매우 좋았겠지만 꼭 예상하지 못한 이슈가 발생하기 마련이다.

Zappa를 도입하기로 했을 때 여러가지 이슈로 삽질을 하게 되었는데,(물론 내가 부족해서 그랬던것이 대부분이지만)

그런 이슈들을 기록으로 남겨두면 좋을 것 같아 다음 포스팅으로 써야겠다.