Medium - Express.js and AWS Lambda — a serverless love story

원문 - Slobodan Stojanović

Trend 파악을 Medium 기고문 요약 포스팅 - Express.js와 AWS Lambda, 서버리스 사랑 이야기

만약 여러분이 Node.js 개발자거나 Node.js로 API를 만든적이 있으시다면 Express.js을 사용했을 확률이 높을 겁니다. Express는 Node.js 프레임워크 중 가장 인기가 많습니다. Express 응용프로그램은 매우 만들기 쉽습니다. 간단한 앱으 ㅣ경우 경로 몇개와 경로 처리를 추가하면 끝입니다. 그게 다에요.

A simple, traditionally hosted Express.js app, with a single request.

예를들어 간단한 Express 앱은 다음의 코드와 같을 것입니다.

'use strict'

const express = require('express')
const app = express()

app.get('/', (req, res) => res.send('Hello world!'))

const port = process.env.PORT || 3000
app.listen(port, () =>
  console.log(\`Server is listening on port ${port}.\`)
)

코드를 새로운 폴더에 app.js로 저장하면 간단한 express.app을 완성하기 까지 오직 세단계만 남아있습니다.

  1. 새로운 Node.js 프로젝트 생성, 이렇게 하고 npm init -y를 터미널에서 실행하세요. 현재 폴더가 app.js를 포함하고 있는지 먼저 확인하셔야 합니다.
  2. 터미널에서 npm install express –save 명령을 이용해서 npm으로부터 Express 모듈을 설치하세요
  3. node app.js 명령을 실행시키시면 “Server is listening on port 3000”을 응답으로 확인하실 수 있을겁니다.

이제 여러분은 Express app을 갖게 되었습니다. http://localhost:3000 을 브라우저에서 방문하면 헬로 월드 메시지를 보게될 것입니다.

Application deployment

이제 어려운 부분입니다; 어떻게 친구나 가족들에게 보여줄 수 있을까요? 어떻게 모든 사람이 접근할 수 있도록 만들 수 있을까요? 배포는 길고 힘든 과정이 될 수 있습니다만 빠르고 성공적으로 관리하는 것을 상상해 봅시다. 여러분의 앱은 모든사람들이 사용가능하고 행복하게 오랫동안 살았습니다.

그러던 어느날 예상치않은 사용자 무리가 여러분의 앱을 사용하기 시작합니다. 서버는 힘들어하지만 그래도 동작은 합니다.

A simple, traditionally hosted Express.js app under load.

그러던 어느날 서버가 죽어버립니다.☠️

A simple, but dead, traditionally hosted Express.js, that crashed because too many users accessed it.

사용자 무리는 화가났습니다(최소한 그들은 앱결제를 하지 않을 것입니다) 여러분은 필사적으로 해결책을 찾기위해 구글링을 합니다. 클라우드가 도움이 될까요?

Cloud should fix your scaling issues, right?

그러다가 당신은 짜증난 친구를 다시 만나게 됩니다. 그녀는 서버리스인가 뭔가에 대해 얘기를 합니다. 그치만 여러분은 서버가 있잖아요. 그것은 다른사람에게 해당되는 얘기고 당신은 그것을 통제할 수 없습니다.

But, there are servers!

그러나 당신이 필사적이라면 뭐든지 할 것이고 흑마법을 포함해서 서버리스까지 해볼 것입니다. “그래서 대체 서버리스가 뭐야?” 여러분은 “Serverless Applications with Node.js”를 포함해 많은 링크를 접하게 됩니다.

해당 챕터는 서버리스를 세탁기로 설명하고 있습니다. 정신나간 소리지만 어느정도 말이 되는 소리입니다. 그래서 여러분은 일단 시도해보기로 합니다.

Making your Express.js app serverless

위의 챕터는 모두 AWS의 서버리스에 관한 것입니다. 이제 여러분은 서버리스 API가 AWS Lambda 함수와 API 게이트웨이로 구성된다는 것을 알게 되었습니다. 그렇지만 서버리스를 여러분의 앱에 어떻게 사용할까요? 이것은 맷데이먼이 고생했던 영화만큼이나 희망적으로 들리네요…

How do you fit your Express.js app into AWS Lambda?

Claudia가 여러분의 앱을 AWS Lambda에 배포하는 것을 도와줄 것입니다. 그녀에게 물어봅시다. Claudia 명령어를 실행하기 전에 이 가이드를 참고하셔서 AWS 접근 보안을 설정하셔야 합니다.

여러분의 코드는 Claudia를 통해 살짝 수정되서 AWS Lambda를 지원하고 배포하게 될 것입니다. 여러분은 app.listen을 통해 서버를 시작하는 것 대신에 app을 내보내기 해야합니다. 여러분의 app.js는 다음의 코드와 같을 것입니다.

'use strict'

const express = require('express')
const app = express()

app.get('/', (req, res) => res.send('Hello world!'))

module.exports = app

위의 코드는 로컬 Express 서버를 망가트릴 것이기 때문에 다음과 같이 app.local.js 파일을 추가할 수 있습니다.

'use strict'

const app = require('./app')

const port = process.env.PORT || 3000
app.listen(port, ()=>
  console.log(\`Server is listening on port ${port}.\`)
)

그리고 나면 로컬 서버는 node app.local.js를 통해 실행할 수 있습니다. 여러분의 앱이 정확하게 AWS Lambda와 동작하게 하려면 Express app을 위한 AWS Lambda 래퍼를 만들필요가 있습니다. Claudia를 사용하면 다음과 같은 명령어로 해당 작업을 수행할 수 있습니다.

claudia generate-serverless-epxress-proxy --express-module app

app은 여러분의 Express app의 엔트리 이름으로 그냥 .js 확장자를 뗀 것입니다. 이것은 lambda.js 파일을 만들어 냅니다.

'use strict'
const awsServerlessExpress = require('aws-serverless-express')
const app = require('./app')
const binaryMimeTypes = [
  'application/octet-stream',
  'font/eot',
  'font/opentype',
  'font/otf',
  'image/jpeg',
  'image/png',
  'image/svg+xml'
]
const server = awsServerlessExpress
  .createServer(app, null, binaryMimeTypes)
exports.handler = (event, context) =>
  awsServerlessExpress.proxy(server, event, context
)  

끝입니다! 이제 남은것은 Express app과 lambda.js 파일을 AWS Lambda에 배포하고 claudia create명령어를 사용해 API 게이트웨이를 만드는 것입니다.

claudia create --handler lambda.handler --deploy-proxy-api --region eu-central-1

잠시후 명령이 완료되면 다음과 같은 응답이 출력됩니다.

{
  "lambda": {
    "role": "awesome-serverless-expressjs-app-executor",
    "name": "awesome-serverless-expressjs-app",
    "region": "eu-central-1"
  },
  "api": {
    "id": "iltfb5bke3",
    "url": "https://iltfb5bke3.execute-api.eu-central-1.amazonaws.com/latest"
  }
}

그리고 응답에 있던 링크를 브라우저에 입력하면 헬로월드가 출력되는 것을 보실수 있습니다!🙀

Serverless Express app.

서버리스 앱을 사용하면 사용자 무리가 지속적으로 늘어나도 여러분의 앱은 계속 동작할 것입니다. 그것이 가능한 이유는 AWS Lambda가 자동적으로 1000 동시실행을 기본적으로 확장해주기 때문입니다. 새로운 함수들은 API 게이트웨이가 요청을 받은 후 잠시뒤에 준비됩니다.

Serverless Express.js app under heavy load.

그러나 이게 유일한 장점은 아닙니다. 높은 부하에도 안정적인 앱과 더불어 돈도 절약하게 됩니다. AWS Lambda를 사용하면 요청에 사용한 만큼만 돈을 내게됩니다. 또한 프리티어의 경우 처음 백만개의 요청은 매달 무료입니다.

Your serverless app also saves your money!

서버리스를 통한 비즈니스 장점에 대해 더욱 알고 싶다면 이 기사를 참고하세요

Limitations of serverless Express.js apps

서버리스 Express app이 멋지게 보이지만 몇가지 제약사항이 있습니다.

Serverless, the limited edition.

서버리스 Express app의 중요한 제약사항은 다음과 같습니다.

  • 웹소켓은 AWS Lambda와 동작하지 않습니다. 요청이 없을 때는 여러분의 서버도 존재하지 않기 떄문입니다. AWS IOT 웹소켓 등 웹소켓에 대한 제한적인 지원이 가능하긴 합니다.
  • /tmp 폴더에 업로드를 하지 않는 이상 파일시스템에 업로드 또한 동작하지 않습니다. 이것은 AWS Lambda 함수가 읽기전용이기 때문입니다. 여러분이 파일을 /tmp 폴더에 업로드해도 아주 잠깐 동안만 존재하게 될 것입니다. 업로드 피쳐를 동작하게 하려면 AWS S3에 파일을 업로드 해야합니다.
  • 실행 제한이 여러분의 서버리스 Express app에 영향을 줄 수 있습니다. 왜냐면 API 게이트웨이가 30초의 타임아웃이 있고 AWS Lambda의 최대 실행은 5분이기 때문입니다.

Summary

  • Express + AWS Lambda + Claudia를 사용한 Serverless Express app 만들기 예제
  • 합리적인 가격으로 확장가능한 간단한 서버를 만들 수 있지만 업로드 및 웹소켓을 지원하지 않고 게이트웨이 API 및 AWS Lambda의 타임아웃 때문에 실행 제약사항이 있다는 것을 주의해야 한다.

© 2019. All rights reserved.

Powered by Hydejack v8.1.1