共計(jì) 9962 個(gè)字符,預(yù)計(jì)需要花費(fèi) 25 分鐘才能閱讀完成。
這篇文章主要介紹“Serverless 的相關(guān)知識(shí)點(diǎn)有哪些”的相關(guān)知識(shí),丸趣 TV 小編通過實(shí)際案例向大家展示操作過程,操作方法簡單快捷,實(shí)用性強(qiáng),希望這篇“Serverless 的相關(guān)知識(shí)點(diǎn)有哪些”文章能幫助大家解決問題。
Serverfull 到 Serverless 的演變
上圖是 MVC 架構(gòu)的 Web 應(yīng)用部署之后的典型情況。上圖中的整個(gè)藍(lán)色部分就是服務(wù)端的邊界,它是負(fù)責(zé)應(yīng)用或代碼的線上運(yùn)維。而 Serverless 要解決的問題的邊界就是服務(wù)端的邊界,也就是服務(wù)端運(yùn)維。
那么下面我們先來看一下服務(wù)端運(yùn)維的發(fā)展史,也就是從一開始到 Serverless 的發(fā)展史。假設(shè)有一個(gè) Web 應(yīng)用,這個(gè) Web 應(yīng)用的研發(fā)涉及到兩個(gè)角色:研發(fā)工程師和運(yùn)維工程師。研發(fā)工程師只關(guān)心應(yīng)用的業(yè)務(wù)邏輯。具體來說就是,整個(gè) MVC 架構(gòu) Web 應(yīng)用的開發(fā)都?xì)w他負(fù)責(zé),也就是從服務(wù)端界面 View 層,到業(yè)務(wù)邏輯 Control 層,再到數(shù)據(jù)存儲(chǔ) Model 層,整個(gè) Web 應(yīng)用的版本管理和線上 bug 修復(fù)都?xì)w研發(fā)工程師。運(yùn)維工程師則只關(guān)心應(yīng)用的服務(wù)端運(yùn)維事務(wù)。他負(fù)責(zé)部署上線小程的 Web 應(yīng)用,綁定域名以及日志監(jiān)控。在用戶訪問量大的時(shí)候,他要給這個(gè)應(yīng)用擴(kuò)容; 在用戶訪問量小的時(shí)候,他要給這個(gè)應(yīng)用縮容; 在服務(wù)器掛了的時(shí)候,他還要重啟或者換一臺(tái)服務(wù)器。
Serverfull 時(shí)代。最開始的時(shí)候,研發(fā)工程師不用關(guān)心任何部署相關(guān)的事情。研發(fā)工程師每次發(fā)布新的應(yīng)用后,運(yùn)維工程師都負(fù)責(zé)部署上線最新的代碼。運(yùn)維工程師需要管理好迭代版本的發(fā)布,分支合并,將應(yīng)用上線,遇到問題回滾。如果線上出了故障,還需要抓取日志發(fā)給研發(fā)工程師。
Serverfull 時(shí)代將研發(fā)和運(yùn)維完全隔離開來了。這種完全隔離開來的好處很明顯:研發(fā)工程可以專心做好自己的業(yè)務(wù),但是運(yùn)維工程師就成了工具人了,就困在大量的運(yùn)維工作中,處理大量瑣碎的雜事。
DevOps 時(shí)代。運(yùn)維工程師發(fā)現(xiàn)有很多事情都是重復(fù)性的工作,線上出故障了還得自己抓日志發(fā)給研發(fā)工程師,效率很低。因此運(yùn)維工程師就開發(fā)了一套運(yùn)維控制臺(tái),將部署上線和日志抓取的工作讓研發(fā)工程師處理。
這樣,運(yùn)維工程師可以稍微輕松點(diǎn)了,但是優(yōu)化架構(gòu)和擴(kuò)縮容資源方案還是得負(fù)責(zé)。而研發(fā)工程師除了開發(fā)的任務(wù),還要自己通過運(yùn)維控制臺(tái)發(fā)布新版本和解決線上故障。這個(gè)時(shí)候是研發(fā)兼運(yùn)維 DevOps,研發(fā)工程師兼任了部分運(yùn)維工程師的工作,但是這部分的工作就應(yīng)該是研發(fā)工程負(fù)責(zé)的(比如版本控制、線上故障等),而且運(yùn)維工程師將這部分工作工具化了,更加高效了,有 less 的趨勢了。
工業(yè)時(shí)代。運(yùn)維工程師又基于研發(fā)工程師的開發(fā)流程,將運(yùn)維控制臺(tái)進(jìn)一步提升,可以實(shí)現(xiàn)代碼自動(dòng)發(fā)布:代碼掃描 - 測試 - 灰度驗(yàn)證 - 上線。這樣一來,研發(fā)工程師只需要將最新的代碼合并到 Git 倉庫指定的 develop 分支,剩下的就由代碼自動(dòng)發(fā)布的流水線來負(fù)責(zé)了。這個(gè)時(shí)候研發(fā)工程師也不需要運(yùn)維了,免運(yùn)維 NoOps,研發(fā)工程師也就回到了當(dāng)初,只需要關(guān)心自己的應(yīng)用業(yè)務(wù)就可以了。
同時(shí),運(yùn)維工程師發(fā)現(xiàn)資源優(yōu)化和擴(kuò)縮容方案也可以利用性能監(jiān)控 + 流量估算解決。這樣運(yùn)維工程師的運(yùn)維工作也全都自動(dòng)化了。那么對于研發(fā)工程師來說,運(yùn)維工程師的存在感越來越弱,需要運(yùn)維工程師干的事情越來越少,都由自動(dòng)化工具替代了。這就是 Serverless。
未來。實(shí)現(xiàn)了免運(yùn)維之后,運(yùn)維工程師要轉(zhuǎn)型去做更底層的服務(wù),做基礎(chǔ)架構(gòu)的建設(shè),提供更加智能、更加節(jié)省資源、更加周到的服務(wù)。而研發(fā)工程師可以完全不被運(yùn)維的事情困擾,專注做好自己的業(yè)務(wù),提升用戶體驗(yàn),思考業(yè)務(wù)價(jià)值。
免運(yùn)維 NoOps 并不是說服務(wù)端運(yùn)維就不存在了,而是通過全知全能的服務(wù),覆蓋研發(fā)部署需要的所有需求,讓研發(fā)工程師對它的感知越來越少。另外,NoOps 是理想狀態(tài),因?yàn)槲覀冎荒軣o限逼近 NoOps,所以說是 less,而不是 ServerZero。
Serverless 的 Server 限定了 Serverless 解決問題的邊界,即服務(wù)端運(yùn)維;less 說明了 Serverless 解決問題的目的,即免運(yùn)維 NoOps。所以,Serverless 應(yīng)該叫做服務(wù)端免運(yùn)維,這也就是 Serverless 要解決的問題。
什么是 Serverless
Serverless 要解決的就是將運(yùn)維工程師的工作徹底透明化; 而研發(fā)工程師只關(guān)心業(yè)務(wù)邏輯,不用關(guān)心部署運(yùn)維和上線的各種問題。而要實(shí)現(xiàn)這種狀態(tài),那么就意味要對整個(gè)互聯(lián)網(wǎng)服務(wù)端的運(yùn)維工作進(jìn)行極端抽象。而越抽象的東西,由于蘊(yùn)含的信息量越大,所以越難定義。
但是,總的來說 Serverless 的含義有這兩種:
狹義 Serverless(最常見)是指 Serverless computing 架構(gòu) = FaaS 架構(gòu) = Trigger(事件驅(qū)動(dòng))+FaaS(Function as a Service,函數(shù)即服務(wù))+BaaS(Backend as a Service,后端即服務(wù),持久化或第三方服務(wù))=FaaS + BaaS。
廣義 Serverless 是指服務(wù)端免運(yùn)維,也就是具有 Serverless 特性的云服務(wù)。
狹義的 Serverless
我們?nèi)粘9ぷ魈岬降?Serverless 都是指狹義的 Serverless。
而這主要是因?yàn)闅v史原因,2014 年 11 月份,亞馬遜推出了真正意義上的第一款 Serverless FaaS 服務(wù):Lambda。從此,Serverless 的概念才進(jìn)入大多數(shù)人的視野,因此 Serverless 曾經(jīng)一度就等于 FaaS。FaaS,函數(shù)即服務(wù),它還有個(gè)名稱叫作 Serverless Computing,它可以讓我們隨時(shí)隨地創(chuàng)建、使用、銷毀一個(gè)函數(shù)。
通常函數(shù)的使用過程:需要先從代碼加載到內(nèi)存,也就是實(shí)例化,然后被其他函數(shù)調(diào)用時(shí)執(zhí)行。FaaS 中也是一樣的,函數(shù)也需要實(shí)例化,然后被觸發(fā)器 Trigger 調(diào)用。這兩個(gè)最大的區(qū)別就是在 Runtime,也就是函數(shù)的上下文。FaaS 的 Runtime 是預(yù)先設(shè)置好的,都是云服務(wù)商提供的,我們可以使用但是無法控制。并且 FaaS 的 Runtime 是臨時(shí)的,當(dāng) FaaS 的函數(shù)調(diào)用完之后,云服務(wù)商就會(huì)銷毀這個(gè)實(shí)力,回收資源,也就意味著這個(gè)臨時(shí)的 Runtime 會(huì)和函數(shù)一起銷毀。因此,F(xiàn)aaS 推薦無狀態(tài)的函數(shù),也就是一個(gè)函數(shù)只要參數(shù)固定,那么返回的結(jié)果也必須是固定的。
那么將一開始的 MVC 架構(gòu)的 Web 應(yīng)用變成 Serverless 的話,那應(yīng)該是怎樣的呢?View 層是客戶端展示的內(nèi)容,通常并不需要函數(shù)算力;Control 層,就是函數(shù)的典型使用場景。在 MVC 架構(gòu)中,一個(gè) HTTP 的數(shù)據(jù)請求往往對應(yīng)著一個(gè) Control 函數(shù),因此這個(gè) Control 函數(shù)完全可以被 FaaS 函數(shù)代替。在 HTTP 的數(shù)據(jù)請求量大的時(shí)候,F(xiàn)aaS 函數(shù)會(huì)自動(dòng)擴(kuò)容多實(shí)例同時(shí)運(yùn)行; 在 HTTP 的數(shù)據(jù)請求量小的時(shí)候,又會(huì)自動(dòng)縮容; 當(dāng)沒有 HTTP 請求的時(shí)候,還會(huì)縮容至 0 實(shí)例。如下圖所示:
Control 函數(shù)變成了無狀態(tài)的,并且函數(shù)的實(shí)例在不停地?cái)U(kuò)容縮容,那么此時(shí)想要持久化一些數(shù)據(jù)怎么辦? 當(dāng)然 Control 函數(shù)中還是可以以操作數(shù)據(jù)庫的命令方式來實(shí)現(xiàn)。但是,這種方式并不合理,因?yàn)?Control 層的方式變了,假如 Model 層還是以之前的那種方式,那么這種架構(gòu)肯定是要散架。此時(shí),就需要 BaaS 了,也就是將 Model 層進(jìn)行 BaaS 化,BaaS 就是專門配合 FaaS 用的。下面 Model 層以 MySQL 為例,Model 層最好將操作數(shù)據(jù)庫的命令封裝成 HTTP 的 OpenAPI,提供給 FaaS 調(diào)用,自己控制這個(gè) API 的請求頻率以及限流降低等。這個(gè) Model 層本身則可以通過連接池、MySQL 集群等方式去優(yōu)化。如下圖所示:
至此,基于 Serverless 架構(gòu),傳統(tǒng)的 MVC 架構(gòu)完完全全被轉(zhuǎn)化為了 View + FaaS + BaaS 的組合了。Serverless 毋庸置疑是因?yàn)?FaaS 架構(gòu)才流行起來的。我們常見的 Serverless 都是指 Serverless Computing 架構(gòu),也就是由 Trigger、FaaS、BaaS 架構(gòu)組成的應(yīng)用。
廣義的 Serverless
廣義的 Serverless 其實(shí)就是指服務(wù)端免運(yùn)維,也是未來的趨勢。要想達(dá)到 NoOps,需要具備:
無需用戶關(guān)心服務(wù)端的事情(容錯(cuò)、容災(zāi)、安全驗(yàn)證、自動(dòng)擴(kuò)縮容、日志調(diào)試)
按使用量 (調(diào)用次數(shù)、時(shí)長等) 付費(fèi),低費(fèi)用和高性能并行,大多數(shù)場景下節(jié)省開支。
快速迭代 試錯(cuò)能力(多版本控制、灰度、CI CD 等等)。
為什么需要 Serverless 呢
在 2009 年的時(shí)候,有兩種相互競爭的云虛擬化方法:
Amazon EC2,EC2 實(shí)例看起來很像物理硬件,用戶可以從內(nèi)核向上控制整個(gè)軟件棧。
Google App Engine,是另一個(gè)針對特定領(lǐng)域的應(yīng)用平臺(tái),它是一種將 stateless 計(jì)算層和 stateful 的存儲(chǔ)層分類開來的一種應(yīng)用程序結(jié)構(gòu)。
最終市場使用了 Amazon 這種針對云計(jì)算的 low-level 虛擬機(jī)方式,而這種 low-level 虛擬機(jī)成功的主要原因是,早起的云計(jì)算用戶希望在云中可以重新創(chuàng)建一個(gè)與本地計(jì)算機(jī)上相同的計(jì)算環(huán)境,以簡化將其負(fù)載遷移到云上的工作。很明顯,這種實(shí)際需求比為云重新編寫新的程序更重要,尤其是在當(dāng)時(shí)云計(jì)算能否成功尚不明確的情況下。
然后這種方式的缺點(diǎn)是,開發(fā)人員必須自己管理虛擬機(jī),所以要么成為系統(tǒng)管理員,要么與它們一起設(shè)置環(huán)境。這些促使那些只使用簡單化應(yīng)用的客戶向云服務(wù)商提出新要求,希望能有更簡單的方式來運(yùn)行這些簡單應(yīng)用。例如,假設(shè)應(yīng)用希望將圖片從手機(jī)端應(yīng)用發(fā)送到云上,這需要?jiǎng)?chuàng)建極小的圖片并將其放在 web 上,完成這個(gè)任務(wù)可能只需要幾十行 JavaScript 代碼,這與設(shè)置適當(dāng)?shù)姆?wù)器環(huán)境來運(yùn)行這段代碼相比,這個(gè)代碼的開發(fā)是很微不足道的。
在這些需求的驅(qū)使下,Amazon 在 2015 年推出了一個(gè)名為 AWS Lambda service 的新服務(wù)。用戶只需要編寫代碼,服務(wù)器供應(yīng)和任務(wù)管理問題都由服務(wù)提供商來負(fù)責(zé)。編寫的代碼被打包為 FaaS(Function as a service),代表了 Serverless 計(jì)算的核心,但是云平臺(tái)還提供了專門的 Serverless 框架,以滿足特定的程序需求,如 BaaS(Backend as a Service)。簡單地說,無服務(wù)計(jì)算定義如下:Serverless Computing = FaaS + BaaS。同時(shí),服務(wù)被視為無服務(wù)的話,那么必須能夠自動(dòng)擴(kuò)縮容,并且根據(jù)實(shí)際使用情況計(jì)費(fèi)。
★Cloud functions (i.e., FaaS) provide general compute and are complemented by an ecosystem of specialized Backend as a Service (BaaS) offfferings such as object storage, databases, or messaging.
”Serverless VS Serverful
在 Serverless 中,用戶只需要使用高級語言編寫云函數(shù),選擇觸發(fā)云函數(shù)運(yùn)行的事件就可以了。例如,加載一個(gè)圖像到云存儲(chǔ)中,或者向數(shù)據(jù)庫添加一個(gè)很小的圖片時(shí),用戶只需要編寫相應(yīng)的代碼,而剩下的全都由 Serverless 系統(tǒng)來處理,比如選擇實(shí)例、擴(kuò)縮容、部署、容錯(cuò)、監(jiān)控、日志、安全補(bǔ)丁等等。下面,總結(jié)了 Serverless 和傳統(tǒng)方式的差異,我們將傳統(tǒng)方式稱為 Serverful。
Serverless 和 Serverful 計(jì)算最關(guān)鍵的三個(gè)不同之處在于:
** 將計(jì)算與存儲(chǔ)解耦。** 存儲(chǔ)和計(jì)算資源是分開提供的,相當(dāng)于這兩種資源的分配和計(jì)價(jià)都是獨(dú)立的,通常來說存儲(chǔ)資源是由一個(gè)獨(dú)立的云服務(wù)來提供的,并且計(jì)算是無狀態(tài)的。
** 執(zhí)行代碼而不需要管理資源分配。** 與傳統(tǒng)云計(jì)算用戶需要請求資源的方式不同,serverless 是用戶提交一段代碼,云會(huì)自動(dòng)給這段代碼分配資源并執(zhí)行。
** 以實(shí)際使用的資源量付費(fèi),而不是根據(jù)分配的資源數(shù)。**serverless 計(jì)費(fèi)是根據(jù)一系列與執(zhí)行相關(guān)的因素來計(jì)算的,例如代碼的執(zhí)行時(shí)間,而不實(shí)根據(jù)云平臺(tái),例如分配的 VM 的大小和數(shù)量
假如使用匯編語言和高級語言來形容的話,Serverful 計(jì)算類似于使用低級匯編語言進(jìn)行編程,而 Serverless 計(jì)算類似于使用高級語言 (例如 python) 進(jìn)行編程。例如,c = a + b 的簡單表達(dá)式的匯編程序員必須顯示選擇一個(gè)或者多個(gè)寄存器,將值加載到這些寄存器中,執(zhí)行運(yùn)算,然后存儲(chǔ)結(jié)果。這跟 Serverful 云編程的幾個(gè)步驟是類似的:首先提供資源或者標(biāo)識(shí)可用的資源,然后用必要的代碼和數(shù)據(jù)加載這些資源,執(zhí)行計(jì)算,返回或者存儲(chǔ)結(jié)果,最終管理資源釋放。而 Serverless 則提供了類似于高級編程語言的便捷性,Serverless 和高級編程語言也很相似性。比如,高級語言的自動(dòng)內(nèi)存管理不用再管理內(nèi)存資源,而 Serverless 計(jì)算使程序員也不用再管理服務(wù)器資源。
Attractiveness of Serverless Computing
對云服務(wù)提供商來說
Serverless 可以促進(jìn)業(yè)務(wù)的增長,因?yàn)樗沟迷朴?jì)算更容易編程,進(jìn)而有助于吸引新客戶并幫助現(xiàn)有客戶更多地使用云計(jì)算。例如,最近的調(diào)查發(fā)現(xiàn),大約 24% 的 Serverless 計(jì)算用戶是云計(jì)算的新用戶,30% 現(xiàn)有的 serverful 用戶也使用了 Serverless 計(jì)算。
短的運(yùn)行時(shí)間、較小的內(nèi)存占用和無狀態(tài)特性使得云提供商更容易找到那哪些未使用的資源來運(yùn)行這些任務(wù),從而改進(jìn)了資源復(fù)用。
可以利用不太流行的計(jì)算機(jī)(實(shí)例類型由云提供商決定),比如對 serverful 云客戶吸引較小的舊服務(wù)器。
★后面的兩點(diǎn)可以最大化現(xiàn)有的資源并提高收益。”
對用戶來說
從編程效率的提高中獲益,對于新手來說不需要理解云基礎(chǔ)設(shè)施的前提下部署函數(shù),老用戶可以節(jié)省出部署的時(shí)間并聚焦于應(yīng)用本身的問題。
節(jié)約成本,因?yàn)樵品?wù)提供商將底層服務(wù)器的利用率提高了,并且函數(shù)只有在事件發(fā)生時(shí)才會(huì)計(jì)費(fèi),而且是細(xì)粒度的計(jì)費(fèi)(通常是 100 毫秒),那么也就意味著只需要支付他們實(shí)際使用的部分而不是為他們預(yù)留的部分。
FaaS 是怎么運(yùn)行的
在 Serverless 出現(xiàn)之前,我們要部署這樣一個(gè) Hello World 應(yīng)用得何等繁瑣。
我們要購買虛擬機(jī)服務(wù);
初始化虛擬機(jī)運(yùn)行環(huán)境,安裝我們需要的應(yīng)用運(yùn)行環(huán)境,盡量和本地開發(fā)環(huán)境保持一致;
緊接著為了讓用戶能夠訪問我們剛剛啟動(dòng)的應(yīng)用,我們需要購買域名,用虛擬機(jī) IP 注冊域名,配置 Nginx,啟動(dòng) Nginx;
最后我們還需要上傳應(yīng)用代碼;
啟動(dòng)應(yīng)用;
采用 Serverless 之后,只需要簡單的 3 步。Serverless 相當(dāng)于對服務(wù)端運(yùn)維體系進(jìn)行了極端的抽象(抽象意味著用戶請求 HTTP 數(shù)據(jù)請求的全鏈路,并沒有質(zhì)的改變,只是將全鏈路的模型簡化了)。
之前在服務(wù)端構(gòu)建代碼的運(yùn)行環(huán)境 — 函數(shù)服務(wù)
之前需要負(fù)載均衡和反向代理 — HTTP 函數(shù)觸發(fā)器
上傳代碼和啟動(dòng)應(yīng)用 — 函數(shù)代碼
整個(gè)啟動(dòng)過程如下圖所示:
用戶第一次訪問 HTTP 函數(shù)觸發(fā)器時(shí),函數(shù)觸發(fā)器會(huì) Hold 住用戶的 HTTP 請求,并產(chǎn)生一個(gè) HTTP Request 事件通知函數(shù)服務(wù);
函數(shù)服務(wù)檢查有沒有閑置的函數(shù)實(shí)例,如果沒有函數(shù)實(shí)例,則去函數(shù)代碼倉庫拉取你的代碼,初始化并啟動(dòng)一個(gè)函數(shù)實(shí)例; 之后再傳入 HTTP Request 對象作為函數(shù)的參數(shù),執(zhí)行函數(shù)。
函數(shù)執(zhí)行的結(jié)果 HTTP Response 返回函數(shù)觸發(fā)器,函數(shù)觸發(fā)器再將結(jié)果返回給等待的用戶客戶端。
★FaaS 和 PaaS 平臺(tái)對比,最大的區(qū)別在于資源利用率。這也是 FaaS 最大的創(chuàng)新點(diǎn),F(xiàn)aaS 的應(yīng)用實(shí)例可以縮容到 0,而 PaaS 平臺(tái)至少要維持一臺(tái)服務(wù)或容器。這主要是因?yàn)?FaaS 可以做到極速啟動(dòng)函數(shù)實(shí)例,而 PaaS 創(chuàng)建實(shí)例通常需要幾十秒,為了保證你的服務(wù)可用性,必須一直維持至少一臺(tái)服務(wù)器運(yùn)行你的應(yīng)用實(shí)例。
FaaS 的極速啟動(dòng)
FaaS 中的冷啟動(dòng)是指從調(diào)用函數(shù)開始到函數(shù)實(shí)例準(zhǔn)備完成的整個(gè)過程。冷啟動(dòng)關(guān)注的是啟動(dòng)時(shí)間,啟動(dòng)時(shí)間越短,對資源的利用率就越高。現(xiàn)在的云服務(wù)商,基于不同的語言特性,冷啟動(dòng)平均耗時(shí)基本在 100~700 毫秒之間。
下面這張圖是 FaaS 應(yīng)用冷啟動(dòng)的過程。其中,藍(lán)色部分是云服務(wù)商負(fù)責(zé)的,紅色部分是用戶負(fù)責(zé)的。云服務(wù)商會(huì)不停地優(yōu)化自己負(fù)責(zé)的部分,畢竟啟動(dòng)速度越快對資源的利用率就越高,例如冷啟動(dòng)過程中耗時(shí)較長的是下載函數(shù)代碼。所以一旦你更新代碼,云服務(wù)商就會(huì)偷偷開始調(diào)度資源,下載你的代碼構(gòu)建函數(shù)實(shí)例的鏡像。請求第一次訪問時(shí),云服務(wù)商就可以利用構(gòu)建好的緩存鏡像,直接跳過冷啟動(dòng)的下載函數(shù)代碼步驟,從鏡像啟動(dòng)容器,這個(gè)也叫預(yù)熱冷啟動(dòng)。除此之外,還有預(yù)留實(shí)例策略也可加速或繞過冷啟動(dòng)時(shí)間。
★FaaS 服務(wù)從 0 開始,啟動(dòng)并執(zhí)行完一個(gè)函數(shù),只需要 100 毫秒。這也是為什么 FaaS 敢縮容到 0 的主要原因。通常我們打開一個(gè)網(wǎng)頁有個(gè)關(guān)鍵指標(biāo),響應(yīng)時(shí)間在 1 秒以內(nèi),都算優(yōu)秀。這么一對比,100 毫秒的啟動(dòng)時(shí)間,對于網(wǎng)頁的秒開率影響真的極小。”為什么應(yīng)用托管平臺(tái) PaaS 做不到極速啟動(dòng)呢? 因?yàn)閼?yīng)用托管平臺(tái) PaaS 為了適應(yīng)用戶的多樣性,必須支持多語言兼容,還要提供傳統(tǒng)后臺(tái)服務(wù),例如 MySQL、Redis。這也就意味著,PaaS 在初始化環(huán)境時(shí),有大量依賴和多語言版本需要兼容,而且兼容多種用戶的應(yīng)用代碼往往也會(huì)增加應(yīng)用構(gòu)建過程的時(shí)間。
而 FaaS 設(shè)計(jì)之初就犧牲了用戶的可控性和應(yīng)用場景,來簡化代碼模型,并且分層結(jié)構(gòu)進(jìn)一步提升了資源的利用率。
FaaS 的分層
FaaS 實(shí)例執(zhí)行時(shí),就如下圖所示,至少是 3 層結(jié)構(gòu):容器、運(yùn)行時(shí) runtime、具體的函數(shù)代碼。
目前的 FaaS 實(shí)現(xiàn)方案中,容器方案可能是 Docker 容器、VM 虛擬機(jī),甚至 Sandbox 沙盒環(huán)境。
運(yùn)行時(shí) Runtime,就是你的函數(shù)執(zhí)行時(shí)的上下文 context。Runtime 的信息包括代碼運(yùn)行的語言和版本,例如 Node.js v10,Python3.6; 可調(diào)用對象,例如 aliyun SDK; 系統(tǒng)信息,例如環(huán)境變量等等。
這樣分層的好處就是,容器層適用性更廣,云服務(wù)商可以預(yù)熱大量的容器實(shí)例,將物理服務(wù)器的計(jì)算碎片化。Runtime 的實(shí)例適用性較低,可以少量預(yù)熱。容器和 Runtime 固定后,下載你的代碼就可以執(zhí)行了。通過分層,我們就可以做到資源統(tǒng)籌優(yōu)化,讓你的代碼快速低成本地被執(zhí)行。
另外,一旦容器 Runtime 啟動(dòng)后,就會(huì)維持一段時(shí)間,這段時(shí)間內(nèi)的這個(gè)函數(shù)實(shí)例就可以直接處理用戶數(shù)據(jù)請求。當(dāng)一段時(shí)間內(nèi)沒有用戶請求事件發(fā)生(各個(gè)云服務(wù)商維持實(shí)例的時(shí)間和策略不同),則會(huì)銷毀這個(gè)函數(shù)實(shí)例。
FaaS 進(jìn)程模型
從運(yùn)行函數(shù)實(shí)例的進(jìn)程角度來看,有兩種模型:
用完即毀型:函數(shù)實(shí)例準(zhǔn)備好后,執(zhí)行完函數(shù)就直接結(jié)束。FaaS 最純正的用法。
常駐進(jìn)程型:函數(shù)實(shí)例準(zhǔn)備好后,執(zhí)行完函數(shù)不結(jié)束,而是返回繼續(xù)等待下一次函數(shù)被調(diào)用。即使 FaaS 是常駐進(jìn)程型,如果一段時(shí)間沒有事件觸發(fā),函數(shù)實(shí)例還是會(huì)被云服務(wù)商銷毀。
★從下面這張圖其實(shí)可以看到觸發(fā)器就是一個(gè)常駐進(jìn)程模型,只不過這個(gè)觸發(fā)器由云服務(wù)商處理罷了。”
假設(shè)我們要部署的是一個(gè) MVC 架構(gòu)的 Web 服務(wù),那么:
在之前,假設(shè)沒有 FaaS,我們要將應(yīng)用部署到托管平臺(tái) PaaS 上; 啟動(dòng) Web 服務(wù)時(shí),主進(jìn)程初始化連接 MongoDB,初始化完成后,持續(xù)監(jiān)聽服務(wù)器的 80 端口,直到監(jiān)聽端口的句柄關(guān)閉或主進(jìn)程接收到終止信號(hào); 當(dāng) 80 端口和客戶端建立完 TCP 鏈接,有 HTTP 請求過來,服務(wù)器就會(huì)將請求轉(zhuǎn)發(fā)給 Web 服務(wù)的主進(jìn)程,這時(shí)主進(jìn)程會(huì)創(chuàng)建一個(gè)子進(jìn)程來處理這個(gè)請求。
而在 FaaS 常駐進(jìn)程型模式下,首先我們要改造一下代碼,Node.js 的 Server 對象采用 FaaS Runtime 提供的 Server 對象; 然后我們把監(jiān)聽端口改為監(jiān)聽 HTTP 事件; 啟動(dòng) Web 服務(wù)時(shí),主進(jìn)程初始化連接 MongoDB,初始化完成后,持續(xù)監(jiān)聽 HTTP 事件,直到被云服務(wù)商控制的父進(jìn)程關(guān)閉回收。
當(dāng) HTTP 事件發(fā)生時(shí),我們的 Web 服務(wù)主進(jìn)程跟之前一樣,創(chuàng)建一個(gè)子進(jìn)程來處理這個(gè)請求事件。主進(jìn)程就如我們上圖中繪制的那個(gè)藍(lán)色的圓點(diǎn),當(dāng) HTTP 事件發(fā)生時(shí),它創(chuàng)建的子進(jìn)程就是藍(lán)色弧形箭頭,當(dāng)子進(jìn)程處理完后就會(huì)被主進(jìn)程回收。
通過上面的例子,可以看到:常駐進(jìn)程型就是為了傳統(tǒng) MVC 架構(gòu)部署上 FaaS 專門設(shè)計(jì)的(顯得很不自然,F(xiàn)aaS 原生的還是用完即毀型)。當(dāng)然也可以使用用完即毀型來部署 MVC 架構(gòu)的 Web 服務(wù),但是不推薦這么做,因?yàn)橛猛昙礆蛯鹘y(tǒng) MVC 改造的成本太大。
★從可控性和改造成本角度來看 Web 服務(wù),服務(wù)端部署方案最適合的還是托管平臺(tái) PaaS 或者自己搭服務(wù)跑在 IaaS 上。正如我上一講所說,使用 FaaS 就必須在 FaaS 的條件限制內(nèi)使用,最佳的做法應(yīng)該是一開始就選用 FaaS 開發(fā)。”用完即毀型適用的場景:數(shù)據(jù)編排和服務(wù)編排。
數(shù)據(jù)編排
目前最成功最廣泛的設(shè)計(jì)模式就是 MVC 模式。但隨著前端 MVVM 框架越來越火,前端 View 層逐漸前置,發(fā)展成 SPA 單頁應(yīng)用; 后端 Control 和 Model 層逐漸下沉,發(fā)展成面向服務(wù)編程的后端應(yīng)用。這種情況下,前后端更加徹底地解耦了,前端開發(fā)可以依賴 Mock 數(shù)據(jù)接口完全脫離后端限制,而后端的同學(xué)則可以面向數(shù)據(jù)接口開發(fā),但這也產(chǎn)生了高網(wǎng)絡(luò) I/O 的數(shù)據(jù)網(wǎng)關(guān)層。
Node.js 的異步非阻塞和 JavaScript 天然親近前端工程師的特性,自然地接過數(shù)據(jù)網(wǎng)關(guān)層。因此誕生了 Node.js 的 BFF 層 (Backend For Frontend),BFF 層充當(dāng)了中間膠水層的角色,粘合前后端。將后端數(shù)據(jù)和后端接口編排,適配成前端需要的數(shù)據(jù)結(jié)構(gòu),提供給前端使用。
★未經(jīng)加工的數(shù)據(jù),我們稱為元數(shù)據(jù) Raw Data,對于普通用戶來說元數(shù)據(jù)幾乎不可讀。所以我們需要將有用的數(shù)據(jù)組合起來,并且加工數(shù)據(jù),讓數(shù)據(jù)具備價(jià)值。對于數(shù)據(jù)的組合和加工,我們稱之為數(shù)據(jù)編排。”
BFF 層通常是由善于處理高網(wǎng)絡(luò) I/O 的 Node.js 應(yīng)用負(fù)責(zé)。傳統(tǒng)的服務(wù)端運(yùn)維 Node.js 應(yīng)用還是比較重的,需要我們購買虛擬機(jī),或者使用應(yīng)用托管 PaaS 平臺(tái)。但是,由于 BFF 層只是做無狀態(tài)的數(shù)據(jù)編排,所以我們完全可以用 FaaS 用完即毀型模型替換掉 BFF 層的 Node.js 應(yīng)用,也就是最近圈子里老說的 SFF(Serverless For Frontend)。
現(xiàn)在我們再串下新的請求鏈路邏輯。前端的一個(gè)數(shù)據(jù)請求過來,函數(shù)觸發(fā)器觸發(fā)我們的函數(shù)服務(wù); 我們的函數(shù)啟動(dòng)后,調(diào)用后端提供的元數(shù)據(jù)接口,并將返回的元數(shù)據(jù)加工成前端需要的數(shù)據(jù)格式; 我們的 FaaS 函數(shù)完全就可以休息了。
服務(wù)編排
服務(wù)編排和數(shù)據(jù)編排很像,主要區(qū)別是服務(wù)編排是對云服務(wù)商提供的各種服務(wù)進(jìn)行組合和加工(也就是說服務(wù)商提供了一些 API,我們對這些 API 進(jìn)行整合來實(shí)現(xiàn)我們想要的功能)。
在 FaaS 出現(xiàn)之前,就有服務(wù)編排的概念,但服務(wù)編排受限于服務(wù)支持的 SDK 語言版本。我們要使用這些服務(wù)或 API,都要通過自己熟悉的編程語言去找對應(yīng)的 SDK,在自己的代碼中加載 SDK,使用秘鑰調(diào)用 SDK 方法進(jìn)行編排。如果沒有 SDK,則需要自己根據(jù)平臺(tái)提供的接口或協(xié)議實(shí)現(xiàn) SDK。
但是,有了 FaaS 之后,我們就方便很多了。假如我們服務(wù)商沒有給我們提供我們熟悉的語言的 SDK,那么我們可以使用其他語言編寫一個(gè)編排的程序,這個(gè)編排的程序會(huì)對服務(wù)商的服務(wù)進(jìn)行編排。之后,我們再去調(diào)用這個(gè)編排的程序即可,而這個(gè)編排的程序就可以使用用完即毀的方式。比如,我們的 Web 服務(wù)需要發(fā)送驗(yàn)證碼郵件。我們查看阿里云的郵件服務(wù)文檔,發(fā)現(xiàn)阿里云只提供了 Java、PHP 和 Python 的 SDK,而沒有 Node.js 的 SDK。這個(gè)時(shí)候,我們可以參考郵件服務(wù)的 PHP 文檔,就用 PHP 的 SDK 創(chuàng)建一個(gè) FaaS 服務(wù)來發(fā)送郵件(發(fā)送郵件的功能是很單一的)。
這個(gè)也是 FaaS 的一個(gè)亮點(diǎn):語言無關(guān)性。它意味著你的團(tuán)隊(duì)不再局限于單一的開發(fā)語言了,你們可以利用 Java、PHP、Python、Node.js 各自的語言優(yōu)勢,混合開發(fā)出復(fù)雜的應(yīng)用。FaaS 服務(wù)編排被云服務(wù)商特別關(guān)注正是因?yàn)樗邆涞倪@種開放性。使用 FaaS 可以創(chuàng)造出各種各樣復(fù)雜的服務(wù)編排場景,而且還與語言無關(guān),這大大增加了云服務(wù)商各種服務(wù)的使用場景。當(dāng)然,這對開發(fā)者也提出了要求,它要求開發(fā)者去更多地了解云服務(wù)商提供的各種服務(wù)。
關(guān)于“Serverless 的相關(guān)知識(shí)點(diǎn)有哪些”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注丸趣 TV 行業(yè)資訊頻道,丸趣 TV 小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。