Serverless無伺服器架構詳解
阿新 • • 發佈:2020-08-04
> 本文對Serverless架構的基礎概念、具體產品、應用場景、工作原理進行詳細解析。
## 基礎概念
**Serverless:** 無伺服器架構,即在無需管理伺服器等底層資源的情況下完成應用的開發和執行,是雲原生架構的核心組成部分。
通俗來說,如果將購買一臺物理伺服器比作**買車**,購買雲伺服器就類似於**租車**(租賃期間需要駕駛和維護,且即使閒置也需付費),那麼Serverless則類似於**計程車**(只需乘坐,按里程計費)。
從技術層面來說,我們可以簡單理解為:**Serverless = FaaS + BaaS**。一個完整的Serverless應用一般由FaaS層的雲函式負責無狀態的計算,由BaaS層元件負責狀態的維護:
- FaaS(函式即服務,Function as a Service):將函式程式碼託管給雲產商,以服務形式執行,支援事件觸發。代表產品有騰訊雲SCF、AWS Lambda等。
- BaaS(後端即服務,Backend as a Service):指雲平臺提供的後端元件整合,開發者無需開發和維護後端服務,通過API/SDK的呼叫便可獲得例如資料儲存(物件儲存、雲資料庫、雲中間件等)、訊息推送、賬號管理、地圖定位、AI、IoT等能力。
![Serverless組成](https://blog.cos.zhayujie.com/cloud/serverless-arch.png)
**特點及優勢:**
1. **免運維**:無需管理基礎設施 —> 可以專注業務開發
2. **按量計費**:閒時不計費 —> 降低成本
3. **彈性伸縮**:峰時自動擴容 —> 無需考慮可用性問題
**劣勢及適用場景:**
1. **冷啟動延遲:** 一定時間內的首次呼叫可能需要冷啟動(如進行載入程式碼、拉起容器等任務)—> 適合對響應速度要求不是太高的介面,更適合非同步任務,不適合啟動耗時久的Java專案
2. **開發和管理設施:** Serverless應用的除錯、測試、排障、釋出等設施暫不成熟 —> 目前更適合後端邏輯不太複雜的輕量級應用
3. **雲產商繫結:** 不同雲產商提供的元件(如儲存)介面不同,可能增加未來遷移成本 —> 使用標準化框架,並在設計時儘量隔離通用邏輯層和BaaS依賴層
## 工作原理
雲函式之所以能做到按量計費和彈性擴容,與其實現機制是分不開的。核心原理是在函式被呼叫時才動態的啟動容器例項去執行,容器的生命週期很短,執行完後一定時間就會被回收,所以沒有呼叫時是不消耗任何資源的。而面對同一時間的並行呼叫,會啟動多個例項來完成執行,這也實現了單個請求級別的彈性擴容,且理論上是可以無限擴容的。
由於容器啟動本身需要耗時,所以一般的實現會在例項執行完之後保留一定時間視窗。大致的工作流程如下圖,其中步驟(1) (2) (3) (4) 為冷啟動呼叫流程,(5) 為非冷啟動呼叫。
![工作原理](https://blog.cos.zhayujie.com/cloud/scf-work-principle.png)
**1.函式註冊**
使用者在控制檯(或命令列)提交函式程式碼到雲平臺,並進行函式配置。程式碼一般會被作為靜態資源儲存(如物件儲存),而函式的元資訊會被存入資料庫中(如mysql)。
**2.函式觸發**
雲函式的觸發可以分為同步和非同步兩種情況:
+ 如果是同步請求則等待函式執行結果後返回
+ 如果是非同步請求則可以投遞到佇列後直接返回
**3.函式執行**
雲函式的執行可以分為冷啟動和非冷啟動兩種情況:
+ 如果沒有可用的例項資源則進入冷啟動流程,需要進行宿主機排程,在宿主機拉起容器例項,下載函式程式碼,然後執行程式碼。
+ 首次執行完畢後docker容器不會立即關閉,會等待一定時間週期,如果此時有新的請求進來,會被分配到該容器,直接執行程式碼。
**冷啟動問題**
前面說到雲函式的實現機制必須要在函式呼叫時才去啟動執行環境,需要面臨冷啟動問題。雖然保留一定時間可以讓後續的請求無需載入,但如果在極短時間內併發大量請求,還是會同時啟動多個容器,影響首個請求的響應時間。前面也說到,雲函式的特性和機制決定了它的應用場景,對於同時要求高併發、低時延的場景並不是特別適合。
對於冷啟動問題,下面以騰訊雲的[雲函式SCF](https://cloud.tencent.com/product/scf)為例進行驗證。使用Postman的批量測試功能(Collection Runner)對雲上部署的一個Hello World函式進行序列測試。
![SCF測試](https://blog.cos.zhayujie.com/cloud/scf-iter-test.png)
從圖中可以看出,一段時間內的首次請求耗時會比其他請求的耗時高出一個數量級。
**冷啟動優化**
冷啟動的優化主要針對同步的請求,首先分析下冷啟動耗時的組成,主要是容器的拉起和程式碼的下載(當然也有資源排程和網路配置等,這裡暫不討論)。
1.**程式碼快取**:可以設計多級快取,比如在宿主機上進行程式碼包快取,以及在可用區(AZ)內部進行快取,這樣後續的首次啟動就可以快速就近獲取,而無需再次從物件儲存下載。
2.**容器預建立**:一個優化思路就是預載入,也就是預測將會到來的請求,提前拉起容器例項,從而減少耗時。有以下幾種可能的方案:
+ 進行請求量的**實時計算**,如果請求呈上升趨勢,就開始預建立容器例項,同理下降則進行回收。
+ **雲函式呼叫鏈:** 這是一種可確定的預測,當雲函式之間出現互相呼叫,在前面的函式被觸發時就可以同時預建立呼叫鏈後面的例項;
+ **版本更新:** 如果函式版本進行更新,則之後的所有請求都會重新冷啟動,為了避免這種情況,需要預建立一些例項並下載新版本程式碼,之後才能將流量平滑遷移到新版本函式。
## 應用場景
**1.Rest API**
利用雲函式可以快速部署一個Rest API應用,目前的雲廠商基本都支援大部分node,python和php的web框架,如koa、Express.js、Next.js、Flask、Django、Laravel等等。
這種web架構是前後端分離,即雲函式中的後臺介面只提供資料,頁面的渲染在瀏覽器進行。可以將前端的程式碼部署到物件儲存中,並使用相關雲資料庫作為資料儲存,這就成為一個完整的雲上Full Stack應用。
**2.SSR**
SSR(Server-Side Rendering):後端渲染,即頁面直接在後臺進行渲染,瀏覽器只負責顯示。這種比較傳統的web架構很適合應用於Serverless,只需將整個後端程式碼部署到雲函式即可,好處有:1.利於SEO,2.降低系統複雜度,易於部署。
Serverless很適合用於流量分佈不均的輕量應用,比如一些活動頁面,可能一個週期內只有很短的一段時間會有大量訪問,且需要長期的維護,此時為這個應用去購買高配置的伺服器顯然是不划算的。使用Serverless之後則可以完全解決這個問題,按量計費降低了成本,既免去了長期運維又不需要擔心擴容問題。
**3.任務執行**
雲函式本身是無狀態的,所以天然適合無狀態任務,如果需要狀態儲存則需要藉助BaaS層的元件。雲函式的優勢是可以與雲提供商下的其他服務(比如資料庫、快取、物件儲存、CDN、AI、轉碼等)打通,在函式中使用SDK連線各個元件(但這同樣意味著將在雲產商繫結的道路上越走越遠)。以下是一些適用場景:
- 訊息通知:比如觸發後向某個使用者傳送郵件、簡訊等。
- 定時任務:雲函式一般提供定時器觸發,方便進行定時任務的執行。
- CDN自動重新整理:一般來說會把圖片、網頁等靜態資源存到物件儲存,並且配置CDN加速,一旦資源發生修改還得手動進行CDN重新整理預熱。可以使用物件儲存上傳的事件觸發器,在雲函式中呼叫CDN介面自動化重新整理預熱。
- 視訊轉碼:如果雲產商提供轉碼服務,可以藉助雲函式很方便的完成轉碼任務。如原視訊上傳到物件儲存後,該事件可以觸發雲函式呼叫轉碼服務,並將轉碼後的視訊釋出到物件儲存中,如果使用了CDN還可以進行快取重新整理。
- AI服務:可以使用雲函式呼叫該產生的AI服務,比如呼叫OCR介面識別圖片文字內容後返回。
- Devops:例如將Github的webhook設定為雲函式的地址,當代碼提交後觸發雲函式,執行CI/CD任務,構建後釋出產物到雲伺服器上。
## 具體產品
下面以[騰訊雲](https://cloud.tencent.com/)上的Serverless產品為例介紹具體的使用實踐。
**SCF雲函式**
[SCF (Serveless Cloud Function)](https://cloud.tencent.com/product/scf)是騰訊雲Serverless的核心產品,部署一個可以從公網訪問的雲函式只需簡單兩步:
1.函式編寫:可以直接在控制檯上的編輯器中編寫函式程式碼,下圖就是一個Hello World雲函式:
![雲函式編寫](https://blog.cos.zhayujie.com/cloud/scf-helloword-sample.png)
2.建立觸發器:如果想通過瀏覽器進行函式呼叫,則建立一個API閘道器觸發器,會分配一個公網地址供訪問。API閘道器還支援繫結自定義域名,可實現通過 "{自定義域名}/{函式名}" 的方式訪問雲函式