Serverless 架構模式及演進

作者 | 羅松(西流)

 Serverless 架構

按照 CNCF 對 Serverless 計算的定義,Serverless 架構應該是採用 FaaS(函數即服務)和 BaaS(後端服務)服務來解決問題的一種設計,這個定義讓我們對 Serverless 的理解稍微清楚了一些,但是可能也造成了一些爭論。

因此,Serverless 的界線是有些模糊,但是雲服務是在 Serverless 方向上不斷演進的。一個模糊的東西如何指導我們解決業務問題呢?Serverless 有一個最根本的理念是:讓用戶最大化的專注業務邏輯。其它的特徵如不關心服務器,自動彈性,按使用計費等等都是爲了實現這個理念而服務。Serverless 的理念可以讓我們更好地用有限的資源解決真正需要解決的問題,正是因爲我們少做了一些事情,轉而讓別人做這些事情,我們纔可以在業務上做的更多。

著名的 Serverless 實踐者 Ben Kehoe 這樣描述 Serverless 原生心智:

在實踐 Serverless 架構時,最重要的心智不是選擇哪些流行服務和技術,攻克哪些技術難題,而是時刻銘記在心專注業務邏輯,這樣更容易讓我們選擇合適的技術和服務,明確如何設計應用架構。

靜態站點

Serverless 架構從使用技術上有計算,數據存儲,消息通信,我們可從運維性,安全性,可靠性,可擴展性,成本幾個角度來衡量架構的優劣。本文會介紹一些常見的業務場景,探討如何使用 Serverless 架構來支持這些場景。爲了讓這種討論不過於抽象,下面會介紹一些具體的技術實現作爲參考,但是這些架構的思想是通用的,可以用其它類似產品實現。

靜態站點的業務需求是比較簡單的,它相當於一個信息展示的站點。比如早期網站都是靜態展示,如圖是 1997 年的中國黃頁,它其實就是一個單層的頁面。其特徵可以分爲三點:

1、它的頁面是偏靜態的展示信息。

2、其頁面更新並不頻繁。

3、不確定訪問量。

架構的演進

圖中所展示出的由雲下到雲上,由管理服務器到無需管理服務器(即 Serverless)的轉變給開發者帶來了巨大的受益。如前兩種方案需要預算,擴展,實現高可用,自行監控等,而當年中國黃頁開發者的業務邏輯只是想單純的展示信息,讓世界瞭解中國。正好與 Serverless 原生心智相吻合,即讓開發者最大化的去專注業務邏輯。

  1. 買臺服務器放在 IDC 機房裏託管,運行站點。

  2. 爲了解決高可用的問題又買了負載均衡服務和多個服務器。

  3. 採用靜態站點方式,站長直接將站點由對象存儲服務(如 OSS)支持,並使用 CDN 做緩存。

傳統架構模式下開發網站,會把網站部署在服務器上,隨後再把這個服務器託管到機房,然後用戶或者客戶端用電腦瀏覽器去訪問這個網站。它所存在弊端就是:如果這個網站出現問題,服務器不再可用,爲了維護這個網站的高可用性,會再掛一個負載均衡和兩個儲備服務器,這就是 Serverful 服務的架構。Serverless 架構對於開發人員來說,它只需要把它的靜態頁面直接發佈到對象存儲,而對象存儲本身就是一個 Serverless 的文件存儲服務,它可以存儲靜態頁頁面、圖片、音頻、視頻等等,並且做到無限擴展。

Serverless 架構有着其它方案無法比擬的優勢:

• 無需管理服務器,比如操作系統的安全補丁升級,故障升級,高可用性,這些雲服務(OSS,CDN)都幫着做了。

• 無需對資源做預估和考慮未來的擴展,因爲 OSS 本身是彈性的,使用 CDN 使得系統延遲更小,費用更低,可用性更高。

• 按實際使用的資源付費,包括存儲費用和請求費用,沒有請求時不收取請求費用。

• 安全性:這樣一個系統甚至看不到服務器,不需要通過 SSH 登錄,DDOS 攻擊也交給雲服務來解決。

靜態是個好東西,緩存也是軟件開發經常用到的技術,雖然有句玩笑是說計算機技術只有兩個最難的事情,讓緩存失效和命名。但是這也體現了緩存的重要性,只要運用得當,能大大提升系統的性能。

比如說目前很多安卓應用,要發佈到如小米應用商店、華爲應用商店等各種渠道商,開發者更希望的是打包好一個母包,放在對象存儲裏,而不是反覆做打渠道包維護等重複工作。對用戶來說,只需要維護一個母包,然後再維護一個簡單的動態計算即可。其實 CDN 不只可以回源到對象存儲,還可以回源到動態後端,如 API 網關,函數計算,負載均衡器等,也不止有 CDN 可以這種類型的緩存,還可以使用 Redis,以及進程內的緩存。

單體和微服務

爲何會有單體和微服務,因爲靜態站點的話,它可能只是解決一些展示信息的需求,但是隨着業務需求複雜程度增加,就需要動態站點了。比如:

靜態頁面和站點適合用於內容少更新頻率低的場景,反之,比如像圖中淘寶的一個商品詳情頁,使用靜態站點的頁面是不太現實的,原因有下:

1、商品是海量的。

2、更新頻繁

3、動態信息來源廣泛,如基本信息、價格、運費、銷量、庫存、評論等是實時變化的。

上面提到的 Serverless 原生心智有助於我們專注業務。比如:

  1. 是否需要自己購置服務器安裝數據庫,實現高可用,管理備份,升級版本等,還是可以把這些事情交給託管的服務如 RDS;是否可以使用表格存儲,Serverless HBase 等 Serverless 數據庫服務,實現按使用的彈性擴容縮容和付費。

  2. 單體應用是需要自己購置服務器運行,還是可以交給託管服務,如函數計算和 Serverless 應用引擎。

  3. 是否可以通過函數來實現輕量級微服務,依賴函數計算提供的負載均衡、自動伸縮、按需付費、系統監控等能力。

  4. 基於 Spring Cloud、Dubbo、HSF 等實現的微服務應用是否需要自己購置服務器部署應用,管理服務發現,負載均衡,彈性伸縮,熔斷,系統監控等,還是可以將這些工作交給諸如 Serverless 應用引擎服務。

關於架構的演進,經歷了 Serverful 單體架構到 Serverful 微服務架構再到 Serverless 微服務架構過程。隨着業務的發展,組織規模的不斷增大,這時候一般就需要將單體應用中的邏輯拆分成多個執行單元,比如商品頁面上的評論信息,售賣信息,配送信息等都可以對應一個單獨的微服務;而右圖的架構引入了 API 網關、函數計算或 SAE 來實現計算層,將大量工作交換雲服務完成。Serverless 這種微服務架構的好處是每個單元都能高度自治,單元之間松耦合,易於開發(比如使用不同技術)、部署和擴展。

但是這種架構也引入了分佈式系統的一些問題,如服務間通信的負載均衡,失敗處理,分佈式事務等。處在不同階段不同規模的組織可以選擇適合的方式,能解決它面臨的首要的業務問題。

其實這裏的商品頁面雖然信息繁多,但是相對來說依舊比較簡單,主要是因爲這裏只是涉及到了讀操作。這種圖顯示了系統內部多個微服務的交互。通過提供一個商品聚合服務,將內部的多個微服務統一的呈現給外部。這裏的微服務可以通過 SAE 或者函數實現。

另一個延伸是,我們開始的業務需求沒有提到需要支持不同客戶端的訪問,現實中這種需求是常見的,不同的客戶端需要的信息可能是不同的。比如手機可以根據位置信息做相關推薦。如何讓手機客戶端和不同瀏覽器都能受益於 Serverless 架構呢?

這又牽扯出了另一個詞,BFF,backend for fronted,即爲前端定做的後端,這受到了前端開發工程師的推崇,Serverless 技術讓這個架構廣泛流行,因爲前端工程師可以從業務角度出發直接編寫 BFF,而無需管理服務器相關的讓前端工程師更加頭疼的事情。

事件觸發

下面通過介紹一個具體的業務場景:對於事件觸發類的場景,闡述 Serverless 架構是怎樣解決問題的。前面提到的動態頁面生成是同步請求完成的,還有一類常見場景,其中請求處理通常需要較長時間或者較多資源,比如用戶評論中的圖片和視頻內容管理,涉及到如何上傳圖片和處理圖片(縮略圖,水印,審覈等),視頻處理以適應不同客戶端播放需求等。比如該圖中業務場景是一個買家秀,當買家完成了交易,想要發表圖片或者視頻的評論,買家完成後,後端的服務要對這個圖片加水印,然後縮放並且審覈;視頻也需要做多種格式的轉換和審覈,因爲要適配各種不同的終端。

這種業務特徵實際上是非常耗 CPU 的,每次任務執行的時間一般比較長,因此針對於這種業務,我們可能會有一些技術架構的演進。

比如大家所熟悉的抖音,就是用戶上傳視頻的業務場景。在抖音後端也是需要對視頻進行統一處理的:如加水印,轉碼成各種不同的碼率或者是長寬分辨率去配適不同的手機。這個業務落戶是十分消耗 CPU 計算資源的。同時帶寬的壓力也很大。這個時候你只能不停地加帶寬,加機器,其結果就是運維和維護成本不斷增加;第二個問題就是會存在波峯波谷,比如說早上 8 點鐘的地鐵時間和中午喫飯的 1 鍾或者晚上 8 點鐘的時候,業務量可能是非常高的,如果你的業務需要 1000 臺機器,但是到了凌晨,這 1000 臺機器可能就用不上,因此便會造成資源的一些浪費,同時你還要處理運維監控,擴彈性,擴縮容等工作。

將架構演進再延伸一下,事件觸發能力是 FaaS 非常重要的特性,這種 Pub-Sub 事件驅動模式不是一個新的概念,但是在 Serverless 流行之前,事件的生產者,消費者,以及中間的連接樞紐都是用戶負責的,就像前面架構演進中的第二個架構。Serverless 讓生產者發送事件,維護連接樞紐都從用戶職責中省略了,而只需關注消費者的邏輯,這是 Serverless 的價值。函數計算服務還集成其它雲服務事件源,讓你更方便的在業務中使用一些常見的模式,如 Pub/Sub,事件流模式,Event Sourcing 模式。

服務編排

前面的商品頁面雖然複雜,但是所有的操作都是讀操作,聚合服務 API 是無狀態、同步的。我們來看一下電商中的一個核心場景——訂單流程。

比如說用戶在淘寶裏面進行了購物,或者說在餓了麼下單了外賣,它都是涉及到一個訂單的流程。這種訂單流程是比商品展示更爲複雜的。因爲在訂單流程裏面,它所要保留更多的事情。比如有用戶下單時,我們第一步要檢查庫存,庫存儲量夠的話,然後庫存減 1 ,隨後接通支微信或者說支付寶的服務去支付扣款,單子下來了以後,還要安排物流去配送,同時還要查看物流的詳情並進行短信通知等等。

同時在這些代碼邏輯中你要寫各種重試邏輯。如果說最終失敗的話,我們便要對已完成的事情進行回滾,如若用戶取消訂單,那麼需要回滾的則更多。比如說這個錢要退還給用戶,這個場景是是非常複雜的,我們可以看一下這個流程怎麼發起來的。比如說第一步用戶下單之後,其實是走到了這個訂單服務,這個訂單服務會生成訂單號;然後會涉及到買家是誰,賣家是誰。第二步我們會把消息發送到消息總線,其他的這些服務(配送服務、庫存服務、支付服務)是訂閱到消息總線的。

另一方面它的可觀測性、可描述性並不好,其次在編排上,它的複用性很差。如若說開發者改成了另外一個流程的服務,那麼這一套就要重新改寫了。

在這個 Serverless 架構裏,各個服務直接是獨立的,也不通過事件傳遞信息,而是有一個集中的協調者服務來調度單個業務服務,業務邏輯和狀態由集中協調者維護。從網關層下單後,觸發函數計算的一次函數執行,函數執行的邏輯會觸發一個工作流的執行。就比如說右邊這張圖其實就是用戶自己去編寫的,這個流程,就是工作流。

比如說第一步下單,第二步付錢,付錢成功了會如何,付錢失敗了應該怎樣。整個訂單就相當於是右側流程的執行。而每次流程的執行都是可以被追溯的。你可以理解成他就是個組織者,然後調用其他的雲服務。

所以在這個架構,我們可以看出對開發者而言,不需要去做消息總線,從事邏輯的處理,維護數據的一致性等到。他只需要專注他的業務邏輯,把每個流程調用的服務寫好,把這些編排的流程寫好就可以了。

如果直接依賴於雲上的服務,比如阿里雲的 Serverless 工作流服務,這些事情都可以交給平臺來做。用戶又回到了只需關注業務邏輯的狀態。右圖是流程定義,我們可以看到這實現了前面基於事件的 Saga 模式的效果,並且流程的複雜度大大簡化。

Serverless 技術毫無疑問將會承擔更多的責任,讓用戶更快更好的構建應用。使用 Serverless 架構可以覆蓋很多場景,這裏只是介紹了 Web 網站前端後端,微服務,事件觸發,服務編排等幾個場景的架構。Less is more 把事情交給可靠的平臺(比如雲廠商)去做,讓開發者可以更加聚焦自身的核心業務價值,是 Serverless 所一直推崇的理念。

直播回放:

https://developer.aliyun.com/live/247330

西流

阿里雲智能雲原生函數計算技術專家

負責阿里雲函數計算產品功能開發(runtime 開發、事件源集成以及企業級 Serverless 解決方案落地等),目前專注在 Serverless 開發者工具鏈的建設,是雲原生 Serverless Dev Tools 研發負責人之一,主導了 S/FC 組件的開發工作。關注 Serverless 最新技術動態以及在企業級解決方案的落地,致力於推動 Serverless 在開發者羣體的流行

社區網址

Serverless Devs

社區官網

http://www.serverless-devs.com/

項目倉庫

https://github.com/Serverless-Devs/Serverless-Devs

Serverless Desktop 桌面客戶端

https://serverlessdevs.resume.net.cn/zh-cn/desktop/index.html

Serverless 應用開發者套件

http://serverless-dk.oss.devsapp.net/docs/tutorial-dk/intro/react

Serverless Devs CLI 

https://serverlessdevs.resume.net.cn/zh-cn/cli/index.html

Serverless Hub 應用中心

https://serverlesshub.resume.net.cn/#/hubs/special-view

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/ZuPYagEi17OHPuja7iMl0Q