AWS 上的專案

建立現代 Web 應用程式

部署 Web 應用程式、連接資料庫,以及分析使用者行為

第 5 單元:擷取使用者行為

在本單元中,您將使用 AWS Lambda 和其他無伺服器服務捕擷取使用者行為。

概觀

現在,您的 Mythical Mysfits 站點已啟動並在執行中,接著我們將建立一種新的方法,以便更好地了解使用者會如何與網站及其 Mysfits 互動。當我們採用或點讚 mysfits 時,我們將能非常容易地分析使用者在網站上的動作,而這些動作會導致我們後端的資料變更。

但是,了解使用者在決定點讚或採用 mysfit 之前於網站上的動作,可能有助您在將來設計更好的使用者體驗,從而加快採用 mysfit。為幫助我們收集這些洞見,我們將實作網站前端提交微小請求的能力,即使用者每次點按 mysfit 設定檔,均會我們建立的新微型服務 API 提交一次請求。這些記錄將由無伺服器程式碼函數即時予以處理、彙總及存放,以供將來可能執行的任何分析之用。

現代應用程式設計原則偏好專注、分離和模組化的服務。因此,我們不會在到目前為止您一直在使用的現有 Mysfits 服務中新增其他方法和功能,而是建立一個新的分離服務,以從 Mysfits 網站接收使用者點按事件。該完整堆疊已使用提供的 CloudFormation 範本表示。

架構圖

擷取使用者行為

為什麼選擇 AWS Lambda 進行此實作?

Lambda 非常適合需要即時回應資料變更、系統狀態變化或使用者動作的資料驅動型應用程式。這些應用程式通常會連接至資料存放區,以存取和分析資料,從而便於進行批次處理、串流分析和機器學習推斷。Lambda 非常適合這些應用程式,因為它已與 Kinesis Data Streams 和 Data Firehose、S3、CloudWatch Events、CloudWatch Logs 及 DynamoDB 等資料存放區整合,目前共有 17 個事件來源。   

本單元中使用的無伺服器資源

AWS Kinesis Firehose 交付串流:Kinesis Firehose 是一項高可用性的受管即時串流服務,可接受資料記錄並將其自動擷取至 AWS 內的多個可能的儲存目標中,例如 Amazon S3 儲存貯體或 Amazon Redshift 資料倉儲叢集。Kinesis Firehose 還可以將串流接收的所有記錄自動交付至使用 AWS Lambda 建立的無伺服器函數中。這意味著您編寫的程式碼可以對記錄進行任何其他處理或轉換,然後再將它們進行彙總並存放在設定的目標中。

Amazon S3 儲存貯體:S3 中將建立一個新儲存貯體,其中所有已處理的點按事件記錄都將彙總至檔案中並存放為物件。

AWS Lambda 函數:AWS Lambda 讓開發人員能夠編寫僅包含其邏輯要求的程式碼函數,並實現其程式碼的部署、叫用、高可靠性及擴展性,而無需管理任何基礎架構。此處,使用了 AWS SAM 定義無伺服器程式碼函數。它將部署到以 Python 編寫的 AWS Lambda,然後處理並豐富交付串流接收的點按記錄。我們編寫的程式碼非常簡單,且可以在網站前端完成進行豐富,而無需任何後續處理。該函數可擷取有關 Mysfit 上點按的其他屬性,從而令點按記錄更有意義 (網站前端已擷取的資料)。但是,基於本研討會的目的,該程式碼旨在演示包含無伺服器程式碼函數的架構可能性,以便在存放記錄之前即時執行任何其他所需的處理或轉換。一旦建立 Lambda 函數並將 Kinesis Firehose 交付串流設定為函數的事件來源,交付串流會自動將點按記錄作為事件交付至我們建立的程式碼函數,接收程式碼傳回的回應,以及將更新的記錄交付至已設定的 Amazon S3 儲存貯體。

Amazon API Gateway REST API:AWS Kinesis Firehose 與其他 AWS 服務一樣,可提供服務 API,且在這種情況下,我們會使用其 PutRecord 操作將使用者點按事件記錄置放於交付串流中。但是,我們並不希望我們的網站前端一定要直接與 Kinesis Firehose PutRecord API 整合。這樣可能需要我們在前端程式碼中管理 AWS 登入資料以授權對 PutRecord API 的那些 API 請求,並且其將向使用者公開所依賴的直接 AWS API (這或會鼓勵惡意網站訪客嘗試新增記錄至格式不正確或不利於我們理解真實使用者行為的目標的交付串流中)。所以,我們將使用 Amazon API Gateway 來建立 Kinesis Firehose 的 PutRecord API 的 AWS 服務代理。這樣一來,我們將能構建自己的公共 RESTful 端點,而該端點無需在前端進行 AWS 登入資料管理亦可處理請求。另外,我們還將在 API Gateway 中使用請求映射範本,這樣,我們將能定義自己的請求承載結構 (該結構將請求限制為我們期望的結構),然後將這些格式正確的請求轉換為 Kinesis Firehose PutRecord API 要求的結構。

IAM 角色:Kinesis Firehose 需要一個服務角色,可讓其將接收的記錄作為事件交付至建立的 Lambda 函數,以及將處理後的記錄交付至目標 S3 儲存貯體。Amazon API Gateway API 還需要一個新角色,允許 API 針對每個接收的 API 請求在 Kinesis Firehose 中叫用 PutRecord API。

實作說明

  • A:建立新的 CodeCommit 資料儲存器

    您將使用 CloudFormation 部署的新堆疊不僅包含基礎架構環境資源,還包含 AWS Lambda 為處理串流事件而執行的應用程式程式碼。要將基礎架構和程式碼的建立捆綁在一個部署中,我們將使用預先安裝在 AWS Cloud9 IDE 中的另一個 AWS 工具 - AWS SAM CLI。透過將 .zip 封裝中的函數程式碼上傳到 Amazon S3 儲存貯體,即可將 AWS Lambda 函數程式碼交付至服務中。

    SAM CLI 可為我們自動執行該程序。使用它,我們可以建立一個 CloudFormation 範本,而該範本可在存放 Lambda 函數的所有程式碼的檔案系統中進行本地參考。然後,SAM CLI 將其封裝在一個 .zip 檔案中,將其上傳到已設定的 Amazon S3 儲存貯體,並建立一個新的 CloudFormation 範本,該範本可指示在 S3 中已建立的 .zip 封裝已上傳到 AWS Lambda 以進行部署的位置。然後,我們可以將該 SAM CLI 產生的 CloudFormation 範本部署到 AWS 上,並觀察使用 Lambda 函數建立的環境,其中該函數會使用 SAM CLI 上傳的程式碼封裝。

    首先,我們建立一個新的 CodeCommit 資料儲存器,其中包含即時串流服務程式碼:

    aws codecommit create-repository --repository-name MythicalMysfitsStreamingService-Repository

    在該命令的回應中,複製 "cloneUrlHttp" 的值。它的格式應為:https://git-codecommit.REPLACE_ME_REGION.amazonaws.com/v1/repos/MythicalMysfitsStreamingService-Repository

    接下來,我們將向 IDE 中複製新的空資料儲存器:

    cd ~/environment/
    git clone {insert the copied cloneValueUrl from above}
    B:複製串流服務程式碼庫

    現在,讓我們將工作目錄移動到這個新的資料儲存器中:

    cd ~/environment/MythicalMysfitsStreamingService-Repository/

    然後,將 module-5 應用程式元件複製到這個新的資料儲存器目錄中:

    cp -r ~/environment/aws-modern-application-workshop/module-5/app/streaming/* .

    另外,我們還可為本單元複製 CloudFormation 範本

    cp ~/environment/aws-modern-application-workshop/module-5/cfn/* .
  • A:使用 Pip 安裝 Lambda 函數相依項

    現在,我們已用提供的所有成品設定了資料儲存器目錄:

    一個用於建立完整堆疊的 CFN 範本。

    一個包含 Lambda 函數程式碼的 Python 指令碼:streamProcessor.py

    這是 AWS 客戶常用的一種方法 - 將其 CloudFormation 範本與其應用程式程式碼一起存放於資料儲存器中。這樣,您就可以在一個地方追蹤應用程式及其環境的所有變更。

    但是,如果您查看 streamProcessor.py 檔案中的程式碼,您會發現它正在使用請求 Python 封裝,以為您之前建立的 Mythical Mysfits 服務請求 API。外部資料庫不會自動包含在 AWS Lambda 執行時間環境中,因為不同的 AWS 客戶可能依賴於各種不同的資料庫版本。

    在將所有資料庫相依項與 Lambda 程式碼函數一起上傳到 Lambda 服務之前,您需要將其封裝。我們將使用 Python 封裝管理器 pip 完成此動作。在 Cloud9 終端中,執行以下命令,以在本地安裝請求封裝、其相依項以及函數程式碼:

    pip install requests -t .

    完成該命令後,您將會看到有多個其他的 python 封裝資料夾存放於您的資料儲存器目錄中。

    B:更新 Lambda 函數程式碼

    接下來,在完全準備好部署 Lambda 函數程式碼之前,我們需要進行一次程式碼變更。streamProcessor.py 檔案中有一列需要取代為適用於 Mysfits 服務 API 的 ApiEndpoint - 您在第 4 單元中建立並在網站前端使用的同一服務 ApiEndpoint。

    replace-api-endpoint

    該服務負責與 DynamoDB 中的 MysfitsTable 整合,因此,即使是我們也可以編寫直接與 DynamoDB 資料表整合的 Lambda 函數,這樣一來,便會干擾第一個微型服務的目的,並給我們留下多個/單個與同一資料表整合的程式碼。不過,我們將會透過現有服務與該資料表集成,並設定更加分離和模組化的應用程式架構。

    C:將您的程式碼推送至 CodeCommit

    我們可以將程式碼變更遞交至新的資料儲存器,以便將其儲存在 CodeCommit 中:

    git add .
    git commit -m "New stream processing service."
    git push
  • A:為 Lambda 函數程式碼封裝建立 S3 儲存貯體

    在 Python 檔案中變更該列並遞交我們的程式碼之後,我們準備使用 AWS SAM CLI 封裝所有的函數程式碼,將其上傳到 S3,並建立可部署的 CloudFormation 範本,進而建立我們的串流堆疊。

    首先,使用 AWS CLI 建立一個新的 S3 儲存貯體,而我們的 Lambda 函數程式碼封裝會上傳到該儲存貯體。S3 儲存貯體名稱在所有 AWS 客戶之間必須為全域唯一,因此請將此儲存貯體名稱的結尾取代為您的獨有字串:

    B:使用 SAM CLI 封裝您的 Lambda 程式碼

    建立儲存貯體後,我們準備使用 SAM CLI 封裝及上傳我們的程式碼並轉換 CloudFormation 範本,請確保將上一個命令參數取代為上面剛剛建立的儲存貯體名稱 (此命令還假定您的終端仍在資料儲存器工作目錄中):

    sam package --template-file ./real-time-streaming.yml --output-template-file ./transformed-streaming.yml --s3-bucket replace-with-your-bucket-name

    如果成功,您將在 ./MythicalMysfitsStreamingService-Repository/ 目錄中看到新建立的 transformed-streaming.yml 方案,如果查看其內容,則會發現無伺服器 Lambda 函數的 CodeUri 參數已更新為 SAM CLI 上傳封裝程式碼的物件位置。

    C:使用 AWS CloudFormation 部署堆疊

    SAM CLI 命令還傳回了 CloudFormation 命令,後者是建立新的完整堆疊需要執行的命令。但是,由於我們的堆疊建立了 IAM 資源,因此您需要在命令中添加一個額外參數。執行以下命令以部署串流堆疊:

    aws cloudformation deploy --template-file /home/ec2-user/environment/MythicalMysfitsStreamingService-Repository/cfn/transformed-streaming.yml --stack-name MythicalMysfitsStreamingStack --capabilities CAPABILITY_IAM

    一旦完成此堆疊建立,便會建立完整的即時處理微型服務。

    若未來出現這樣一種案例,即僅需對 Lambda 函數進行程式碼變更而 CloudFormation 堆疊的其餘部分保持不變,您可以重複上述相同的 AWS SAM CLI 和 CloudFormation 命令。這樣一來,基礎架構環境將會保持不變,但是 Lambda 函數會出現程式碼部署。

  • A:更新網站內容

    隨著串流堆疊的建立和執行,我們現在需要發佈 Mythical Mysfits 前端的新版本,其中包括可在使用者點按 mysfit 設定檔時將事件傳送到我們的服務的 JavaScript。

    新的 index.html 檔案包含於:~/environment/aws-modern-application-workshop/module-5/web/index.html

    該檔案包含與第 4 單元相同且需要更新的預留位置,及一個額外預留位置以用於剛剛建立的新串流處理服務端點。對於先前的變數值,您可以參閱之前在第 4 單元中已更新的 index.html 檔案。

    對新的串流堆疊執行以下命令,以為您的串流處理服務擷取新的 API Gateway 端點:

    aws cloudformation describe-stacks --stack-name MythicalMysfitsStreamingStack
    B:將新站點版本推送到 S3

    index.html 中的最終值取代為 streamingApiEndpoint,隨後您即可發佈最終的 Mythical Mysfits 主頁更新:

    aws s3 cp ~/environment/aws-modern-application-workshop/module-5/web/index.html s3://YOUR-S3-BUCKET/

    再次在瀏覽器中重新整理您的 Mythical Mysfits 網站,您即會擁有一個站點,而該站點會在使用者每次點按 mysfits 設定檔時進行記錄和發佈!

    檢視已處理的記錄,它們將到達作為 MythicalMysfitsStreamingStack 的一部分而建立的目標 S3 儲存貯體中。

    現在,您已經擁有完整的現代應用程式架構,我們鼓勵您現在探索 AWS 主控台 以及您已建立的用於啟動 Mythical Mysfits 的所有各種服務!

  • 請務必刪除在研討會上建立的所有資源,以確保對資源的計費不會持續超過您預期的時間。我們建議您利用 AWS 主控台探索您已建立的資源並適時予以刪除

    對於使用 AWS CloudFormation 佈建資源的兩種情況,您僅需為每個堆疊執行以下 CLI 命令即可刪除這些資源:

    aws cloudformation delete-stack --stack-name STACK-NAME-HERE

    要刪除所有建立的資源,您可以瀏覽下列 AWS 主控台,其中包含您在 Mythical Mysfits 研討會期間建立的資源:

結論

本次體驗旨在讓您體會到成為一名開發人員在 AWS 上設計和建置現代應用程式架構的感覺。AWS 開發人員能夠使用 AWS CLI 以編程方式佈建資源,透過 AWS CloudFormation 重複使用基礎架構定義,使用 AWS 開發人員工具套件的程式碼服務自動建置和部署程式碼變更,以及利用多種不同的運算和應用程式服務功能,而完全不需要您佈建或管理任何伺服器!

接下來,要進一步了解您建立的 Mythical Mysfits 網站的內部工作原理,請深入研究提供的 CloudFormation 範本及其中宣告的資源。

我們希望您喜歡 AWS Modern Application Workshop! GitHub 上亦託管了本教學,因此如果您有任何建議,可以提交問題。如果您想要協作改進程式碼,還可以初始化 GitHub 提取請求。

如果您想進一步了解有關在 AWS 上進行開發的資訊,請瀏覽我們的 AWS 開發人員中心

恭喜您!

您在 AWS 上建置了一個現代 Web 應用程式。
與您的朋友分享或向我們傳送意見回饋。

Twilight Glitter 對您的作品印象深刻