[譯] Express.js 與 AWS Lambda — 一場關於 serverless 的愛情故事

不管你是 Node.js 的職業開發者,亦或是使用 Node.js 開發過 API 的普通開發者,你都極有可能使用了 Express.js。Express 能夠稱得上是 Node.js 中最流行的框架了。html

構建 Express App 極爲容易。你僅需添加一些路由規則和對應的處理函數,一個簡單的應用就此誕生。前端

圖注:一個使用傳統託管方法的簡單 Express.js App —— 響應單次請求的過程。node

下列代碼展現了一個最簡單的 Express App:android

'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 運行起來。ios

  1. 首先將終端的工做目錄切換到 app.js 所在的文件夾,以後執行 npm init -y 命令以初始化一個新的 Node.js 項目。
  2. 使用終端執行 npm install express --save 命令以從 NPM 安裝 Express 模塊。
  3. 執行 node app.js 命令,終端會回顯 「Server is listening on port 3000.」 字樣。

瞧,這就完成了一個 Express App。若使用瀏覽器訪問 http://localhost:3000,你即可以在打開的網頁中看到 「Hello world!」 信息。git

應用部署

麻煩的問題來了:如何才能將你構建的 Express App 展現給你的朋友或者家人?如何才能讓每一個人都能訪問到它?github

應用部署是一個耗時且痛苦的過程,但如今咱們就假定你已經很快、很好地完成了部署的工做。你的應用已經能被全部人訪問了,而且以後也運轉良好。web

就這樣直到一天,忽然有一大批用戶涌入開始使用你的應用。express

你的服務器開始變得疲憊不堪,不過仍然還能工做。npm

圖注:一個使用傳統託管方法的簡單 Express.js App —— 處於較大負載下。

就這樣持續了一段時間後,它終於宕機了。☠️

圖注:一個使用傳統託管方法的簡單 Express.js App —— 由於過多用戶訪問致使應用掛掉。

一大批用戶由於應用沒法訪問而變得不開心(不管他們是否爲此應用付費)。你對此感到絕望,並開始在 Google 上尋求解決方法。若是在雲(Cloud)上部署能夠改善現狀嗎?

圖注:在雲上部署應該就能夠解決應用規模伸縮的問題了,對吧?

此時你遇到了以前一個惱人的朋友,她又在給你談論 Serverless(無服務器)技術的種種。可是等等,你如今但是有一臺服務器的呀。雖然這臺服務器是某個服務商提供的,而且它的狀態也不怎麼好暫時失去了控制,但總歸是能供你使用的。

圖注:可是,Serverless 背後仍是有一堆服務器呀!

走投無路的你願意嘗試一切方法 」挽救「 你的應用,管它是 Serverless 仍是其餘什麼黑魔法。「不過,這個 Serverless 到底是個什麼東西呢?」

你翻閱了數個網頁,包括 「Serverless Apps with Node and Claudia.js」 這本書的 第一章試讀(由 Manning Publications Co. 出版)。

在這一章中,做者使用洗衣機類比說明了 Serverless 的原理,這聽起來很瘋狂不過解釋起原理來還蠻有用。你的應用已經到了 🔥 燒眉毛的地步了,所以你決定立刻試試 Serverless。

讓你的 Express.js App Serverless 化

上面書中的一整章都是基於 AWS 的 Serverless 進行編寫的。你已經知道了 Serverless API 是由 API Gateway 和 AWS Lambda function 組成的。如今須要考慮的是如何讓你的 Express App Serveless 化。

就像 Matt Damon 出演的電影《縮小人生》中描繪的橋段,Serverless 在將來也具備無限的潛力和可能性。

圖注:如何才能讓你的 Express.js App 無縫接入 AWS Lambda?

Claudia 有能力幫助你把你的 App 部署到 AWS Lambda — 讓咱們向它請教一番!

在運行 Claudia 命令前,請確保你已經參照 教程 配置好了 AWS 的訪問憑證。

爲了能接入 AWS Lambda 和使用 Claudia 進行部署,你的代碼須要稍微調整一下。你須要 export 你的 app,而不是調用 app.listen 去啓動它。你的 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 」包裹「 一番。在 Claudia 的幫助下,你只須要在終端中執行一條命令就能夠生成 AWS Lambda 須要的 」包裹「 代碼了:

claudia generate-serverless-express-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
)
複製代碼

至此已經完成了全部的準備工做!接下來你只須要執行 claudia create 命令就能夠將你的 Express App(含 lambda.js 文件)部署到 AWS Lambda 和 API Gateway 了。

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"
  }
}
複製代碼

在瀏覽器中打開響應信息中返回的連接,若網頁展現出 「Hello world!」 那麼證實應用已經成功部署起來了!🙀

圖注:Serverless Express App。

將你的應用 Serverless 化後,你再也不畏懼用戶羣體的進一步擴大,應用會始終保持爲可用狀態。

這並非言過其實,由於在默認狀況下 AWS Lambda 可經過彈性伸縮最高支持 1000 個 function 併發執行。當 API Gateway 接收到請求後,新的 function 會在短期內處於可用狀態。

圖注:在高負載下的 Serverless Express.js App。

這並非你接入 Serverless 後惟一的收益。在保證應用不會由於高負載宕機的前提下,你一樣削減了很多應用的運行開銷。使用 AWS Lambda,你僅需按你應用的實際訪問量付費。一樣,AWS 的免費試用計劃還將給予你每應用每個月一百萬的免費流量(按訪問次數計算)。

圖注:你的 Serverless App 真是太替你省錢了!

想了解更多關於使用 Serverless 帶來的好處,請點擊查看 這篇 文章。

Serverless Express.js App 的短板

即使 Serverless Express App 聽起來超讚,卻一樣有它的不足之處。

圖注:Serverless,」閹割「 版。

下面是 Serverless Express App 一些最 「致命」 的短板:

  • Websockets 沒法在 AWS Lambda 中使用。這是由於在 AWS Lambda 中,若應用沒有任何的訪問,那麼你的服務器在客觀上也是不存在的。AWS IOT websockets over MQTT protocol 能夠提供一個 「閹割」 版的 Websockets 支持。
  • 上傳 文件到文件系統一樣是沒法工做的,除非你的上傳目錄是 /tmp 文件夾。這是由於 AWS Lambda function 對文件系統是隻讀的,即便你將文件上傳到了 /tmp 文件夾,它們也只會在 function 處於 「工做態」 時存在。爲確保你應用中的上傳功能運轉正常,你應當把文件上傳並保存到 AWS S3 上。
  • 執行限制 也將影響你的 Serverless Express App 功能。例如 API Gateway 有 30 秒的超時時間限制,AWS Lambda 最大執行時間不能超過 5 分鐘等。

這僅僅算是你的應用與 AWS Lambda 之間關於 Serverless 愛情故事的一個序章,期待儘快涌現更多的愛情故事!

如往常同樣,感謝來自個人朋友 Aleksandar Simović 以及 Milovan Jovičić 的幫助和對文章的反饋意見。

全部的插圖均是使用 SimpleDiagrams4 創做的。

若是你想了解更多關於 Serverless Express 和 Serverless App 的信息,「Serverless Apps with Node and Claudia.js」 這本書不容錯過。這本書由我和 Aleksandar Simovic 合做完成,Manning Publications 負責出版:

這本書除了會包含很多 Serverless Express App 的知識,它還將教會你如何使用 Node 和 Claudia.js 去構建、調試真實場景下的 Serverless API(含 DB 和身份校驗)。隨書還將講解如何構建 Facebook Messenger 和短信(使用 Twilio)的聊天機器人,以及如何構建亞馬遜的 Alexa skills。

再次向 Aleksandar Simovic 表示衷心的感謝。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索