使用 Google Cloud 實現無服務器 Node.js 函數

已發表: 2022-03-11

創建軟件並不以編寫好的代碼結束。 當軟件部署完成並能夠正確處理請求並且我們可以在不影響性能和運行成本的情況下進行擴展時,它就完成了。

您可能正在考慮如何使用雲計算來處理所有這些事情。 “那麼這個新的無服務器的東西是什麼,Vignes?”

使用 Google Cloud 的無服務器 Node.js 函數

無服務器計算是一種架構風格,其中代碼在雲平台中執行,我們無需擔心硬件和軟件設置、安全性、性能和 CPU 空閒時間成本。 這是雲計算的進步,它超越了抽象軟件環境的基礎設施。 這意味著運行代碼不需要任何配置。

使用無服務器,以下將是您的工作方式:

  1. 開發代碼。

  2. 將代碼上傳到服務提供商。

  3. 配置觸發器(在我們的例子中是一個 HTTP 請求)。

我們的工作完成了! 現在平台提供商將處理傳入的請求和擴展。

無服務器微服務簡介

無服務器架構通常與微服務風格設計相結合。 微服務是大型軟件的獨立部分,用於處理對特定模塊的請求。 通過創建可以在無服務器環境中運行的微服務,可以輕鬆維護代碼並加快部署速度。

AWS Lambda 和 GCF 簡介,比較

無服務器功能通常稱為“後端即服務”或“功能即服務”。 無服務器計算提供商的數量開始增加。 但是,一些傳統的大玩家也提供無服務器選項,例如 Amazon Web Services 的AWS Lambda Functions和 Google Cloud 的Google Cloud Functions (GCF),後者目前處於測試階段,是我正在使用的。 儘管它們的工作方式相似,但它們之間存在一些重要差異。

AWS 拉姆達谷歌云函數
語言支持Node.js、Python、C#、Java 節點.js
觸發器DynamoDB、Kinesis、S3、SNS、API 網關 (HTTP)、CloudFront 等HTTP、Cloud PubSub、雲存儲桶
最長執行時間300 秒540 秒

在本文中,我們將介紹使用 GCF 實現無服務器代碼部署的過程。 Google Cloud Functions 是一種基於事件的輕量級異步計算解決方案,它允許您創建小型、單一用途的函數來響應云事件,而無需管理服務器或運行時環境。

GCF 具有基於觸發器分離的三種可能的實現。

  1. HTTP 觸發器 將 HTTP 請求路由到雲函數

  2. 內部 Google 發布/訂閱觸發器 將發布和訂閱請求路由到雲功能

  3. 雲存儲桶觸發器 將對存儲桶所做的任何更改路由到雲函數

讓我們使用 Google Cloud Functions 創建一個基於 HTTP 觸發器的設置

Google Cloud Functions 不需要任何額外的特殊設置或安裝。 GCF 確保默認節點環境已設置並準備好執行。 當使用 HTTP 作為觸發器創建雲函數時,它會提供一個 URL 來觸發該函數。 與使用 API 網關作為與其通信的媒介的 AWS Lambda 相比,Google Cloud Functions 會根據projectID和區域立即提供 URL。

谷歌云平台圖——雲函數和AWS Lambda

創建無服務器 Node.js 應用程序

為了使我們的代碼在 GCF 中可執行,我們應該將代碼包裝在一個函數中。 每當觸發發生時,GCF 都會調用該特定函數。 可能的方法是上傳,

  1. 單個文件:導出一個默認函數,該函數將根據請求調用其他函數。

  2. 多個文件:有一個index.js文件需要所有其他文件並導出默認函數作為起點。

  3. 多個文件:在package.json中配置一個主文件,使用"main": "main.js"作為起點。

以上任何一種方法都可以。

GCF 支持特定的 Node 運行時版本。 確保編寫代碼以支持該特定版本。 在創建這篇文章時,GCF 支持 Node 版本 v6.11.1。

要創建一個函數,需要考慮的選項很少。

  1. 內存這告訴需要多少內存來處理一個運行時間的請求。 以 MB 定義。 對於小型應用程序,128MB 應該足夠了,但可以增加到 2GB。

  2. Timeout顧名思義,Timeout 定義了預期的代碼執行超時。 在此之後,代碼將被殺死並停止。 在此之後的任何執行都將突然停止。 最大超時為 540 秒。

  3. 要執行的函數雖然可以從主處理程序文件中導出多個函數,但我們需要配置一個應該觸發的函數來處理請求。 這允許開發人員擁有基於 HTTP 方法/URL 的多個入口點。

要上傳代碼,只需複制粘貼代碼即可創建功能門戶。 對於多個文件,壓縮內容並上傳文件。 確保在 ZIP 文件的情況下,應該有一個index.js文件或一個package.json文件,其中提到了主文件。

任何 NPM 模塊依賴都應該在package.json中提及。 GCF 嘗試在首次安裝期間安裝package.json文件中提到的模塊。

讓我們創建一個簡單的處理程序來返回 200 狀態和一些消息。 創建一個函數並將以下代碼添加到源代碼中。

 exports.httpServer = function httpServer(req, res) { console.log(req); res.status(200).send('Server is working'); } 

正在創建的函數的屏幕截圖

創建函數後,打開提供的 URL 以觸發函數。 它應該響應如下。

瀏覽器輸出“服務器正在工作”的屏幕截圖

現在,讓我們檢查日誌中的req對象。 要查看日誌,GCF 直接從控制台提供選項。 單擊垂直點並打開日誌選項。

打開日誌選項的屏幕截圖

現在,讓我們更新代碼以處理/users的簡單路由。

以下代碼用於處理/users路由的簡單GETPOST請求:

 exports.httpServer = function httpServer(req, res) { const path = req.path; switch(path) { case '/users': handleUsers(req, res); break; default: res.status(200).send('Server is working'); } }; const handleUsers = (req, res) => { if (req.method === 'GET') { res.status(200).send('Listing users...'); } else if (req.method === 'POST') { res.status(201).send('Creating User...') } else { res.status(404); } }

更新後,現在讓我們在瀏覽器中測試它,但這次最後使用/users

瀏覽器輸出“列出用戶...”的屏幕截圖

這很酷。 我們創建了一個帶有路由的基本 HTTP 服務器。

操作與調試

如果代碼是故事結束的地方,那麼您就不會研究無服務器 Node.js 應用程序等基礎設施選項。 下面簡要介紹瞭如何處理部署和調試等常見任務。 Node.js 開發人員已經為其他應用程序做的事情。

部署:

函數代碼可以通過四種方式部署。

  • 複製粘貼代碼到控制台

  • 上傳 ZIP 文件

  • 從雲存儲桶部署為 ZIP 文件

  • 從雲源存儲庫部署

顯然,最方便的選擇是從源存儲庫進行部署。

調用:

在創建函數時,Console 會提供 HTTP URL 來觸發函數,格式為: https://<region>-<project-id>.cloudfunctions.net/<function-name>

AWS Lambda 的函數存在冷啟動問題,導致函數執行需要額外的時間才能啟動。 一旦開始,以下執行將正常響應。 這個初始的額外啟動時間稱為冷啟動。 雖然我們沒有與此主題相關的 GCF 官方文檔,但在我們的測試過程中並沒有出現冷啟動問題。

調試:

GCF 與 Google Cloud 中的 Stackdriver Logging 服務集成。 所有控制台日誌和錯誤都將記錄在這裡,它有助於調試已經部署的代碼。

測試:

控制台提供了通過傳遞 JSON 作為輸入來測試函數的選項。 該函數將以 JSON 作為輸入調用,輸出將顯示在控制台中。 請求(輸入)和響應類似於 Express.js 框架,可以在開發過程本身進行單元測試。 如果您需要復習 Node.js 測試,請查看實際進行集成測試的 Node.js 指南

限制和後續步驟

使用無服務器功能有其自身的優勢,但也有局限性

  • 供應商鎖定:它將我們編寫的代碼限制在一個特定的服務提供商。 將代碼移動到另一個提供商需要在遷移過程中付出巨大的努力來重寫代碼。 由於這可能是一個大問題,因此我們在選擇服務提供商時應該非常小心。

  • 請求數量和硬件資源的限制:提供者通常會限制一個函數一次處理的並行請求的數量。 還有內存限制。 這些類型的限制可以通過與提供商交談來提高,但它們仍然存在。

谷歌云功能正在成熟和改進很多。 它仍在不斷改進和更新,尤其是在它可以支持的語言中。 如果您計劃使用 Google Cloud 功能,請密切關注更改日誌,以避免在實施過程中出現任何重大更改。


進一步閱讀 Toptal 工程博客:

  • 使用 TypeScript 和 Jest 支持:AWS SAM 教程