close

  Lambda是AWS上的其中一種服務,它是Serverless概念的一種,所謂的Serverless,說得簡單一點,就是開發者著重在程式,而不需要費心去管理伺服器,例如:Linux的操作指令、佈署的環境安裝等相關作業,這一類的跟程式邏輯沒有太大關係的作業,Serverless就是要幫開發人員省掉這些功夫。雖說如此,因為Serverless是一種全新的概念,所以和當初學校所教授的課程,有很大的差異,這些差異包含:

  1. 程式的佈署:

早期的網頁程式是整個包成一包,而將我們寫好的這一包程式,放在網頁上後去執行;但Serverless的情況不是,Serverless的狀況,最小的單位稱為Function,每一個Function,負責一段商業邏輯。舉個例子,假設我們的網站有100個功能,早期會將這100個功能包成一包,放到一台伺服器上,但Serverless的情況變成,我們要分別將100個功能,分成100包檔案,佈署到100個Lambda Server上。

  1. Session的處理:

因為早期程式都在同一台Server上,所以Session的處理會交由Web Container(例如:tomcat)來負責;但變為Serverless的架構後,因為Function佈署在不同的機器上,所以並沒有Session的機制,如果真的需要Session的機制的話,只能想辧法自行作出Session機制。

  1. 程式的運行時間:

因為Serverless的金額計算,是以程式執行的時間來計算,換句話說,程式如果沒有執行的話,是不用算錢的。而為了防止程式進入無窮迴圈的狀態下,系統會有一個預設的運行時間(Lambda最大運行時間為300秒,每個Function需要個別設定),如果程式執行時間超過設定時間,Lambda服務會自動中斷整個程式的運行,這點是在設計Serverless時必須要特別考慮的問題。

這幾點是我們在早期的程式設計與Serverless設計的很大差異。

Lambda的費用與免費額度

  Lambda計算方式,其實跟EC2差不多,Lambda的金額計算是以先選擇執行機器的大小(Memory)後,再根據執行的時間,並加上呼叫的次數、資料的傳輸量來計費。簡單地說,就是:

  1. Memory的大小配合程式執行時間

  2. 呼叫次數

  3. 資料傳輸量

關於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的幾樣特性:

  1. Lambda是被動式的呼叫,而且它並不支援外部網址;Lambda只支援AWS服務本身來呼叫;換句話說,Lambda必須搭配某個AWS的服務,所以當我們決定使用Lambda,我們要有知覺,我們已經被AWS綁架了

  2. Lambda上不支援Debug下中斷點,所以我們需要透過Log的方式來進行Debug,不過Log的服務卻在CloudWatch上,所以我們在執行Lambda時,必須給這個Function可以寫入CloudWatch Log的Role權限(如果忘了什麼是Role,請回來這篇文章)。

  3. Lambda上支援的程式語法是有限的,目前Lambda上支援的程式語法是JAVA,C#,NodeJS,Python等,目前筆著試過利用JAVA與NodeJS的方式,上到Lambda去執行,不過為了考慮到將來部署的方便性,所以最後選擇了NodeJS來進來Lambda的開發(詳細的原因下次有機會會說明),所以這邊的範例也會選擇NodeJS。

  4. 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會負責與系統相關的部份,這些部份包括:

  1. Load Balancer(分流)

  2. Auto Scaling(自動成長)

  3. 被駭客攻擊的處理

前二點還有文件可以入門,但是第三點就很難了,尤其當我們使用了一些第三方套件而產生的問題,像是最近有點熱門的Strtus 2被攻擊事件,如果使用Serverless的概念來實作的話,Struts 2並不會存在於Serverless概念裡,也就不會因為這樣被攻擊;換句話說,Serverless可以大幅降低--因為不是我們的問題而產生的被攻擊事件,這一點,也是筆者很建議使用Serverless的原因。

  看完這篇文章,或許會覺得Lambda很難應用,如果有這種想法的話,只能說是--因為對AWS瞭解不夠而產生的錯覺。Lambda的應用範圍很廣,包含我們之前在學校裡學會的Web端程式,都可以用Lambda取代表(不過整個設計概念要翻掉就是了),所以Lambda是很重要的。

arrow
arrow

    JAVA Programmer 發表在 痞客邦 留言(2) 人氣()