用 Node.js 和 AWS Lambda 創建無服務器的微服務

ManLavallee 9年前發布 | 13K 次閱讀 微服務 Node.js Node.js 開發 AWS Lambda

在本文中,我們將使用 Lambda—Amazon Web Services(AWS)套件中的一個新工具—來啟動并運行一個微服務。 我們將使用 Lambda 創建一個 HTTP GET 終端,該終端使用 GitHub 的API 發起請求,從 GitHub 中提取存儲庫信息并返回一個 JSON 響應。

為方便你可以按本文中的步驟進行操作,你將需要一個自己的 AWS 賬戶。 如果沒有,您可以在  https://aws.amazon.com/ 上創建免費的AWS賬戶。

什么是 AWS Lambda?

Lambda 的口號是:“運行代碼不用考慮服務器”。乍一看,這可能讓人覺得比較困惑。 代碼究竟是在哪里或如何運行的呢?

無服務器與函數即服務

“無服務器”是一個新的軟件基礎設施術語,你可能有所耳聞。 它用于描述按需執行代碼的解決方案。“無服務器”這個術語可能會誤導大家,因為事實上,在程序中仍然有服務器。 更好的描述符是 FaaS 或“函數即服務”。

這兩個定義用于描述新的開發和部署經驗。 這種新體驗被認為是“無服務器”的,因為作為開發人員,不再需要管理,監視或擴展正在運行代碼的任何服務器。 您只需將代碼上傳到 FaaS 提供服務的程序(在本例中為 AWS Lambda),FaaS 提供程序將在后臺幫你執行代碼并管理所有的基礎架構。

無服務器架構的利弊

鑒于這一“無服務器”架構擴展的定義,讓我們來看看用 Lambda 工作的一些利弊。

優點

  • 按需使用定價

傳統的服務器托管使用重復計費周期。 你的服務器總是啟動和運行使用資源和等待輸入。  為了保持服務器正常運行,你按月或按年作為賬單周期來支付費用。用按需定價,Lambda 按每個函數的使用進行計費。這意味著你的項目利用 Lambda 的功能是不頻繁的,相比傳統的托管解決方案,你可以節省大量的金錢。

Lambda 定價如下:

  • 每 100 萬個請求 0.20 美元
  • 每 GB 秒的計算時間 0.00001667 美元,每次執行時間接近 100ms

  • 內置的自動伸縮功能 

    在一個傳統的被托管的基礎設施中, 你會進入到這樣一個時期,你可能需要擔心性能和擴展性。隨著應用程序使用量和通信量的增加,您可能需要添加更多的托管服務器基礎設施來跟上需求。對于你的用戶,這可能導致失敗,成為瓶頸。 當需要增加或減少額外的開銷時,Lambda 會自動完成擴展性。

缺點

  • 與本地開發工作流程不一致。

    你可以在本地寫 Lambda 功能代碼,隔離測試,但是在沒有創建你的拼裝版的 Lambda,你不能在本地模擬生產環境。

Lambda 關鍵概念

函數代碼和觸發器

Lambda 有兩個主要概念:代碼和觸發器。 代碼是不言自明的。 在我們的示例中,就是那些由您編寫并上傳到 Lambda 以產生你所需行為的 JavaScript 代碼。

一旦你上傳后,代碼不會自行執行。 Lambda 有一個稱為“觸發器”的附加概念。觸發器是由其他 AWS 服務觸發的事件,它們將數據傳遞到 Lambda 函數以供執行。

一些示例觸發器:

  • 用指向 AWS API 網關的 HTTP 請求來觸發 Lambda 代碼。

  • 用輪循的事件觸發,例如來源于 CloudWatch 事件的 corn 任務。

  • 用 DynamoDB 表的更新來觸發 Lambda 代碼。

Lambda 代碼函數簽名

你可以從與預期的 Lambda 簽名相匹配的 JavaScript 中,通過導出一個常規函數來定義一個 Lambda 函數。

exports.myLambdaFunction = (event, context, callback) => {
   // Use callback() and return 
}

該函數接收3個參數:

  1. event— Lambda 傳遞給函數的'觸發數據'的鍵值對字典。
  2. context— AWS 內部信息,例如 AWS 請求ID, Lambda 超時時間, 和日志信息.
  3. callback— 一個標準的 JavaScript 異步回調句柄。

建設Lambda函數

開始創建新的 Lambda 函數。訪問 Lambda 儀表盤:

然后會看到像這樣的界面:

點擊藍色的按鈕 創建 Lambda 函數(Create a Lambda function) 來開始。

選擇設計圖

下一個界面會提示你 選擇一個設計圖(Select a blueprint) 并提供一個可過濾的設計圖列表。點擊 空函數(Blank Function) 選項,它應該是設計圖列表中的第一個選項。這個頁面可用于將來參考著使用其它工具。

配置觸發器

接下來的界面是 配置觸發器(Configure Triggers) ,顯示成這樣:

點擊 下一步(Next) 離開這個界面。我們會在后面,建立起我們的函數之后,再來定義觸發器。

配置函數

在這一部分,需要給 Lambda 函數一個名稱。我會使用 GithubGet 這個名稱。你也可以填寫對這個函數的描述,這是可選的。

指定 Lambda 函數代碼

默認情況下,Lambda UI 設置為內聯編輯代碼。 您應該看到一個內聯編輯器,編輯器中有一個樣本函數,如下所示:

內聯編輯器需要很少的開銷來獲取和運行 lambda 代碼,但對于本教程,我們將做一些更進階的事情。

創建復雜的函數依賴關系

在大多數真實環境中,你如果要創建更多的復雜函數,常常需要通過npm來安裝第三方的庫。

讓我們創建一個使用 npm 依賴項的自定義函數,并將其上傳到Lambda。 您可以按照下面的步驟,或者可隨意使用 示例代碼庫 中的代碼

創建一個新的函數

讓我們為我們的新函數設置一個文件夾,并在文件夾中用默認的 package.json 文件初始化 npm:

npm init -f

接下來,我們將安裝 GitHub 客戶端:

npm install github

創建 index.js 文件,使用以下代碼:

var GitHubApi = require('github');
var github = new GitHubApi();

exports.handler = (event, context, callback) => {

  github.search.repos({
    q: 'sitepoint',
    sort: 'stars'
  }, function(err, res){
    if(err){
      callback(err);
    }

    var results = res.items.map((repo) => {
      return {
        url: repo.html_url,
        stars: repo.stargazers_count
      };
    });

    callback(null, {
      statusCode: 200,
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(results)
    });
  });

};

下面是這段代碼的功能細節:

  1. 引入并初始化了 GitHubAPI

  2. 定義了一個與 Lambda 簽名匹配的 handler 函數。

  3. 當 handler 函數被調用時,它會發出一個查詢請求到 GitHub,對所有符合‘sitepoint’的數據倉庫進行查詢。

  4. 在 Github 的應答格式中,創建了一個 map 數據結構,其中包含了每個數據倉庫的網址和星標數。

  5. 最后,用 http 響應(如對象)調用 Lambda 的回調函數,好與 API 網關預計集成 相匹配。

將代碼上傳到AWS Lambda

任意使用一個你熟悉的 zip 工具,創建一個包含函數文件的 zip 壓縮包。我在 OS X 系統上使用 zip 命令行是這樣的:

zip -r lambdaupload.zip ./index.js ./node_modules/

要將代碼上傳到 Lambda, 在內聯編輯器的 “代碼條目類型” 選項上選擇 “ 上傳 zip 文件 ”,然后使用彈出的窗口上傳您的代碼。

配置函數的 handler 和任務

在這一部分下,我們要設置幾個值。 Handler 是在上傳的 JavaScript 文件中 Lambda 函數的引用。 默認情況下,它設置為 index.handler。hander 函數通過查找 index 文件與我們上傳的文件相映射,并為我們 hander 函數檢索出與我們 export.handler 文件相對應的的導出語句。

使用以下信息填寫“Role”字段,為創建 Lambda 函數的基本角色:

  • Role: 從模板中創建新的 role

  • Role name: Lambda 獲取 Role

  • Policy templates: 簡單的微服務權限

這部分完成后, 單擊“Next” 按鈕繼續。比可以看到  ‘Review’ 界面的概述配置:

如果一切正常,單擊“創建函數”按鈕繼續。

為新函數分配觸發器

既然我們的函數已經創建并初始化了,我們需要一種方法來調用它。現在是時候為該函數分配觸發器了。對于觸發器的實現,我們將使用 API 網關。

API 網關是另一種 AWS 服務,它能自動創建可配置響應源的 HTTP 終端。我們將把我們的 Lambda 函數作為 API 網關的響應。

  1. 點擊‘Triggers’(觸發器)

  2. 點擊‘Add trigger’

  3. 點擊lambda旁邊的空白區域

  4. 選擇“API Gateway”

  5. 在安全性中選擇“Open”

  6. 點擊提交

這些步驟可以在下面動畫中看到:

當成功添加觸發器之后,你應該可以在 Triggers 標簽中看到觸發器和你的函數被關聯起來。

在 API 網關 ID 中會列出一個 URL。你可以訪問在瀏覽器中這個 URL,然后你贏高可以看到一個 JSON 響應,類似下面的日志:

[{"url":"https://github.com/bodrovis/Sitepoint-source","stars":106},
{"url":"https://github.com/Azzurrio/moviestore","stars":80},
{"url":"https://github.com/bodrovis/SitepointMiniChat","stars":54},
{"url":"https://github.com/upchuk/d8-demo-modules","stars":34},

恭喜!你已經成功在 Lambda 上部署和觸發代碼了。

后續及 Lambda 的未來

希望這個項目能給你在 AWS Lambda 上工作建立一個好的基礎。雖然我們在函數代碼中整合了第三方客戶端(GitHub),但它可以替換為其它客戶端 API 或者數據庫的客戶端鏈接。

無服務器框架

這篇文章中演示了建立起 Lambda 的這個過程。這過程看起來手工操作比較多,時間也不長。還有另外一個配置和初始化 Lambda 的方法,就是通過 AWS API 來完成。

現在,已經有一些框架基于 AWS API 建立起來了,它們有助于簡化這個過程。

  • https://serverless.com/

    Serverless 框架是當前最強大的無服務器框架。在寫文本的時候,這個框架進行了重大版本更新,從0.5 更新到官方 1.0 發行版。很不幸,這個更新并不向后兼容。大多數流行的插件當前還是 0.5,未能更新到 1.0,還需要等等待一段時間才能使用。

    Serverless 以及它的插件,承諾提供一個非常全面的 Lambda 體驗。它的本地開發環境提供了快速迭代、自動化的 Lambda 代碼開發、多個開發平臺環境,以及其它功能。

  • https://open-lambda.org/

    OpenLambda 試圖通過提供一個本地開發體驗來模擬 Lambda 環境。它提供工具來讓部署 Lambda 代碼變得容易,也提供快速迭代。這彌補了上面列出的 Lambda 的一些缺點。

 

來自:https://www.oschina.net/translate/getting-started-node-js-aws-lambda

 

 本文由用戶 ManLavallee 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!