程序員為什么要使用AWS Lamdba?一言以蔽之,簡單。AWS Lambda和function-as-a-service平臺(如Microsoft Azure函數(shù),Google Cloud Functions和IBM OpenWhisk)通過抽象代碼堆棧中的內(nèi)容來簡化開發(fā)。程序員編寫了響應(yīng)某事件的函數(shù)(如表單提交,webhook等),并將其上傳,在代碼執(zhí)行時付費。
在《程序員請注意,無服務(wù)器將改變應(yīng)用程序開發(fā)》一文中,我們介紹了FaaS運行時的工作原理以及實現(xiàn)無服務(wù)器的軟件架構(gòu)。今天,我們會通過在AWS Lambda中創(chuàng)建一個簡單函數(shù)來展現(xiàn)更多事件操作,并討論這項強大技術(shù)的常見設(shè)計模式。
在2014年的AWS re:Invent大會上,AWS首次發(fā)布了AWS Lambda。用于解釋事件驅(qū)動的計算平臺平臺如何工作的示例如下:
將圖片上傳到S3存儲區(qū),觸發(fā)執(zhí)行Lambda功能的事件。在事件觸發(fā)之前,該函數(shù)位于磁盤上的文件中,沒有CPU 資源被使用,直到工作到達。一旦觸發(fā)器觸發(fā),該函數(shù)將被加載到Lambda運行時并傳遞有關(guān)該事件的信息。在此示例中,該函數(shù)將圖像文件從S3讀入存儲器,并創(chuàng)建不同大小的縮略圖,然后將其寫入第二個S3存儲區(qū)。
下面我們就將創(chuàng)建實現(xiàn)此示例所需的Lambda代碼框架,設(shè)置觸發(fā)器并測試我們的代碼。我們還將挖掘CloudWatch日志,以調(diào)試遇到的一些權(quán)限問題。
創(chuàng)建一個AWS Lambda函數(shù)并觸發(fā)
創(chuàng)建Lambda函數(shù)有很多方法,如Eclipse插件或者是類似Serverless Framework這樣的工具。這其中最簡單的方法之一就是使用AWS提供的藍圖。如果我們轉(zhuǎn)到AWS Lambda控制臺并單擊創(chuàng)建新功能,就會出現(xiàn)如下界面:
接下來使用Node.js來創(chuàng)建一個對S3事件作出響應(yīng)的函數(shù),所以我們從Select Runtime菜單中選擇Node.js 6.10,并將S3輸入到Filter 對話:
單擊s3-get-object blueprint,進入“配置觸發(fā)器”頁面:
在這里設(shè)置用于生成事件(infoworld.walkthrough)的bucket,并將事件類型設(shè)置為在每個bucket中創(chuàng)建新對象時觸發(fā)。接下來我們也可以進一步過濾 ,僅當(dāng)存在對象名稱中的某些前綴或后綴時才會觸發(fā)事件。但是我們跳過該操作,并單擊“下一步”按鈕啟用觸發(fā)器。
這就創(chuàng)建了基于 blueprint的功能骨架:
我們把功能命名為infoworldWalkthrough,我們可以看到它會自動檢索觸發(fā)觸發(fā)器的對象信息。
在同一配置頁面下,我們需要設(shè)置一些權(quán)限:
每個功能必須分配一個IAM角色,以便我們可以控制對AWS資源的訪問。這里我們要求系統(tǒng)創(chuàng)建一個名為infoworldRole的新角色,并將該角色的只讀權(quán)限賦予給S3。如果我們要實現(xiàn)完整的規(guī)范示例并生成縮略圖,我們還要添加S3寫入權(quán)限。但是,由于我們只需讀取有關(guān)觸發(fā)S3對象的信息,所以只讀權(quán)限應(yīng)該是足夠的。
最后,我們需要注意一些高級設(shè)置:
最重要的工作是我們要設(shè)置內(nèi)存量和執(zhí)行超時的上限。請記住,Lambda運行時借鑒了容器的流水線,它們預(yù)裝了各種語言運行時。當(dāng)一個事件觸發(fā)它會將代碼加載到這些容器中,并執(zhí)行功能。內(nèi)存和超時設(shè)置決定了容器將有多大,以及我們的功能需要執(zhí)行多少時間。在這個示例中,默認值設(shè)置為128MB和3秒比較好。如果是其它示例,可以根據(jù)自己的需求來更改默認值。
點擊“Next”進入到另一個頁面,來查看我們目前為止所有輸入的設(shè)置:
點擊“創(chuàng)建函數(shù)”按鈕在AWS Lambda中創(chuàng)建函數(shù)。
檢查我們的AWS Lambda代碼
以下是blueprint為我們創(chuàng)建的默認代碼:
在第14和15行,Lambda函數(shù)提取了bucket的名稱和觸發(fā)觸發(fā)器的對象名稱(也稱為鍵)。然后使用S3 API獲取有關(guān)對象的更多信息,(如果順利)輸出其內(nèi)容類型。雖然我們在這里沒有這樣做,但是我們可以很容易地包含,然后讀取對象的代碼,并相應(yīng)地生成縮略圖。
測試我們的AWS Lambda代碼
現(xiàn)在讓我們來到S3控制臺來解決這個問題,在這種情況下,bucket最開始是空的:
我們將InfoWorld徽標(biāo)的PNG上傳到該存儲區(qū):
從S3 控制臺還無法看出函數(shù)是否被執(zhí)行,即使訪問Lambda控制臺,也無法完全獲得。每個Lambda函數(shù)都通過CloudWatch記錄信息,所以如果我們檢查CloudWatch,就會看到有一個函數(shù)的新日志組。
檢查該日志,其顯示訪問S3 bucket 被拒絕:
當(dāng)我們的代碼嘗試讀取S3對象的信息時,被拒絕訪問數(shù)據(jù)。為什么呢?是因為我們沒有設(shè)置IAM角色,以便我們的函數(shù)在S3 bucket上具有只讀權(quán)限嗎?我們需要在IAM控制臺上仔細檢查一下:
沒錯,這個角色有一個策略,我們來看一下:
我們有權(quán)在CloudWatch中創(chuàng)建日志,但是S3只讀權(quán)限策略不知為何沒有被采取。點擊附加策略按鈕之后,我們會看到下方界面:
通過選擇AmazonS3FullAccess選項并按附加策略按鈕,為函數(shù)添加所需的權(quán)限。通過手動將PNG文件添加到S3 bucket中來測試功能:
現(xiàn)在,如果我們按測試按鈕,我們將得到一個對話框,讓我們從許多示例事件中進行選擇。我們要測試S3 put。我們需要編輯S3 key和bucket名稱字段中的值,分別對應(yīng)于我們的圖像文件和存儲bucket的名稱:
事件中各種各樣的其他字段也可以在這里設(shè)置,但是由于我們的代碼僅查看關(guān)鍵字和bucket名稱,所以先暫時忽略其余的字段。按保存和測試按鈕將觸發(fā)事件并執(zhí)行函數(shù)。與上一次不同,當(dāng)通過S3控制臺觸發(fā)事件時,我們看到了現(xiàn)場反饋。我們還可以在Lambda UI中獲取CloudWatch日志的相關(guān)部分:
您可以看到我們的代碼執(zhí)行并按預(yù)期標(biāo)識了內(nèi)容類型。
IDE集成和命令行工具(如Serverless Framework)能夠顯著加速此過程,但是這次演示顯示了通過CloudWatch創(chuàng)建具有正確權(quán)限,設(shè)置事件和調(diào)試代碼的功能以及兩種不同的方式觸發(fā)事件,以便可以測試該功能。
我們來看看一些常見的Lambda設(shè)計模式。
AWS Lambda設(shè)計模式
針對無服務(wù)器應(yīng)用程序架構(gòu)出現(xiàn)了許多設(shè)計模式。AWS re:Invent上“ 無服務(wù)架構(gòu)模式”和“最佳實踐 ”的會議上強調(diào)了四個模式。接下來,我會介紹兩個自己很喜歡的模式,因為它們適用于剛剛開始使用無服務(wù)器架構(gòu)!
首先,構(gòu)建Web應(yīng)用程序,使用S3和CloudFront進行靜態(tài)內(nèi)容,使用由Lambda和DynamoDB支持API網(wǎng)關(guān)的動態(tài)需求:
這種基本模式可以在多個級別的安全性下緊密鎖定:
Web應(yīng)用程序的大部分內(nèi)容對于用戶來說是只讀的,并且可以從S3和CloudWatch獲得此模型。授權(quán)數(shù)據(jù)可以利用IAM hook API網(wǎng)關(guān)以及與DynamoDB進行交互的單個Lambda函數(shù)的IAM角色。
我第二個最喜歡的用例 - 由Capital One為其Cloud Custodian項目實施 - 是使用Lambda設(shè)置自動化hook。 在Capital One的實施中,CloudWatch日志事件觸發(fā)Lambda函數(shù),以針對Capital One特有的合規(guī)性和策略規(guī)則執(zhí)行檢查。 當(dāng)發(fā)現(xiàn)潛在問題時,該功能將通過Amazon SNS生成通知,可通過Amazon SNS配置發(fā)送短信,電子郵件和其他一些機制,以便向正確的人員發(fā)出需要注意的違規(guī)策略。
我喜歡這種自動化模式,因為它為現(xiàn)有流程增加了巨大的價值,而不會以任何方式擾亂該流程。系統(tǒng)合規(guī)性是自動化的,而不會觸及被監(jiān)控的系統(tǒng)。
更多思考
如我們所見,設(shè)置Lambda功能,配置事件,應(yīng)用安全策略和測試結(jié)果是一個沒有IDE或命令行工具的快照。 Microsoft,Google和IBM為他們的FaaS運行時提供了類似的輕松onboarding功能。 加上設(shè)計模式的出現(xiàn),這無疑將為更高級的工具和重用鋪平道路。
無服務(wù)器應(yīng)用程序體系結(jié)構(gòu)表現(xiàn)出非常不同的心態(tài)。 代碼段較小,僅在觸發(fā)時才執(zhí)行,降低了成本,并通過松散耦合的事件而不是靜態(tài)定義的API綁定在一起。 無服務(wù)器可以實現(xiàn)比之前可能更快的開發(fā)周期,并且利用簡單的自動化和Web應(yīng)用程序設(shè)計模式,風(fēng)險更低。