使用無服務器框架、AWS 和 BigQuery 構建應用程序
已發表: 2021-01-28無服務器是指由雲提供商管理和分配服務器和資源的應用程序。 這意味著雲提供商動態分配資源。 該應用程序在一個可以由事件觸發的無狀態容器中運行。 上面的一個示例以及我們將在本文中使用的示例是關於AWS Lambda的。
簡而言之,我們可以將“無服務器應用程序”確定為基於事件驅動的基於雲的系統的應用程序。 該應用程序依賴於第三方服務、客戶端邏輯和遠程調用(直接將其稱為 Function as a Service )。
為 Amazon AWS 安裝和配置無服務器框架
1.無服務器框架
無服務器框架是一個開源框架。 它由一個命令行界面或 CLI 和一個託管儀表板組成,它為我們提供了一個完全無服務器的應用程序管理系統。 使用該框架可確保減少開銷和成本,快速開發和部署並保護無服務器應用程序。
在繼續安裝無服務器框架之前,您必須先設置 NodeJS。 在大多數操作系統上很容易做到——您只需訪問官方 NodeJS 站點即可下載並安裝它。 記得選擇高於 6.0.0 的版本。
安裝後,您可以通過在控制台中運行node -v
來確認 NodeJS 可用。 它應該返回您已安裝的節點版本:
您現在可以開始了,所以繼續安裝無服務器框架。
為此,請按照文檔設置和配置框架。 如果你願意,你可以只為一個項目安裝它,但在 DevriX,我們通常在全局安裝框架: npm install -g serverless
等待該過程完成並通過運行以下命令確保 Serverless 已成功安裝: serverless -v
2. 創建亞馬遜 AWS 賬戶
在繼續創建示例應用程序之前,您應該在Amazon AWS中創建一個賬戶。 如果您還沒有,只需前往 Amazon AWS 並單擊右上角的“創建 AWS 帳戶”並按照步驟創建帳戶即可。
亞馬遜要求您輸入信用卡,因此您必須輸入該信息才能繼續操作。 成功註冊並登錄後,您應該會看到 AWS 管理控制台:
偉大的! 現在讓我們繼續創建您的應用程序。
3. 使用 AWS Provider 配置無服務器框架並創建示例應用程序
在這一步中,我們必須使用 AWS 提供商配置無服務器框架。 某些服務(例如 AWS Lambda)在您訪問它們時需要憑證,以確保您有權訪問該服務所擁有的資源。 AWS 建議使用 AWS Identity and Access Manager (IAM) 來完成此操作。
因此,首先也是最重要的事情是在AWS中創建一個IAM用戶,以便在我們的應用程序中使用它:
在 AWS 控制台:
- 在“查找服務”字段中鍵入IAM 。
- 點擊“IAM” 。
- 轉到“用戶” 。
- 點擊“添加用戶” 。
對於“用戶名” ,使用任何你想要的。 例如,我們使用serverless-admin。 對於“訪問類型” ,選中“程序訪問” ,然後單擊“下一步權限”。
之後,我們必須為用戶附加權限,單擊“直接附加現有策略”,搜索“管理員訪問”並單擊它。 繼續單擊“下一個標籤”
標籤是可選的,因此您可以通過單擊“下一個審核”和“創建用戶”繼續。 完成並加載後,頁面上會顯示一條成功消息,其中包含我們需要的憑據。
現在我們必須運行以下命令:
serverless config credentials --provider aws --key key --secret secret --profile serverless-admin
用上面提供的替換密鑰和秘密。 您的 AWS 憑證被創建為配置文件。 您可以通過打開~/.aws/credentials文件來仔細檢查。 它應該由 AWS 配置文件組成。 目前,在下面的示例中,它只有一個——我們創建的那個:
到目前為止做得很好! 您可以繼續使用NodeJS和內置的啟動模板創建一個示例應用程序。
注意:此外,在本文中,我們使用的是sls
命令,它是serverless
的縮寫。
創建一個空目錄並輸入它。 運行命令
ls create --template aws-nodejs
使用create –template命令指定可用模板之一,在本例中為aws-nodejs,它是一個NodeJS “Hello world”模板應用程序。
完成後,您的目錄應包含以下內容,如下所示:
我們創建了新文件handler.js和serverless.yml 。
handler.js文件存儲您的函數, serverless.yml存儲您稍後將更改的配置屬性。 如果您想知道.yml文件是什麼,簡而言之,它是一種人類可讀的數據序列化語言。 熟悉它是件好事,因為在插入任何配置參數時都會用到它。 但是現在讓我們看一下serverless.yml文件中的內容:
服務:aws-sample-application 提供者: 名稱:aws 運行時:nodejs12.x 職能: 你好: 處理程序:handler.hello
- service: – 我們的服務名稱。
- provider: – 一個包含提供者屬性的對象,正如我們在這裡看到的,我們的提供者是 AWS,我們使用的是 NodeJS 運行時。
- 函數: – 它是一個對象,包含可部署到 Lambda 的所有函數。 在這個例子中,我們只有一個名為hello的函數,它指向handler.js 的 hello 函數。
在繼續部署應用程序之前,您必須在這裡做一件關鍵的事情。 之前,我們使用配置文件(我們將其命名為serverless-admin )設置 AWS 的憑證。 現在您所要做的就是告訴無服務器配置使用該配置文件和您的區域。 打開serverless.yml並在運行時下方的provider屬性下輸入:
個人資料:無服務器管理員 地區:us-east-2
最後,我們應該有這個:
提供者: 名稱:aws 運行時:nodejs12.x 個人資料:無服務器管理員 地區:us-east-2
注意:要獲取區域,一個簡單的方法是在您登錄到控制台後查看 URL:示例:
現在我們有了關於我們生成的模板的必要信息。 讓我們檢查一下如何在本地調用該函數並將其部署到 AWS Lambda。
我們可以通過在本地調用函數來立即測試應用程序:
sls invoke local -f hello
它調用函數(但僅在本地!),並將輸出返回到控制台:
現在,如果一切正常,您可以嘗試將您的函數部署到AWS Lambda 。
那麼,有那麼複雜嗎? 不,不是! 感謝無服務器框架,它只是一行代碼:
sls deploy -v
等待一切完成,可能需要幾分鐘,如果一切正常,您應該以這樣的方式結束:
現在讓我們檢查一下 AWS 中發生了什麼。 轉到 Lambda(在“查找服務”類型Lambda中),您應該會看到您的Lambda函數已創建。
現在您可以嘗試從 AWS Lambda 調用您的函數。 在終端類型sls invoke -f hello
它應該返回與之前相同的輸出(當我們在本地測試時):
您可以通過在AWS Lambda中打開函數並轉到“監控”選項卡並單擊“在 CloudWatch 中查看日誌”來檢查是否已觸發 AWS 的函數。 “。
你應該在那裡有一個日誌。
現在,您的應用程序中仍然缺少一件事,但它是什麼……? 好吧,您沒有可以訪問您的應用程序的端點,所以讓我們使用AWS API Gateway 創建它。
您必須先打開serverless.yml文件並清除註釋。 您需要在我們的函數及其http屬性下添加一個events屬性。 這告訴無服務器框架創建一個 API 網關,並在部署應用程序時將其附加到我們的 Lambda 函數。 我們的配置文件應該這樣結束:
服務:aws-sample-application 提供者: 名稱:aws 運行時:nodejs12.x 個人資料:無服務器管理員 地區:us-east-2 職能: 你好: 處理程序:handler.hello 事件: - 網址: 路徑:/你好 方法:獲取
在http我們指定路徑和 HTTP 方法。
就是這樣,讓我們通過運行sls deploy -v
再次部署我們的應用程序
完成後,輸出終端中應該會出現一件新事物,那就是已創建的端點:
讓我們打開端點:
您應該看到您的函數正在執行、返回輸出以及有關請求的一些信息。 讓我們檢查一下我們的 Lambda 函數發生了什麼變化。
打開AWS Lambda ,然後單擊您的函數。
我們在“ Designer ”選項卡下看到我們已將API Gateway附加到我們的 Lambda 和 API Endpoint。
偉大的! 您已經創建了一個超級簡單的無服務器應用程序,將其部署到 AWS Lambda,並測試了它的功能。 此外,我們還使用AWS API Gateway添加了一個端點。
4. 如何離線運行應用程序
到目前為止,我們知道我們可以在本地調用函數,而且我們可以使用 serverless-offline 插件離線運行整個應用程序。
該插件在您的本地/開發機器上模擬 AWS Lambda 和 API Gateway。 它啟動一個 HTTP 服務器來處理請求並調用您的處理程序。
要安裝插件,請在 app 目錄中運行以下命令
npm install serverless-offline --save-dev
然後在項目的serverless.yml中打開文件並添加plugins屬性:
插件: - 無服務器離線
配置應如下所示:
服務:aws-sample-application 提供者: 名稱:aws 運行時:nodejs12.x 個人資料:無服務器管理員 地區:us-east-2 職能: 你好: 處理程序:handler.hello 事件: - 網址: 路徑:/你好 方法:獲取 插件: - 無服務器離線
要檢查我們是否已成功安裝和配置插件運行
sls --verbose
你應該看到這個:
現在在項目的根目錄中,運行命令
sls offline
如您所見, HTTP服務器正在偵聽端口 3000,您可以訪問您的函數,例如,這裡我們的 hello 函數有 http://localhost:3000/dev/hello。 打開我們有與我們之前創建的API Gateway相同的響應。
添加 Google BigQuery 集成
到目前為止,你做得很好! 你有一個使用無服務器的完整工作應用程序。 讓我們擴展我們的應用並向其添加BigQuery集成,看看它是如何工作的以及如何完成集成。
BigQuery 是一種無服務器軟件即服務 (SaaS),它是一種支持查詢的經濟高效且快速的數據倉庫。 在我們繼續將它與我們的 NodeJS 應用程序集成之前,我們必須創建一個帳戶,所以讓我們繼續。
1. 設置谷歌云控制台
轉到 https://cloud.google.com 並使用您的帳戶登錄(如果您尚未登錄) - 創建一個帳戶並繼續。
當您登錄 Google Cloud Console 時,您必須創建一個新項目。 單擊徽標旁邊的三個點,它將打開一個模式窗口,您可以在其中選擇“新建項目。 ”
輸入項目的名稱。 我們將使用bigquery-example 。 創建項目後,使用抽屜導航到BigQuery :
當 BigQuery 加載時,您將在左側看到您有權訪問的項目數據以及公共數據集。 我們在這個例子中使用了一個公共數據集。 它被命名為covid19_ecdc :
玩轉數據集和可用表。 預覽其中的數據。 這是一個公共數據集,每小時更新一次,包含有關COVID-19全球數據的信息。
我們必須創建一個 IAM 用戶 -> 服務帳戶才能訪問數據。 因此,在菜單中,點擊“IAM & Admin”,然後點擊“Service Accounts”。
單擊“創建服務帳戶”按鈕,輸入服務帳戶名稱,然後單擊“創建”。 接下來,轉到“服務帳戶權限” ,搜索並選擇“BigQuery Admin” 。
點擊“繼續”,這是最後一步,這裡你需要你的密鑰,所以點擊“密鑰”下的創建按鈕並導出為JSON 。 將它安全地保存在某個地方,我們稍後會需要它。 單擊完成以完成服務帳戶的創建。
現在,我們將使用此處生成的憑據連接 NodeJS BigQuery 庫。
2. 安裝 NodeJS BigQuery 庫
您需要安裝BigQuery NodeJS 庫才能在您剛剛創建的項目中使用它。 在應用程序目錄中運行以下命令:
首先,通過運行npm init
來初始化 npm
填寫所有問題並繼續安裝BigQuery庫:
npm install @google-cloud/bigquery
在我們繼續更改我們的函數處理程序之前,我們必須從我們之前創建的 JSON 文件中攜帶私鑰。 我們將使用無服務器環境變量來執行此操作。 您可以在此處獲取更多信息。
打開serverless.yml ,並在提供者屬性中添加環境屬性,如下所示:
環境: PROJECT_ID:${file(./config/bigquery-config.json):project_id} CLIENT_EMAIL: ${file(./config/bigquery-config.json):client_email} PRIVATE_KEY: ${file(./config/bigquery-config.json):private_key}
創建PROJECT_ID、PRIVATE_KEY和CLIENT_EMAIL環境變量,它們從我們生成的 JSON 文件中獲取相同的屬性(小寫)。 我們已將它放在config文件夾中,並將其命名為bigquery-config.json 。
現在,您最終應該得到如下所示的 serverless.yml 文件:
服務:aws-sample-application 提供者: 名稱:aws 運行時:nodejs12.x 個人資料:無服務器管理員 地區:us-east-2 環境: PROJECT_ID:${file(./config/bigquery-config.json):project_id} CLIENT_EMAIL: ${file(./config/bigquery-config.json):client_email} PRIVATE_KEY: ${file(./config/bigquery-config.json):private_key} 職能: 你好: 處理程序:handler.hello 事件: - 網址: 路徑:/你好 方法:獲取 插件: - 無服務器離線
現在打開handler.js並讓我們導入 BigQuery 庫,在文件頂部的“use strict”下添加以下行:
const {BigQuery} = require('@google-cloud/bigquery');
現在我們必須告訴 BigQuery 庫憑據。 為此,創建一個使用憑據實例化BigQuery的新常量:
常量 bigQueryClient = 新 BigQuery({ projectId:process.env.PROJECT_ID, 證書: { client_email:process.env.CLIENT_EMAIL, private_key:process.env.PRIVATE_KEY } });
接下來,讓我們創建 BigQuery SQL 查詢。 我們要檢索有關保加利亞COVID-19病例的最新信息。 在繼續之前,我們正在使用 BigQuery 查詢編輯器對其進行測試,因此我們創建了一個自定義查詢:
SELECT * FROM `bigquery-public-data.covid19_ecdc.covid_19_geographic_distribution_worldwide` WHERE geo_ ORDER BY date DESC LIMIT 1
好的! 現在讓我們在我們的 NodeJS 應用程序中實現它。
打開handler.js並粘貼下面的代碼
const query = 'SELECT * FROM `bigquery-public-data.covid19_ecdc.covid_19_geographic_distribution_worldwide` WHERE geo_id = \'BG\' ORDER BY date DESC LIMIT 1'; 常量選項 = { 查詢:查詢 } const [job] = await bigQueryClient.createQueryJob(options); const [rows] = 等待 job.getQueryResults();
我們已經創建了查詢和選項常量。 然後我們繼續將查詢作為作業運行並從中檢索結果。
讓我們還更改我們的返回處理程序以從查詢中返回生成的行:
返回 { 狀態碼:200, 正文: JSON.stringify( { 行 }, 空值, 2 ), };
讓我們看看完整的handler.js :
'使用嚴格'; 常量 {BigQuery} = 要求('@google-cloud/bigquery'); 常量 bigQueryClient = 新 BigQuery({ projectId:process.env.PROJECT_ID, 證書: { client_email:process.env.CLIENT_EMAIL, private_key:process.env.PRIVATE_KEY } }); module.exports.hello = 異步事件 => { const query = 'SELECT * FROM `bigquery-public-data.covid19_ecdc.covid_19_geographic_distribution_worldwide` WHERE geo_id = \'BG\' ORDER BY date DESC LIMIT 1'; 常量選項 = { 查詢:查詢 } const [job] = await bigQueryClient.createQueryJob(options); const [rows] = 等待 job.getQueryResults(); 返回 { 狀態碼:200, 正文: JSON.stringify( { 行 }, 空值, 2 ), }; };
好的! 讓我們在本地測試我們的功能:
sls invoke local -f hello
我們應該看到輸出:
繼續部署應用程序以通過 HTTP 端點對其進行測試,因此運行sls deploy -v
等待它完成並打開端點。 結果如下:
做得好! 我們現在有一個應用程序可以從 BigQuery 檢索數據並返迴響應! 最後讓我們檢查一下它是否離線工作。 sls offline
並加載本地端點:
幹得好。 我們快要結束這個過程了。 最後一步是稍微更改應用程序和行為。 我們想使用Application Load Balancer而不是AWS API Gateway 。 讓我們看看如何在下一章中實現這一點。
ALB – AWS 中的應用程序負載均衡器
我們已經使用AWS API Gateway 創建了我們的應用程序。 在本章中,我們將介紹如何將 API Gateway 替換為Application Load Balancer (ALB)。
首先,讓我們看看應用程序負載均衡器與 API 網關相比如何工作:
在應用程序負載均衡器中,我們將特定路徑(例如/hello/ )映射到目標組——一組資源,在我們的例子中是Lambda函數。
一個目標組只能有一個與之關聯的 Lambda 函數。 每當目標組需要響應時,應用程序負載均衡器都會向 Lambda 發送請求,並且函數必須使用響應對象進行響應。 與 API 網關一樣, ALB處理所有 HTTP(s) 請求。
ALB 和API Gateway之間存在一些差異。 一個主要區別是 API Gateway 僅支持 HTTPS (SSL),而 ALB 同時支持 HTTP 和 HTTPS。
但是,讓我們看看 API Gateway 的一些優缺點:
API網關:
優點:
- 出色的安全性。
- 實施起來很簡單。
- 部署迅速,一分鐘內即可完成。
- 可擴展性和可用性。
缺點:
- 面對高流量時,它可能會變得非常昂貴。
- 它需要更多的編排,這給開發人員增加了一定的難度。
- 由於 API 場景,性能下降會影響應用程序的速度和可靠性。
讓我們繼續創建 ALB 並切換到它,而不是使用 API Gateway:
1.什麼是ALB?
應用程序負載均衡器允許開發人員配置和路由傳入流量。 這是“ Elastic Load Balancing”的一個特性。 它充當客戶端的單一聯繫點,將傳入的應用程序流量分配給多個目標,例如多個區域中的 EC2 實例。
2. 使用 AWS UI 創建應用程序負載均衡器
讓我們通過 Amazon AWS 中的 UI 創建我們的應用程序負載均衡器 (ALB)。 在“查找服務”中登錄 AWS 控制台。 ” 鍵入“ EC2 ”並找到“負載均衡器”。 ”
單擊“應用程序負載均衡器”下的“創建負載均衡器”,選擇“創建”。 對於名稱,輸入您的選擇,我們使用“ sample-alb”,選擇方案“ internet-facing ”, IP 地址類型為ipv4。
在“ Listeners ”上,保持原樣 - HTTP 和端口 80。它可以配置為 HTTPS,儘管您必須有一個域並確認它才能使用 HTTPS。
可用區 – 對於VPC ,從下拉列表中選擇您擁有的一個並標記所有“可用區” :
單擊“下一步配置安全設置”以提示您提高負載均衡器的安全性。 點擊下一步。
在“步驟 3.Configure Security Groups ”中,在“ Assign a security group ”中選擇“Create a new security group”。 單擊“下一步:配置路由”繼續下一步。 “。 在第 4 步配置它,如上面的屏幕截圖所示:
單擊下一步、下一步和創建。
返回負載均衡器並複制 ARN,如屏幕截圖所示:
現在我們必須更改我們的 serverless.yml 並刪除 API Gateway http 屬性。 在 events 屬性下,刪除 http 屬性並添加 alb 屬性。 函數對象應該這樣結束:
你好: 處理程序:handler.hello 事件: - 白: listenerArn: arn:aws:elasticloadbalancing:us-east-2:115129174008:listener/app/sample-alb/ae6e398a898c48e6/67ce6bf319d0513d 優先級:1 狀況: 路徑:/你好
保存文件並運行部署應用程序的命令sls deploy -v
成功部署後返回 AWS 負載均衡器並找到您的 DNS 名稱,如屏幕截圖所示:
複製 DNS 名稱並輸入路徑/hello 。
它應該可以工作並最終為您提供下載內容的選項:)。 到目前為止,應用程序負載均衡器運行良好,但應用程序需要為我們的最終用戶返回正確的響應。 為此,請打開handler.js並將 return 語句替換為以下語句:
返回 { 狀態碼:200, statusDescription: "200 OK", 標題:{ “內容類型”:“應用程序/json” }, isBase64Encoded:假, 正文:JSON.stringify(行) }
ALB 的不同之處在於響應必須包含容器狀態描述、標頭和 isBase64Encoded。 請保存文件,然後再次部署,但這次不是整個應用程序,而是我們更改的功能。 運行以下命令:
sls deploy -f hello
這樣,我們只定義要部署的函數hello 。 部署成功後,再次訪問帶有路徑的DNS名稱,應該會有正確的響應了!
偉大的! 現在我們已將 API Gateway 替換為 Application Load Balancer。 應用程序負載均衡器比 API Gateway 便宜,我們現在可以擴展我們的應用程序以滿足我們的需求,特別是如果我們期望有更高的流量。
最後的話
我們使用無服務器框架、AWS和BigQuery創建了一個簡單的應用程序,並介紹了它的主要用途。 無服務器是未來,用它來處理應用程序很容易。 繼續學習並深入研究無服務器框架,以探索其所有功能和其中的秘密。 它也是一個非常簡單和方便的工具。