Lambda是AWS上的其中一種服務,它是Serverless概念的一種,所謂的Serverless,說得簡單一點,就是開發者著重在程式,而不需要費心去管理伺服器,例如:Linux的操作指令、佈署的環境安裝等相關作業,這一類的跟程式邏輯沒有太大關係的作業,Serverless就是要幫開發人員省掉這些功夫。雖說如此,因為Serverless是一種全新的概念,所以和當初學校所教授的課程,有很大的差異,這些差異包含:
-
程式的佈署:
早期的網頁程式是整個包成一包,而將我們寫好的這一包程式,放在網頁上後去執行;但Serverless的情況不是,Serverless的狀況,最小的單位稱為Function,每一個Function,負責一段商業邏輯。舉個例子,假設我們的網站有100個功能,早期會將這100個功能包成一包,放到一台伺服器上,但Serverless的情況變成,我們要分別將100個功能,分成100包檔案,佈署到100個Lambda Server上。
-
Session的處理:
因為早期程式都在同一台Server上,所以Session的處理會交由Web Container(例如:tomcat)來負責;但變為Serverless的架構後,因為Function佈署在不同的機器上,所以並沒有Session的機制,如果真的需要Session的機制的話,只能想辧法自行作出Session機制。
-
程式的運行時間:
因為Serverless的金額計算,是以程式執行的時間來計算,換句話說,程式如果沒有執行的話,是不用算錢的。而為了防止程式進入無窮迴圈的狀態下,系統會有一個預設的運行時間(Lambda最大運行時間為300秒,每個Function需要個別設定),如果程式執行時間超過設定時間,Lambda服務會自動中斷整個程式的運行,這點是在設計Serverless時必須要特別考慮的問題。
這幾點是我們在早期的程式設計與Serverless設計的很大差異。
Lambda的費用與免費額度
Lambda計算方式,其實跟EC2差不多,Lambda的金額計算是以先選擇執行機器的大小(Memory)後,再根據執行的時間,並加上呼叫的次數、資料的傳輸量來計費。簡單地說,就是:
-
Memory的大小配合程式執行時間
-
呼叫次數
-
資料傳輸量
關於Lambda的定價,可參考AWS的官網。
如果將Lambda的運行時間計算拉到跟EC2一樣的話(配合相同的記憶體),其實會發現Lambda其實比EC2貴了大約三倍左右;這樣子的狀況下,Lambda的競爭優勢在於:
非運行的時間是不收費用的。
也就是說,我們將Function的程式寫好,但如果沒有人去呼叫它的話,是不會有費用產生的,這一點跟EC2是完全不同的。再加上Lambda的功能,對開發者而言,不需去管理伺服器的,包含Load Balancer及Auto Scaling,甚至是被攻擊等相關顧慮,都交由AWS來負責,這對一個開發者而言是非常有吸引力的事情。
Lambda的免費額度
Lambda 免費方案包含每月 100 萬個免費請求以及每月 400,000 GB-秒的運算時間;這個400,000 GB-秒的部份,會根據我們選擇的記憶體(Memory)而有不同的免費秒數,例如:
Lambda運行在512MB的機器上,那就會有800,000的免費秒數。
而很重要的一點是,目前應該是AWS在推廣Serveless的關係吧,這個免費額度目前並沒有受到一年的影響,也就是說,即使免費的頭一年過後,AWS還是提供每月 100 萬個免費請求以及每月 400,000 GB-秒的運算時間,如下圖:
不過,不能保証AWS是會永遠提供免費額度,所以各位讀者在一年的免費額度後,還是重新確認一下官網資訊比較好。
開發第一支Lambda程式
在開發前,我們必須先瞭解Lambda的幾樣特性:
-
Lambda是被動式的呼叫,而且它並不支援外部網址;Lambda只支援AWS服務本身來呼叫;換句話說,Lambda必須搭配某個AWS的服務,所以當我們決定使用Lambda,我們要有知覺,我們已經被AWS綁架了。
-
Lambda上不支援Debug下中斷點,所以我們需要透過Log的方式來進行Debug,不過Log的服務卻在CloudWatch上,所以我們在執行Lambda時,必須給這個Function可以寫入CloudWatch Log的Role權限(如果忘了什麼是Role,請回來這篇文章)。
-
Lambda上支援的程式語法是有限的,目前Lambda上支援的程式語法是JAVA,C#,NodeJS,Python等,目前筆著試過利用JAVA與NodeJS的方式,上到Lambda去執行,不過為了考慮到將來部署的方便性,所以最後選擇了NodeJS來進來Lambda的開發(詳細的原因下次有機會會說明),所以這邊的範例也會選擇NodeJS。
-
Lambda在執行的環境是唯讀的,所以無法透過Disk I/O的方式寫入任何檔案至Lambda上。
瞭解幾個Lambda上的特性後,我們開始來使用Lambda吧。
首先是從AWS眾多的Service中,選出Lambda:
進入後,如果是第一次進入Lambda的網頁時,會被友善的導向「Create Function」的頁面,如下圖:
這邊大概說明一下內容,Lambda本身提供72種藍圖可供選擇,每個選擇進入後,會協助你綁定AWS上的服務(因為Lambda必須搭配AWS的服務),不過不管是那一種藍圖,都可以透過之後的設定來修改,所以我們這邊先選擇第一個藍圖:「Blank Function」。
進入後,可以看到上圖的頁面,這邊要決定好我們要透過那一種AWS的服務來Trigger Lambda,在這裡要決定好我們的功能為何,假設我們來做一個簡單的功能是:
使用者上傳檔案至S3時,會Trigger Lambda。
如果是這樣的功能的話,這一步,我們必須要選擇S3的服務。
選擇好S3的服務後,可以看到我們必須設定一些東西,我們一個一個來說明:
-
Bucket:S3的Bucket,如果忘了的話,請回去翻S3的功能。
-
Event type:這裡要決定,當s3收到什麼樣的動作後,必須觸發我們寫的Lambda程式。我們在這裡選擇「Object Created(All)」,也就是說當S3建立檔案時(使用者上傳檔案時),會觸發Lambda程式。
-
Prefix:前綴文字,這裡可以選定S3的資料夾,例如:當使用者上傳檔案到特定的資料夾時,才觸發Lambda程式;我們這邊跳過不設定。
-
Suffix:後綴文字,這裡可以指定上傳檔案的類型,根據檔案的副檔名來決定是否觸發Lambda程式;我們這邊跳過不設定。
-
Enable trigger:在建立這個Lambda時,需不需同時設定Trigger端服務;以本例來說,勾選這個設定,AWS會私下幫我們在S3那端的機器設定好Trigger。
所以設定完後的結果:
選擇Next後,會看到開始進入程式端的撰寫頁面,如下圖:
這邊一樣有一堆設定,讓我們來過一下這邊設定的意義吧:
-
Name:不用說,是這個Function的名稱,必須在Region裡是唯一。
-
Description:針對這個Function的描述。
-
Runtime:程式語言,開發者撰寫的Function,要用什麼樣的程式語言來執行,根據語言的不同,有不同的上Code方式。
-
Code entry type:
-
Inline:程式語言寫在網頁上,只支援NodeJS及pthyon二種語法。
-
Upload:上傳一個zip檔。
-
S3:將ZIP檔上傳至S3後,Lambda自動去抓取程式。
-
其中上方的紅框內容,是自己寫的,目的是要把event印出來;接著同一頁面的下方,把「Advanced settings」點開後,一樣有一堆設定,我們繼續來看:
-
Environment variables:設定這支程式執行時的環境變數。
-
Hanlder:這個是很重要的一個設定,這個設定決定你的程式進入點,所以如果這個錯誤的話,Lambda根本跑不起來。
-
Role:Lambda在執行程式時,必須指派一個Role給他,這個Role是自己要定義的,AWS建議這個Role必須有可以寫入CloudWatch Log的權限。
-
Memory:這個部份就是跟金額有關的部份了,還記得免費方案的400,000 GB-秒嗎?就是跟這個設定有關了;另外有一點要注意的是,Memory的大小會影響AWS選擇CPU機器的決定,愈小的Memory,執行的CPU等級就越差。筆者曾經有一段Code,執行時最大的記憶體用量是不到60MB,所以理論上用最小的128MB機器執行就夠了,不過在128MB的執行時間是12秒,但是在1024MB的機器上執行是2秒。
-
Timeout:還記得上方文章說過的嗎?Lambda的最大執行時間是300秒,超過300秒的話,會自動中斷程式;不過那是指最大的設定值,我們可以在這裡指定timeout的秒數,程式只要超過這個設定值的話,就會被中止,不需要等到300秒。
-
DLQ Resource:這部個份主要跟Lambda執行失敗時的錯誤流程有關,因為太深入了,這邊不做介紹。
-
VPC:某些AWS的服務一定要使用VPC(例如RDS服務),在這種情況下,如果我們的Lambda需要存取這些服務的話,就會將這個Lambda加入同一個VPC;簡單得說,就是放在同一個網段以方便存取就是了。
-
KMS Key:KMS是AWS的另一項服務,是用來加/解密的服務,直接選擇Defalut即可。
最後按下「Next」,進入下一頁。
有一個大略的資訊供我們確認,沒問題的話就來建立Function了。
Lambda的測試及執行
還有印象我們剛剛並沒有針對程式碼進行任何編輯,而是使用它的範例程式嗎?這個範例程式就是世界知名的「Hello World」程式,所以我們等會執行時,應該可以看到一段「Hello from Lambda」的文字被輸出...到底會在那裡被輸出呢?
首先我們一步一步慢慢來吧,先來介紹它網頁上的功能按鈕:
-
Qualifiers:因為Lambda本身可以做到版本控管,所以這個按鈕的功能主要就是控制Labmda執行的版本。
-
Test:第一次執行Test時,會跳出下方的視窗;這邊是讓我們訂義程式進入點的第一個參數event,它所包含的東西。
不過最常遇到的一種狀況是--如果是由AWS服務觸發的話,我們根本不知道它會帶入那些東西,例如這個Function預計是由S3來解發的,那麼它會有什麼東西在event裡面,我們根本不知道;AWS也很好心的,幫你解決了這個問題,透過紅框中的「Sample event template」,找到我們設定的AWS服務,AWS就會幫我們列出範本;以本程式為例,它會被S3觸發,所以我們選擇「S3 Put」的話,就可以看到下方的圖:
這串JSON,實際上就是在程式中的event參數的內容,假設我們想取得S3的bucket名稱,就可以透過event.Records[0].s3.bucket.name來取得sourcebucket這個值;完成後按下「Save and test」後,Lambda就會把我們設定好的JSON儲存,並呼叫Lambda程式。
呼叫完Lambda程式後,會有一些運行的數值及Log供我們參考,如下圖:
上方的紅框是執行的結果,我們的「Hello from Lambda」也是在這裡被輸出;而左下方的紅框,寫的是本次執行耗費的Memory,我們可以透過這個數值,決定我們需要的機器大小(別忘了也要考慮執行時間);右方的紅框則是Log輸出,可以在這裡看到我們印出的event內容。
這樣基本上,程式已經完成了,所以接下來,我們來實際確認,當我們放檔案到S3時,這支Lambda是否會被執行。
S3的Event與Lambda的Console輸出
還記得我們在一開始建立Lambda時,有勾選一個Trigger嗎?忘了的話看下圖:
勾選了這個方塊,它會幫我們在S3建立好一個叫Event的東西,可以在下圖的地方找到:
確認Event有作用的狀態後,我們上傳一個檔案到S3後,回到Lambda;當檔案上傳完成後,因為我們的程式是Log輸出,所以從表面上完全看不出來有沒有執行,所以我們接下來要去找出Log藏在那裡。按下圖操作:
Log藏在右上角的地方,進去Log後,找出我們想要的Log:
可以看到我們的程式有被正常的執行了。
結論
Lambda在AWS的Serverless服務中,是很重要的一環,因為它能夠運行我們客製化的程式;不過Serverless是最近這幾年的觀念中產生的,所以相對來說是較新穎的技術,可以說跟我們以前學的Web端程式有很大的差別,所以要從老舊的Web程式,跳到Serverless,一定會有一個陣痛期;不過,筆者建議大家,有機會還是要學一下,因為Serverless的概念上,是幫程式設計師處理掉不必要的系統處理,所以Serverless會負責與系統相關的部份,這些部份包括:
-
Load Balancer(分流)
-
Auto Scaling(自動成長)
-
被駭客攻擊的處理
前二點還有文件可以入門,但是第三點就很難了,尤其當我們使用了一些第三方套件而產生的問題,像是最近有點熱門的Strtus 2被攻擊事件,如果使用Serverless的概念來實作的話,Struts 2並不會存在於Serverless概念裡,也就不會因為這樣被攻擊;換句話說,Serverless可以大幅降低--因為不是我們的問題而產生的被攻擊事件,這一點,也是筆者很建議使用Serverless的原因。
看完這篇文章,或許會覺得Lambda很難應用,如果有這種想法的話,只能說是--因為對AWS瞭解不夠而產生的錯覺。Lambda的應用範圍很廣,包含我們之前在學校裡學會的Web端程式,都可以用Lambda取代表(不過整個設計概念要翻掉就是了),所以Lambda是很重要的。
留言列表