serverless framework를 이용해서 서버 애플리케이션을 간단하게 배포해보자! 그리고 테스트까지!

노요셉·2019년 10월 11일
3

내일이면 코드스테이츠 이머시브 14기 4주 프로젝트가 끝이납니다.

저희 프로젝트 이름은 CreativeStorage 이름은 거창해요.
이 프로그램이 하는 일은 파일을 AWS S3 버킷에 저장하고, 자주 접근하지 않은 파일은 사용료가 더 저렴한 저장소로 파일을 이전시키는 작업을 수행합니다.

프로젝트의 개념도

저희 프로젝트는 원래 구조가 다음과 같았어요.

Koa app은 Node.js언어로 서버를 구현할 수 있는 유명한 express 프레임워크에서 빠져나온 친구입니다. 둘은 같다고 생각하고 프로젝트에서 사용했습니다.
이 둘의 장단점 비교는 주제가 아니기 때문에... 넘어갑니다.

자 이제 CreativeStorage v0.1에서는 koa를 통해 s3에 파일 업로드, 다운로드 서비스를 할 수 있게 되었습니다.
요즘 백엔드좀 안다는 분들은 다 들어보셨을 aws lambda를 적용하기로 했습니다.

aws lambda? 들어보기만 했어요.
이번 프로젝트에서 aws lambda를 살짝 사용해보면서 느낀것으로
aws lambda를 한 문장으로 설명을 하자면 다음과 같을 것 같아요.

"서버를 프로비저닝하거나 관리할 필요 없이 AWS Lambda에서 코드를 자동으로 실행합니다."

공식문서에 나와있는 설명인데요. 프로비저닝? 단어 자체가 어려워요.
프로비저닝: 서버에서 동작하는 실제 서비스로직 빼고 나머지 모두를 ( 환경, 세팅 등등 모든 부분 ) 제공해주는 것으로 이해했습니다.

그러면 aws lambda를 뭐라고 설명해야됩니까?

보통은 서버를 만들어서 서버에서 할일을 구현하잖아요. 서버프레임워크를 사용한다면 그 틀에 맞게 내부 로직을 구현할 수 있잖아요.

그런 작업을 할 필요가 없는거죠. 그냥 돌아가는 로직, RestAPI(서비스 요청을 받을 주소), 만 기입한다면 서버가 만들어진겁니다.

처음 해본 저에겐 너무 놀라운 일이였어요.

람다라는 녀석이 매우 응용될 상황이 많아서, 앞으로는 많이 사용하게 될 것 같고, AWS에 정말 모르는 기능이 너무 많은데 AWS모르면 백엔드 개발자로 살기 어려울 것 같은 느낌이 듭니다.


이미 구현된 서버를 다시 lambda로 일일이 만들어야 하나요? 전 aws lambda를 써본적도 없고, 불과 2틀만에 어디서부터 뭘 어떻게 공부해서 프로젝트에 적용해야하는지 모르겠는데요?

저의 멘토이자( 혼자만의 생각입니다 ) 세현님이 방법을 알려주셨어요.
"serverless!!"
서버리스도 결국 lambda를 만드는거잖아요. 결국 핸들러를 일일이 만들어야 합니까?

구글링을 통해 어렵지 않게 koa 프레임워크로 구현한 서버를 serverless 아키텍쳐로 바꿔주는 라이브러리를 찾게 됩니다.
"aws-serverless-koa" 저희 프로젝트에 쓰이는 키워드는 다 나오는 라이브러리인데,


뭔가 인기가 없어요.. 이번주 다운로드가 270..

다른 라이브러리 있었는데 기가막힌 친구가 있었어요.

심지어 supported framework에 Koa가 당당히 자리잡고 있습니다.

너무 간단하게 배포를 할 수 있습니다.
배포를 하기위해선 할일이 있어요.

  1. aws를 lambda를 쓸 것이기 때문에 AWS IAM에서 액세스키와 시크릿액세스키를 발급받습니다.검색하면 많이 나와요. 전 일단 모든 권한을 다 받아왔습니다.

  2. serverless config credentials 명령어를 통해 aws key를 등록합니다. 본인의 키를 쓰세요~

serverless config credentials --provider aws --key AKIAIOSFODNN7EXAMPLE --secret wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
  1. 배포하기 전에 serverless.yml이라는 서버리스를 관리하는 설정파일을 만들어서 배포가 될 서비스의 설정을 담아요. 기본적으로 라우터 등록, CORS, 등록될 리전 등등을 입력해줍니다.

  2. servereless deploy 명령어를 통해 배포를 해줍니다.

API Gateway, Lambda, 배포된 코드를 저장하는 S3Bucket이 생깁니다.

이렇게 간단하게 서버 애플리케이션을 serverless 아키텍쳐로 마이그레이션 할 수 있습니다.


이제는 테스트에 대한 얘기를 해볼게요.
이 프로젝트는 혼자 개발하는게 아니라, 이 프로젝트를 설계하고, 멘토로 프로젝트를 도와주시는 세현님과 함께 했어요. 즉 협업을 했다는 얘기죠. 그리고 프로젝트 초기에 세현님이 이 프로젝트를 오픈소스 프로젝트로 이어가고 싶으시다고 하셨어요.

테스트에 대한 중요성? 못 느꼈어요. 그거 왜 하지? 불편한거, 어렵고?

그런데 협업을 할때는요. 제가 개발하거나, 혹은 남이 개발한 코드를 동작하는지 뭘로 판단해요? 테스트가 없으면요? 그리고 그 코드를 어떻게 믿고 합치죠? 테스트가 없이 프로젝트 하는게 더 어려울거에요.

저희 프로젝트는 원격으로 진행했어요. github 이슈로 프로젝트를 진행했고, 영어가 안되서 구체적으로 깊게~ 물어볼때는 디스코드로 질문하고 세현님이 방향을 설정해주시거나 아니면 막힌 부분을 바로 뚫어주시면서 프로젝트를 진행해왔습니다.

자 이제 테스트에 대한 필요성을 이전 부터 느꼈고, 버전0.1의 경우 S3에 저장하지 않고, 서버가 동작하는 머신에 파일시스템을 이용해서 저장했어요. 물론 테스트 코드와 함께요. 물론 이때도 문제가 있었지만, jest에서 제공해주는 옵션을 통해 문제를 일차원적으로는 해결했어요.

해결방법은 "runInBand"라는 옵션인데요. 간단히 얘기하자면 jest를 테스트를 병렬로 수행하는데, 그러면 포트가 겹치잖아요. 그래서 순서대로 테스트를 하기 때문에 port already in use 라는 에러는 발생하지 않습니다. 테스트가 많아질때는 포트를 바꿔주는 방법을 써야될것 같아요.


github에 이슈가 등록되었습니다. 제가 스스로 assigned 했습니다.
서버 프로그래인 koa 애플리케이션을 serverless 아키텍쳐로 감싸고,
테스트코드로 작성해주세요.
local에서 테스트하게 해주시고, 배포를 위한 셋업까지 부탁드릴게요.

아니 서버리스면 서버리스지 로컬은 뭐에요. 역시 구글링을 통해 serverless를 로컬환경에서 배포된것처럼 테스트할 수 있는 serverless-offline을 알게 됩니다.

serverless-offline을 이용하면 람다를 배포하지 않고 로컬에서 배포될 환경과 똑같은 환경에서 테스트를 할 수 있고, 올라가는데 30초도 안걸려요. 배포를 해서 테스트하는 것과는 비교도 안되죠.

자 이렇게 터미널1에서 serverless-offline를 통해 람다를 배포한 것과 동이한 환경을 구성하고,
터미널2에서는 테스트 코드를 돌리는거에요. upload, download, filelist 테스트를 각각 수행했습니다.

아.. 왜 이렇게 테스트해요! 테스트 동작하기전에 serverless-offline 올려서 테스트 하고, 테스트 끝나면 serverless-offline 내려주세요.

말이 쉽지... serverless-offline도 하나의 프로그램인데... jest도 하나의 프로그램인데 어떻게 동시에 돌려... 자식 프로세스를 하나 더 만들지 뭐. 그런데 node.js로 그게 되나? 안되는게 어딨어...

node.js에 자식스레드를 만드는 방법은 몇 가지 있는데요. 저는
spawn() 을 이용했습니다.
그래서 spawn을 통해 자식스레드에서는 serverless-offline을 실행시키고요. jest테스트를 수행합니다.

테스트 통과..편안...

profile
서로 아는 것들을 공유해요~

2개의 댓글

comment-user-thumbnail
2019년 10월 12일

잘 읽고 갑니다 ;)
벨로그의 서버도 현재 Koa 와 serverless-http를 사용하고 있어요.
당연히, 어떤 측면에선 정말 편하기도 한데, 가끔씩은 Lambda가 이렇게 사용하라고 설계된것은 아닌 것 같기도 한 느낌이 들 때도 있어요.

가장 큰 단점으로는 서버의 로직을 한 Lambda안에 넣다보니까 조금 무거워져서, 새로 배포를 하고난 후에 Cold Start 시간이 길어질 수 있다는 점...

하나로 통합하지 않고 여러개의 Lambda로 관리한다면 서로 관련 없는 로직들끼리 완전히 분리할 수 있어서 좋은 것 같기도 하고..

솔직히 지난 1년간 사용을 해왔는데도.. 뭐가 답인지는 모르겠네요. 벨로그 v2 에서 Lambda 를 쓸 지 아니면 아예 인스턴스를 따로 만들고 오토스케일링 설정을 해서 관리할지 고민을 하고 있답니다.

1개의 답글