如何使用 Serverless 做架構(gòu)和項目管理—— 三年全棧經(jīng)驗總結(jié)

本文是從項目工程角度來講解的,技術(shù)角度請參看另一個文章《真實項目代碼教你四步扔了傳統(tǒng)服務(wù)器,讓你優(yōu)雅使用Serverless做全棧開發(fā)》(https://zhuanlan.zhihu.com/p/493447018)
本文匯總了我的多個Serverless的全棧項目實際開發(fā)的經(jīng)驗,主要針對中小型項目。可以直接使用我的經(jīng)驗,或者根據(jù)實際情況再做調(diào)整。

第一步:決策Serverless
項目管理的藝術(shù)體現(xiàn)在如何在限定條件下發(fā)揮優(yōu)勢、規(guī)避劣勢,因此我們需要先確定中小項目里Serverless的優(yōu)劣勢是什么。
(一)Serverless的優(yōu)勢
成本低:對小項目來說,Serverless的成本可以說極其低,雖然我們技術(shù)人員不太關(guān)心和負(fù)責(zé)成本,但是對于中小項目的公司級決策來說,成本是一個無法規(guī)避的問題。
低人員需求(專注開發(fā)):不再需要對服務(wù)器環(huán)境進(jìn)行配置、管理和優(yōu)化了,代碼直接上傳即可使用。
顛覆式的性能優(yōu)化(性能就是這么方便):這個是我最看重的優(yōu)勢,也是必須發(fā)揮的優(yōu)勢。傳統(tǒng)服務(wù)器的調(diào)優(yōu)配置是針對全項目級的,一個接口出現(xiàn)性能瓶頸需要拉動整個項目的配置,而Serverless可以做單個API接口級的性能優(yōu)化,比如我們可以只提高首頁、熱門活動的性能配置。這是其他傳統(tǒng)項目需付出較高的開發(fā)代價才能做到的,而Serverless極其輕松的就可以實現(xiàn)。
安全:Serverless因其獨特的特點,注定其安全也和傳統(tǒng)安全有很大不同。當(dāng)前主流網(wǎng)絡(luò)攻擊如系統(tǒng)入侵、DDos攻擊等方式對Serverless大多并不生效甚至直接失效,也尚未發(fā)現(xiàn)專門針對Serverless的攻擊工具,加上Serverless本身提供了一些安全機制,比如騰訊云SCF的單函數(shù)的獨占配額、全函數(shù)的共享配額、API網(wǎng)關(guān)鑒權(quán)等,合理的使用后可以低成本實現(xiàn)高安全性。

(二)Serverless弊端:他的弊端需要生態(tài)來解決
實踐少:Serverless雖然2014年就出來了,但是真的被用起來感覺是這三四年的事,使用也以高大上的項目或個人自己玩票為主,全棧項目更是少了。同時,有實踐經(jīng)驗的人員又缺乏布道的時間和渠道,市面的書籍也以理論為主。因此行業(yè)內(nèi)尚無成熟的、權(quán)威的工程理論來指導(dǎo)Serverless的 DevSecOps,這就對項目經(jīng)理自身提出了更高的要求,甚至對項目經(jīng)理是否可以準(zhǔn)確評估風(fēng)險和大膽決策提出了額外要求。
框架少:現(xiàn)在還沒有Serverless原生框架。
部署麻煩:不用多說,這個是硬傷,但也是最好解決的。如同10多年前的JavaScript突然興起后出現(xiàn)的jQuery等框架,Serverless的弊端就是開發(fā)者的機會,大膽嘗試率先尋找出解決之道的也將引領(lǐng)Serverless。
第二步:項目方案選型

WEB函數(shù):在我看來“WEB函數(shù)”是為了擴展云函數(shù)的市場占有率而硬搞出來東西,甚至在開始的時候,云函數(shù)根本就沒有這個“WEB函數(shù)”,是最近一兩年才有的。
廈門量潮科技有限公司的創(chuàng)始人兼CEO張果(知乎iGuo)也提到“WEB函數(shù)”其實就是一種妥協(xié)。
WEB函數(shù)是將整個項目集合在一個云函數(shù)里面進(jìn)行部署, 這會讓我們無法發(fā)揮Serverless的“接口級管理”和“安全”兩大優(yōu)勢,喪失了Serverless最大的特性,而僅得到了“框架支持”這個功能,是非常不劃算的。其實框架支持在Serverless中其實對中小項目來說并不重要,甚至是可有可無,詳見下面說明。
部署方式的選擇:
代碼部署就是直接將代碼部署到云上。鏡像部署是將項目在本地制作成鏡像后上傳到騰訊云的“容器鏡像服務(wù)”,再推送到云函數(shù)中。
其實騰訊云內(nèi)置的各項擴展已經(jīng)滿足大部分的項目技術(shù)需求了,部分沒有直接內(nèi)置的也可以自己通過第三方包直接實現(xiàn),除了要求很復(fù)雜的項目外,代碼部署已經(jīng)滿足大多數(shù)項目的需求了。
“代碼部署”的方式讓云上和本地保持了高度一致性,甚至云上問題本地可以快速、簡單的還原,同時部署操作簡單、維護便捷、速度快、性能好、本地或云上調(diào)試方便。
因此建議:盡量在“代碼部署”確實不能滿足項目需求的時候才使用“鏡像部署”。
我認(rèn)為:Serverless應(yīng)用的極致體驗是本地 hello world式開發(fā),就等同于項目開發(fā)。
第三步:框架選擇
以PHP為例,中小項目使用Serverless,傳統(tǒng)的框架很可能是拖后腿的,是不是覺得很怪異?項目采用框架的目的是為了在工程角度上,更高效、更便捷、更高性能地對項目進(jìn)行開發(fā)和維護。之所以需要框架是因為相對于服務(wù)器開發(fā)而言,本地程序的開發(fā)考慮事情比較少,比如不太需要顧慮性能、不需要考慮大并發(fā)等。框架幫我們做了很多這方面工作,以幫助我們解決線上項目的需求。但是在Serverless中,對于普通項目來說,框架已經(jīng)失去了大部分的價值和意義。
性能弱化:在Serverless中,其實我們使用的不是服務(wù)器而是計算能力,鑒于云函數(shù)本身提供的計算能力相當(dāng)強,因此即便是質(zhì)量差的代碼,也扛得住,框架的高性能其實已經(jīng)被弱化。
并發(fā)弱化:對中小項目來說,絕大部分的業(yè)務(wù)執(zhí)行時間是很短的,高并發(fā)的壓力并非來源于高效算法壓力,而是來源于流量和計算資源的瞬間增長超過了服務(wù)器提供的能力。云函數(shù)每次調(diào)用可以說是物理隔離的,因此云函數(shù)其實就相當(dāng)于是“自動無限膨脹”的計算和網(wǎng)絡(luò)資源,因此不懼高并發(fā)。框架的高并發(fā)方面優(yōu)化的需求其實也就可有可無了。
功能失效:在Serverless中,傳統(tǒng)連接池失效,我們需要獨創(chuàng)連接池,各大云服務(wù)商的數(shù)據(jù)庫也為云函數(shù)的大量鏈接需求進(jìn)行了優(yōu)化,直接提供2000以上的同時鏈接支持。
學(xué)習(xí)成本:中小項目不需要高深技術(shù),沒有龐大的業(yè)務(wù)鏈,快速簡單才是需求。任何框架,再簡單的框架都需要學(xué)習(xí)成本,大多數(shù)技術(shù)開發(fā)者也僅僅只是百度下用法就開始使用,并不會深入研究。因此越是小的項目,當(dāng)框架本身不滿足或者出現(xiàn)問題的時候,框架本身就成了最大的障礙。對于中小項目,也有人為用框架而用框架。
框架不支持:如上所述,大部分語言的框架“事件函數(shù)”并不支持。
沒有Serverless的原生框架。
Serverless技術(shù)框架說明:
要想充分發(fā)揮Serverless的優(yōu)勢則必須采用多函數(shù)部署,即微服務(wù)架構(gòu)模式。Serverless最終、最好的歸宿一定是微服務(wù)架構(gòu)模式,現(xiàn)在的各傳統(tǒng)框架只是沒有原生框架前的臨時過渡。
傳統(tǒng)微服務(wù)框架一般是針對大項目,有著很高的學(xué)習(xí)和入手成本。中小項目的微服務(wù)其實異常簡單,我們并不真的采用微服務(wù)框架,而是像寫本地hello world一樣開發(fā)項目,部署時一個API接口一個云函數(shù)。
我們要微服務(wù)的好處,不要他的麻煩。因此我們應(yīng)該采用的模式是:傳統(tǒng)架構(gòu)+傳統(tǒng)開發(fā)+微服務(wù)式部署。
最簡單的方式就是采用簡單的框架,然后將每個和客戶端交互的API部署成單獨的函數(shù)。一個高效的Serverless開發(fā)框架,必須要支持本地單元測試,并且單元測試的效果必須等同于部署后的執(zhí)行效果。因為不方便測試的框架會讓開發(fā)者偷懶,等待功能部署后再測試,這容易造成很大的返工問題。單元測試的實現(xiàn)邏輯可以參考我上個文章。
因此在我看來,對于中小項目來說,當(dāng)不用框架不影響團隊協(xié)作和效率的時候,就不需要上框架了(傳統(tǒng)框架對云函數(shù)并不太匹配),或者自己寫個簡單的共性項目結(jié)構(gòu)或框架即可。以API接口為單位進(jìn)行部署,部署完畢后直接就形成了微服務(wù)。
開發(fā)時只需要特別注意全項目不存在session,各個API接口執(zhí)行時是互相物理隔離,數(shù)據(jù)不互通的。
我的項目采用的框架是針對Serverless的自研框架,已經(jīng)使用了多個項目。該框架較好的利用了云函數(shù)的各項特性的同時,不但沒有增加開發(fā)難度,反而降低了,低到我都感覺有點LOW。如圖:
xxxxapi.php:此為接口文件,位于項目根目錄下,是依據(jù)功能拆分的全部云函數(shù)的執(zhí)行入口,比如adminapi.php下的sendadminsms函數(shù),部署的時候云函數(shù)名叫做sendadminsms,API網(wǎng)關(guān)為:/admin/sendadminsms。注意事項:多個接口文件中函數(shù)名不可以重復(fù),因為云上的云函數(shù)的名字不能重名。
ctrl目錄:類似其他項目的control模塊,負(fù)責(zé)業(yè)務(wù)代碼。比如: AdminCtrl.php。
model目錄:數(shù)據(jù)庫模塊,負(fù)責(zé)數(shù)據(jù)庫操作,如: AdminModel.php。
vendor中的simplescf:核心庫我自行研發(fā)了一套專門針對騰訊云函數(shù)的核心庫,實現(xiàn)了云函數(shù)動態(tài)調(diào)用、動態(tài)控制、單元測試的執(zhí)行、數(shù)據(jù)庫的封裝、日志的處理和一個極便捷的ORM數(shù)據(jù)庫封裝(支持TCB免費數(shù)據(jù)庫)等,類似微信云云開發(fā)的SCF版本。微信云的云開發(fā)限制性很大,本框架可以同時支持WEB、小程序、APP。
整體調(diào)用順序:?部署完畢后,客戶端-->API網(wǎng)關(guān)-->xxxapi.php入口函數(shù)--->ctrl處理業(yè)務(wù)邏輯-->model處理數(shù)據(jù)。

第四步:項目分工進(jìn)度安排
Serverless的項目管理中,任務(wù)的分工不能簡單的按照傳統(tǒng)的功能模塊來分工,而是以API為單位指定責(zé)任人,并進(jìn)行工作量評估,測試也以API為單位。
若項目涉及協(xié)作,完整的流程建議:
PM預(yù)先創(chuàng)建好各API,并制定好入?yún)⒑统鰠ⅰ]p度的創(chuàng)建是預(yù)先定義好調(diào)用入口函數(shù);深度的創(chuàng)建不但創(chuàng)建入口函數(shù),同時將DEMO代碼部署到云上,深度創(chuàng)建可以有效的讓前后臺異步開發(fā)。
對API接口安排負(fù)責(zé)人,并制定開發(fā)計劃。
盡量每人負(fù)責(zé)的API任務(wù)是共性的,比如此人負(fù)責(zé)的基本是raceapi.php接口文件中的函數(shù)。
將項目的公共功能提煉成公共模塊。
建立好單元測試,讓本地化測試(單元測試TDD)高保真模擬云執(zhí)行是高效非常重要的點。
第五步:項目部署
當(dāng)前Serverless的部署基本就是三種:管理后臺、Serverless Framework CLI和SDK。
管理后臺:你得打開網(wǎng)頁,你得給成員賬號密碼,你得登陸,可能多個人都同時需要,就是兩個字“麻煩”。
Serverless Framework CLI:需要yaml配置文件,需要你自己修改配置,配置錯了可能把你的項目就沖了,需要你給key,要不搞那種什么二維碼掃碼,這真的是中國特色,很是想吐槽。我一個重度使用者偶爾也會配錯,還會把已有配置給沖了,為此我差點砸了桌子。
SDK:別想啦,你為了部署會自己研究SDK嗎?一個觸發(fā)器可能需要2個產(chǎn)品的SDK配合才可以。因為我是騰訊云云函數(shù)的devops開發(fā)者,所以我是SDK重度使用者,但是我不認(rèn)為一個單獨的項目開發(fā)人員會搞這東西!浪費的時間還不夠雇個人專門給你部署呢!
項目中使用微服務(wù)模式部署,可能會有上百個API ,也就是上百個云函數(shù),最多的時候我一個項目部署了近300個云函數(shù),如果CLI來部署,是不是得折騰300個yaml,如果中間要更新某個函數(shù)代碼,我還得配置更新代碼的 yaml,如果要同時更新多個函數(shù)代碼呢?這三百個你還不能出錯,這么一想,CLI對我們小項目還是很尷尬的。
那么CLI的優(yōu)勢是什么呢?他可以跟CI進(jìn)行完美整合,通過CI來實現(xiàn)項目的自動部署,因此大型項目用這個用的很嗨,但是小項目來說,單元測試都不寫,你還跟我說CI?
所以整體下來,是不是感覺中小項目在部署這個工作上會碰到很大的問題。我的解決方案是自己搞了一個GUI部署工具,一鍵更新(秒級部署、更新函數(shù)代碼),還隱式做了項目管理工作的引導(dǎo)功能。差不多2個月后,工具會開源給大家免費用。這個是我使用Serverless做全棧開發(fā)的效率超過傳統(tǒng)模式的一個屠龍刀。
作者:Sheldor,知乎賬號:小助君,歡迎關(guān)注,了解更多關(guān)于Serverless的實踐經(jīng)驗。

