- 原文地址:Express.js and AWS Lambda — a serverless love story
- 原文作者:Slobodan Stojanović
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:劉嘉一
- 校對者:FateZeros,Han Song
無論你是 Node.js 的職業開發者,亦或是使用 Node.js 開發過 API 的普通開發者,你都極有可能使用了 Express.js。Express 可以稱得上是 Node.js 中最流行的框架了。
構建 Express App 極為容易。你僅需新增一些路由規則和對應的處理函式,一個簡單的應用就此誕生。
圖注:一個使用傳統託管方法的簡單 Express.js App —— 響應單次請求的過程。
下列程式碼展示了一個最簡單的 Express App:
'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 執行起來。
- 首先將終端的工作目錄切換到
app.js
所在的資料夾,之後執行npm init -y
命令以初始化一個新的 Node.js 專案。 - 使用終端執行
npm install express --save
命令以從 NPM 安裝 Express 模組。 - 執行
node app.js
命令,終端會回顯 “Server is listening on port 3000.” 字樣。
瞧,這就完成了一個 Express App。若使用瀏覽器訪問 http://localhost:3000,你便可以在開啟的網頁中看到 “Hello world!” 資訊。
應用部署
麻煩的問題來了:如何才能將你構建的 Express App 展示給你的朋友或者家人?如何才能讓每個人都能訪問到它?
應用部署是一個耗時且痛苦的過程,但現在我們就假定你已經很快、很好地完成了部署的工作。你的應用已經能被所有人訪問了,並且之後也運轉良好。
就這樣直到一天,突然有一大批使用者湧入開始使用你的應用。
你的伺服器開始變得疲憊不堪,不過仍然還能工作。
圖注:一個使用傳統託管方法的簡單 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 表示衷心的感謝。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。