本文對serverless架構(gòu)的基礎(chǔ)概念,工作原理,應(yīng)用場景以及具體產(chǎn)品進(jìn)行詳細(xì)解析。
基礎(chǔ)概念
serverless:無服務(wù)器架構(gòu),即在無需管理服務(wù)器等底層資源的情況下完成應(yīng)用的開發(fā)和運行,是云原生架構(gòu)的核心組成部分。
通俗來說,如果將購買一臺物理服務(wù)器比作 買車 ,購買云服務(wù)器就類似于 租車 (租賃期間需要駕駛和維護(hù),且即使閑置也需付費),那么serverless則類似于 出租車 (只需乘坐,按里程計費)。
從技術(shù)層面來說,我們可以簡單理解為: serverless = FaaS + BaaS 。一個完整的serverless應(yīng)用一般由FaaS層負(fù)責(zé)無狀態(tài)的計算,由BaaS層負(fù)責(zé)狀態(tài)的存儲:
- FaaS(函數(shù)即服務(wù),F(xiàn)unction as a Service):將函數(shù)代碼托管給云產(chǎn)商,以服務(wù)形式運行,支持事件觸發(fā)。代表產(chǎn)品有騰訊云SCF、AWS Lambda等。
- BaaS(后端即服務(wù),Backend as a Service):指云平臺提供的后端組件整合,開發(fā)者無需開發(fā)和維護(hù)后端服務(wù),通過API/SDK的調(diào)用便可獲得例如數(shù)據(jù)存儲(對象存儲、云數(shù)據(jù)庫、云中間件等)、消息推送、賬號管理、地圖定位、AI、IoT等能力。

特點及優(yōu)勢:
- 免運維 :無需管理基礎(chǔ)設(shè)施 —> 可以專注業(yè)務(wù)開發(fā)
- 按量計費 :閑時不計費 —> 降低成本
- 彈性伸縮 :峰時自動擴容 —> 無需考慮可用性問題
劣勢及適用場景:
- 冷啟動延遲: 一定時間內(nèi)的首次調(diào)用可能需要冷啟動(如進(jìn)行加載代碼、拉起容器等任務(wù))—> 適合對響應(yīng)速度要求不是太高的接口,更適合異步任務(wù),不適合啟動耗時久的JAVA項目
- 開發(fā)和管理設(shè)施: serverless應(yīng)用的調(diào)試、測試、排障、發(fā)布等設(shè)施暫不成熟 —> 目前更適合后端邏輯不太復(fù)雜的輕量級應(yīng)用
- 云產(chǎn)商綁定: 不同云產(chǎn)商提供的組件(如存儲)接口不同,可能增加未來遷移成本 —> 使用標(biāo)準(zhǔn)化框架,并在設(shè)計時盡量隔離通用邏輯層和BaaS依賴層
工作原理
各個平臺對云函數(shù)的實現(xiàn)在原理上基本相似,核心都是動態(tài)的啟動實例去執(zhí)行函數(shù)代碼,且完成后實例會保留一定時間窗口。大致的底層架構(gòu)如下圖,其中步驟(1) (2) (3) (4) 為冷啟動調(diào)用流程,(5) 為非冷啟動調(diào)用。

1.函數(shù)注冊
用戶在控制臺(或命令行)提交函數(shù)代碼到云平臺,并進(jìn)行函數(shù)配置。代碼一般會被作為靜態(tài)資源保存(如對象存儲),而函數(shù)的元信息會被存入數(shù)據(jù)庫中(如MySQL)。
2.函數(shù)觸發(fā)
云函數(shù)的觸發(fā)可以分為同步和異步兩種情況:
- 如果是同步請求則等待函數(shù)執(zhí)行結(jié)果后返回
- 如果是異步請求則可以投遞到隊列后直接返回
3.函數(shù)執(zhí)行
云函數(shù)的執(zhí)行可以分為窗口內(nèi)首次執(zhí)行(冷啟動)和非首次執(zhí)行兩種情況:
- 如果是首次執(zhí)行,則需要進(jìn)行宿主機調(diào)度,在宿主機拉起容器實例,下載函數(shù)代碼,然后執(zhí)行代碼。
- 首次執(zhí)行完畢后Docker容器不會立即關(guān)閉,會等待一定時間周期,如果此時有新的請求進(jìn)來,會被分配到該容器,直接運行代碼。
從執(zhí)行的原理也可看出,云函數(shù)理論上是支持無限自動擴容的。
冷啟動問題
由于serverless按量計費的特點,其實現(xiàn)機制就必須要在函數(shù)調(diào)用時才去啟動運行環(huán)境,也就是冷啟動問題。雖然保留一定時間可以讓后續(xù)的請求無需加載,但如果在極短時間內(nèi)并發(fā)大量請求,還是會同時啟動多個容器,影響首個請求的響應(yīng)時間。前面也說到,云函數(shù)的特性和機制決定了它的應(yīng)用場景,對于同時要求高并發(fā)、低時延的場景并不是特別適合。
對于冷啟動問題,下面以騰訊云的 云函數(shù)SCF 為例進(jìn)行驗證。使用Postman的批量測試功能(Collection Runner)對云上部署的一個hello world函數(shù)進(jìn)行串行測試。

從圖中可以看出,一段時間內(nèi)的首次請求耗時會比其他請求的耗時高出一個數(shù)量級。
冷啟動優(yōu)化
冷啟動的優(yōu)化主要針對同步的請求,首先分析下冷啟動耗時的組成,主要是容器的拉起和代碼的下載(當(dāng)然也有資源調(diào)度和網(wǎng)絡(luò)配置等,這里暫不討論)。
1. 代碼緩存 :可以設(shè)計多級緩存,比如在宿主機上進(jìn)行代碼包緩存,以及在可用區(qū)(AZ)內(nèi)部進(jìn)行緩存,這樣后續(xù)的首次啟動就可以快速就近獲取,而無需再次從對象存儲下載。
2. 容器預(yù)創(chuàng)建 :一個優(yōu)化思路就是預(yù)加載,也就是預(yù)測將會到來的請求,提前拉起容器實例,從而減少耗時。有以下幾種可能的方案:
- 進(jìn)行請求量的 實時計算 ,如果請求呈上升趨勢,就開始預(yù)創(chuàng)建容器實例,同理下降則進(jìn)行回收。
- 云函數(shù)調(diào)用鏈: 這是一種可確定的預(yù)測,當(dāng)云函數(shù)之間出現(xiàn)互相調(diào)用,在前面的函數(shù)被觸發(fā)時就可以同時預(yù)創(chuàng)建調(diào)用鏈后面的實例;
- 版本更新: 如果函數(shù)版本進(jìn)行更新,則之后的所有請求都會重新冷啟動,為了避免這種情況,需要預(yù)創(chuàng)建一些實例并下載新版本代碼,之后才能將流量平滑遷移到新版本函數(shù)。
應(yīng)用場景
下面介紹比較適合使用serverless技術(shù)的幾種場景。
1.rest API
利用云函數(shù)可以快速部署一個rest API應(yīng)用,目前的云廠商基本都支持大部分node,Python和php的web框架,如koa、Express.js、Next.js、Flask、Django、Laravel等等。
這種web架構(gòu)是前后端分離,即云函數(shù)中的后臺接口只提供數(shù)據(jù),頁面的渲染在瀏覽器進(jìn)行。可以將前端的代碼部署到對象存儲中,并使用相關(guān)云數(shù)據(jù)庫作為數(shù)據(jù)存儲,這就成為一個完整的云上Full Stack應(yīng)用。
2.SSR
SSR(Server-Side Rendering):后端渲染,即頁面直接在后臺進(jìn)行渲染,瀏覽器只負(fù)責(zé)顯示。這種比較傳統(tǒng)的web架構(gòu)很適合應(yīng)用于serverless,只需將整個后端代碼部署到云函數(shù)即可,好處有:1.利于seo,2.降低系統(tǒng)復(fù)雜度,易于部署。
serverless很適合用于流量分布不均的輕量應(yīng)用,比如一些活動頁面,可能一個周期內(nèi)只有很短的一段時間會有大量訪問,且需要長期的維護(hù),此時為這個應(yīng)用去購買高配置的服務(wù)器顯然是不劃算的。使用serverless之后則可以完全解決這個問題,按量計費降低了成本,既免去了長期運維又不需要擔(dān)心擴容問題。
3.任務(wù)執(zhí)行
云函數(shù)本身是無狀態(tài)的,所以天然適合無狀態(tài)任務(wù),如果需要狀態(tài)存儲則需要借助BaaS層的組件。云函數(shù)的優(yōu)勢是可以與云提供商下的其他服務(wù)(比如數(shù)據(jù)庫、緩存、對象存儲、CDN、AI、轉(zhuǎn)碼等)打通,在函數(shù)中使用SDK連接各個組件(但這同樣意味著將在云產(chǎn)商綁定的道路上越走越遠(yuǎn))。以下是一些適用場景:
- 消息通知:比如觸發(fā)后向某個用戶發(fā)送郵件、短信等。
- 定時任務(wù):云函數(shù)一般提供定時器觸發(fā),方便進(jìn)行定時任務(wù)的執(zhí)行。
- CDN自動刷新:一般來說會把圖片、網(wǎng)頁等靜態(tài)資源存到對象存儲,并且配置CDN加速,一旦資源發(fā)生修改還得手動進(jìn)行CDN刷新預(yù)熱。可以使用對象存儲上傳的事件觸發(fā)器,在云函數(shù)中調(diào)用CDN接口自動化刷新預(yù)熱。
- 視頻轉(zhuǎn)碼:如果云產(chǎn)商提供轉(zhuǎn)碼服務(wù),可以借助云函數(shù)很方便的完成轉(zhuǎn)碼任務(wù)。如原視頻上傳到對象存儲后,該事件可以觸發(fā)云函數(shù)調(diào)用轉(zhuǎn)碼服務(wù),并將轉(zhuǎn)碼后的視頻發(fā)布到對象存儲中,如果使用了CDN還可以進(jìn)行緩存刷新。
- AI服務(wù):可以使用云函數(shù)調(diào)用該產(chǎn)生的AI服務(wù),比如調(diào)用OCR接口識別圖片文字內(nèi)容后返回。
- Devops:例如將Github的webhook設(shè)置為云函數(shù)的地址,當(dāng)代碼提交后觸發(fā)云函數(shù),執(zhí)行CI/CD任務(wù),構(gòu)建后發(fā)布產(chǎn)物到云服務(wù)器上。