摘要:原文作者無服務器架構是指一個應用大量依賴第三方服務后端即服務,,簡稱,或者把代碼交由托管的短生命周期的容器中執行函數即服務,,簡稱。這些服務最早被稱為,下文將對此簡稱為。是目前的熱門實現之一,下文將對此簡稱為。它同樣經由網關暴露給外部使用。
譯注:
為了便于對照參考,“Serverless”、“BaaS” 等術語文中不做翻譯。
原文很長,這里分成上下兩篇。翻譯過程在 GitHub 上進行。
原文:https://martinfowler.com/articles/serverless.html
作者:Mike Roberts
無服務器架構(Serverless architectures)是指一個應用大量依賴第三方服務(后端即服務,Backend as a Service,簡稱“BaaS”),或者把代碼交由托管的、短生命周期的容器中執行(函數即服務,Function as a Service,簡稱“FaaS”)。現在最知名的 FaaS 平臺是 AWS Lambda。把這些技術和單頁應用等相關概念相結合,這樣的架構無需維護傳統應用中永遠保持在線的系統組件。Serverless 架構的長處是顯著減少運維成本、復雜度、以及項目起步時間,劣勢則在于更加依賴平臺供應商和現階段仍有待成熟的支持環境。
引言無服務器計算(Severless computing,簡稱 Serverless)現在是軟件架構圈中的熱門話題,三大云計算供應商(Amazon、Google 和 Microsoft)都在大力投入這個領域,涌現了不計其數的相關書籍、開源框架、商業產品、技術大會。到底什么是 Serverless?它有什么長處/短處?我希望通過本文對這些問題提供一些啟發。
開篇我們先來看看 Serverless 是什么,之后我會盡我所能中立地談談它的優勢和缺點。
什么是 Serverless就像軟件行業中的很多趨勢一樣,Serverless 的界限并不是特別清晰,尤其是它還涵蓋了兩個互相有重疊的概念:
Serverless 最早用于描述那些大部分或者完全依賴于第三方(云端)應用或服務來管理服務器端邏輯和狀態的應用,這些應用通常是富客戶端應用(單頁應用或者移動端 App),建立在云服務生態之上,包括數據庫(Parse、Firebase)、賬號系統(Auth0、AWS Cognito)等。這些服務最早被稱為 “(Mobile) Backend as a Service”,下文將對此簡稱為 “BaaS”。
Serverless 還可以指這種情況:應用的一部分服務端邏輯依然由開發者完成,但是和傳統架構不同,它運行在一個無狀態的計算容器中,由事件驅動、生命周期很短(甚至只有一次調用)、完全由第三方管理(感謝 ThoughtWorks 在他們最近的“技術觀察”中對此所做的定義)。這種情況稱為 Functions as a service / FaaS。AWS Lambda 是目前的熱門 FaaS 實現之一,下文將對此簡稱為 “FaaS”。
【邊欄注釋:“Serverless” 術語的起源】
本文將主要聚焦于 FaaS,不僅僅因為它是 Serverless 中最新也最熱門的領域,更重要的是它和我們傳統技術架構思路的顯著不同。
BaaS 和 FaaS 在運維層面有類似之處(都無需管理硬件資源),并且也經常配合使用。主流的云服務商都會提供一套“Serverless 全家桶”,囊括了 BaaS 和 FaaS 產品——例如 Amazon 的 Serverless 產品介紹,Google 的 Firebase 服務也緊密集成了 Google Cloud Functions。
對小公司而言這兩個領域也有交叉,Auth0 最初是一個 BaaS 產品,提供用戶管理的各種服務,他們后來創建了配套的 FaaS 服務 Webtask,并且將此概念進一步延伸推出了 Extend,支持其他 BaaS 和 SaaS 公司能夠輕松地在現有產品中加入 FaaS 能力。
一些示例 界面驅動的應用(UI-driven applications)我們來設想一個傳統的三層 C/S 架構,例如一個常見的電子商務應用(比如在線寵物商店),假設它服務端用 Java,客戶端用 HTML/JavaScript:
在這個架構下客戶端通常沒什么功能,系統中的大部分邏輯——身份驗證、頁面導航、搜索、交易——都在服務端實現。
把它改造成 Serverless 架構的話會是這樣:
這是張大幅簡化的架構圖,但還是有相當多變化之處:
我們移除了最初應用中的身份驗證邏輯,換用一個第三方的 BaaS 服務。
另一個 BaaS 示例:我們允許客戶端直接訪問一部分數據庫內容,這部分數據完全由第三方托管(如 AWS Dynamo),這里我們會用一些安全配置來管理客戶端訪問相應數據的權限。
前面兩點已經隱含了非常重要的第三點:先前服務器端的部分邏輯已經轉移到了客戶端,如保持用戶 Session、理解應用的 UX 結構(做頁面導航)、獲取數據并渲染出用戶界面等等。客戶端實際上已經在逐步演變為單頁應用。
還有一些任務需要保留在服務器上,比如繁重的計算任務或者需要訪問大量數據的操作。這里以“搜索”為例,搜索功能可以從持續運行的服務端中拆分出來,以 FaaS 的方式實現,從 API 網關(后文做詳細解釋)接收請求返回響應。這個服務器端函數可以和客戶端一樣,從同一個數據庫讀取產品數據。
我們原始的服務器端是用 Java 寫的,而 AWS Lambda(假定我們用的這家 FaaS 平臺)也支持 Java,那么原先的搜索代碼略作修改就能實現這個搜索函數。
最后我們還可以把“購買”功能改寫為另一個 FaaS 函數,出于安全考慮它需要在服務器端,而非客戶端實現。它同樣經由 API 網關暴露給外部使用。
消息驅動的應用(Message-driven applications)再舉一個后端數據處理服務的例子。假設你在做一個需要快速響應 UI 的用戶中心應用,同時你又想捕捉記錄所有的用戶行為。設想一個在線廣告系統,當用戶點擊了廣告你需要立刻跳轉到廣告目標,同時你還需要記錄這次點擊以便向廣告客戶收費(這個例子并非虛構,我的一位前同事最近就在做這項重構)。
傳統的架構會是這樣:“廣告服務器”同步響應用戶的點擊,同時發送一條消息給“點擊處理應用”,異步地更新數據庫(例如從客戶的賬戶里扣款)。
在 Serverless 架構下會是這樣:
這里兩個架構的差異比我們上一個例子要小很多。我們把一個長期保持在內存中待命的任務替換為托管在第三方平臺上以事件驅動的 FaaS 函數。注意這個第三方平臺提供了消息代理和 FaaS 執行環境,這兩個緊密相關的系統。
解構 “Function as a Service”我們已經提到多次 FaaS 的概念,現在來挖掘下它究竟是什么含義。先來看看 Amazon 的 Lambda 產品簡介:
通過 AWS Lambda,無需配置或管理服務器(1)即可運行代碼。您只需按消耗的計算時間付費 – 代碼未運行時不產生費用。借助 Lambda,您幾乎可以為任何類型的應用程序或后端服務(2)運行代碼,而且全部無需管理。只需上傳您的代碼,Lambda 會處理運行(3)和擴展高可用性(4)代碼所需的一切工作。您可以將您的代碼設置為自動從其他 AWS 服務(5)觸發,或者直接從任何 Web 或移動應用程序(6)調用。
本質上 FaaS 就是無需配置或管理你自己的服務器系統或者服務器應用即可運行后端代碼,其中第二項——服務器應用——是個關鍵因素,使其區別于現今其他一些流行的架構趨勢如容器或者 PaaS(Platform as a Service)。
回顧前面點擊處理的例子,FaaS 替換掉了點擊處理服務器(可能跑在一臺物理服務器或者容器中,但絕對是一個獨立的應用程序),它不需要服務器,也沒有一個應用程序在持續運行。
FaaS 不需要代碼基于特定的庫或框架,從語言或環境的層面來看 FaaS 就是一個普通的應用程序。例如 AWS Lambda 支持 JavaScript、Python 以及任意 JVM 語言(Java、Clojure、Scala 等),并且你的 FaaS 函數還可以調用任何一起部署的程序,也就是說實際上你可以用任何能編譯為 Unix 程序的語言(稍后我們會講到 Apex)。FaaS 也有一些不容忽視的局限,尤其是牽涉到狀態和執行時長問題,這些我們稍后詳談。
再次回顧一下點擊處理的例子——代碼遷移到 FaaS 唯一需要修改的是 main 方法(啟動)的部分,刪掉即可,也許還會有一些上層消息處理的代碼(實現消息監聽界面),不過這很可能只是方法簽名上的小改動。所有其他代碼(比如那些訪問數據庫的)都可以原樣用在 FaaS 中。
既然我們沒有服務器應用要執行,部署過程也和傳統的方式大相徑庭——把代碼上傳到 FaaS 平臺,平臺搞定所有其他事情。具體而言我們要做的就是上傳新版的代碼(zip 文件或者 jar 包)然后調用一個 API 來激活更新。
橫向擴展是完全自動化、彈性十足、由 FaaS 平臺供應商管理的。如果你需要并行處理 100 個請求,不用做任何處理系統可以自然而然地支持。FaaS 的“運算容器”會在運行時按需啟動執行函數,飛快地完成并結束。
回到我們的點擊處理應用,假設某個好日子我們的客戶點擊廣告的數量有平日的十倍之多,我們的點擊處理應用能承載得住么?我們寫的代碼是否支持并行處理?支持的話,一個運行實例能夠處理這么多點擊量嗎?如果環境允許多進程執行我們能自動支持或者手動配置支持嗎?以 FaaS 實現你的代碼需要一開始就以并行執行為默認前提,但除此之外就沒有其他要求了,平臺會完成所有的伸縮性需求。
FaaS 中的函數通常都由平臺指定的一些事件觸發。在 AWS 上有 S3(文件)更新、時間(定時任務)、消息總線(Kinesis)消息等,你的函數需要指定監聽某個事件源。在點擊處理器的例子中我們有個假設是已經采用了支持 FaaS 訂閱的消息代理,如果沒有的話這部分也需要一些代碼量。
大部分的 FaaS 平臺都支持 HTTP 請求觸發函數執行,通常都是以某種 API 網關的形式實現(如 AWS API Gateway,Webtask)。我們在寵物商店的例子中就以此來實現搜索和購買功能。
狀態當牽涉到本地(機器或者運行實例)狀態時 FaaS 有個不能忽視的限制。簡單點說就是你需要接受這么一個預設:函數調用中創建的所有中間狀態或環境狀態都不會影響之后的任何一次調用。這里的狀態包括了內存數據和本地磁盤存儲數據。從部署的角度換句話說就是 FaaS 函數都是無狀態的(Stateless)。
這對于應用架構有重大的影響,無獨有偶,“Twelve-Factor App” 的概念也有一模一樣的要求。
在此限制下的做法有多種,通常這個 FaaS 函數要么是天然無狀態的——純函數式地處理輸入并且輸出,要么使用數據庫、跨應用緩存(如 Redis)或者網絡文件系統(如 S3)來保存需要進一步處理的數據。
執行時長FaaS 函數可以執行的時間通常都是受限的,目前 AWS Lambda 函數執行最長不能超過五分鐘,否則會被強行終止。
這意味著某些需要長時間執行的任務需要調整實現方法才能用于 FaaS 平臺,例如你可能需要把一個原先長時間執行的任務拆分成多個協作的 FaaS 函數來執行。
啟動延遲目前你的 FaaS 函數響應請求的時間會受到大量因素的影響,可能從 10 毫秒到 2 分鐘不等。這聽起來很糟糕,不過我們來看看具體的情況,以 AWS Lambda 為例。
如果你的函數是 JavaScript 或者 Python 的,并且代碼量不是很大(千行以內),執行的消耗通常在 10 到 100 毫秒以內,大函數可能偶爾會稍高一些。
如果你的函數實現在 JVM 上,會偶爾碰到 10 秒以上的 JVM 啟動時間,不過這只會在兩種情況下發生:
你的函數調用觸發比較稀少,兩次調用間隔超過 10 分鐘。
流量突發峰值,比如通常每秒處理 10 個請求的任務在 10 秒內飆升到每秒 100 個。
前一種情況可以用個 hack 來解決:每五分鐘 ping 一次給函數保持熱身。
這些問題嚴重么?這要看你的應用類型和流量特征。我先前的團隊有一個 Java 的異步消息處理 Lambda 應用每天處理數億條消息,他們就完全不擔心啟動延遲的問題。如果你要寫的是一個低延時的交易程序,目前而言肯定不會考慮 FaaS 架構,無論你是用什么語言。
不論你是否認為你的應用會受此影響,都應該以生產環境級別的負載測試下實際性能情況。如果目前的情況還不能接受的話,可以幾個月后再看看,因為這也是現在的 FaaS 平臺供應商們主要集中精力在解決的問題。
API 網關我們前面還碰到過一個 FaaS 的概念:“API 網關”。API 網關是一個配置了路由的 HTTP 服務器,每個路由對應一個 FaaS 函數,當 API 網關收到請求時它找到匹配請求的路由,調用相應的 FaaS 函數。通常 API 網關還會把請求參數轉換成 FaaS 函數的調用參數。最后 API 網關把 FaaS 函數執行的結果返回給請求來源。
AWS 有自己的一套 API 網關,其他平臺也大同小異。
除了純粹的路由請求,API 網關還會負責身份認證、輸入參數校驗、響應代碼映射等,你可能已經敏銳地意識到這是否合理,如果你有這個考慮的話,我們待會兒就談。
另一個應用 API 網關加 FaaS 的場景是創建無服務器的 http 前端微服務,同時又具備了 FaaS 函數的伸縮性、管理便利等優勢。
目前 API 網關的相關工具鏈還不成熟,盡管這是可行的但也要夠大膽才能用。
工具鏈前面關于工具鏈還不成熟的說法是指大體上 FaaS 無服務器架構平臺的情況,也有例外,Auth0 Webtask 就很重視改善開發者體驗,Tomasz Janczuk 在最近一屆的 Serverless Conf 上做了精彩的展示。
無服務器應用的監控和調試還是有點棘手,我們會在本文未來的更新中進一步探討這方面。
開源無服務器 FaaS 的一個主要好處就是只需要近乎透明的運行時啟動調度,所以這個領域不像 Docker 或者容器領域那么依賴開源實現。未來肯定會有一些流行的 FaaS / API 網關平臺實現可以跑在私有服務器或者開發者工作站上,IBM 的 OpenWhisk 就是一個這樣的實現,不知道它是否能成為流行選擇,接下來的時間里肯定會有更多競爭者出現。
除了運行時的平臺實現,還是有不少開源工具用以輔助開發和部署的,例如 Serverless Framework 在 API 網關 + Lambda 的易用性上就比它的原創者 AWS 要好很多,這是一個 JS 為主的項目,如果你在寫一個 JS 網關應用一定要去了解下。
再如 Apex——“輕松創建、部署及管理 AWS Lambda 函數”。Apex 有意思的一點是它允許你用 AWS 平臺并不直接支持的語言來實現 Lambda 函數,比如 Go。
什么不是 Serverless在前文中我定義了 “Serverless” 是兩個概念的組合:“Backend as a Service” 和 “Function as a Service”,并且對后者的特性做了詳細解釋。
在我們開始探討它的好處和弊端之前,我想再花點兒時間在它的定義上,或者說:區分開那些容易和 Serverless 混淆的概念。我看到一些人(包括我自己最近)對此都有困惑,我想值得對此做個澄清。
對比 PaaS既然 Serverless FaaS 這么像 12-Factor 應用,那不就是另一種形式的 Platform as a Service 么?就像 Heroku?對此借用 Adrian Cockcroft 一句非常簡明的話:
如果你的 PaaS 能在 20ms 內啟動一個只運行半秒鐘的實例,它就叫 Serverless。
— Adrian Cockcroft
換句話說,大部分 PaaS 應用不會為了每個請求都啟動并結束整個應用,而 FaaS 就是這么做的。
好吧,然而假設我是個嫻熟的 12-Factor 應用開發者,寫代碼的方式還是沒有區別對么?沒錯,但是你如何運維是有很大不同的。鑒于我們都是 DevOps 工程師我們會在開發階段就充分考慮運維,對吧?
FaaS 和 PaaS 在運維方面的關鍵區別是伸縮性(Scaling)。對于大多數 PaaS 平臺而言你需要考慮如何伸縮,例如在 Heroku 上你要用到多少 Dyno 實例?對于 FaaS 應用這一步驟是完全透明的。即便你將 PaaS 配置為自動伸縮,也無法精細到單個請求級別,除非你有一個非常明確穩定的流量曲線可以針對性地配置。所以 FaaS 應用在成本方面要高效得多。
既然如此,何必還用 PaaS?有很多原因,最主要的因素應該是工具鏈成熟度。另外像Cloud Foundry 能夠給混合云和私有云的開發提供一致體驗,在寫就本文的時候 FaaS 還沒有這么成熟的平臺。
對比容器使用 Serverless FaaS 的好處之一是避免在操作系統層面管理應用程序進程。有一些 PaaS 平臺如 Heroku 也提供了這樣的特性;另一種對進程的抽象是容器,這類技術的代表是 Docker。容器托管系統(Mesos、Kubernetes 等)把應用從系統級開發中抽象出來,這種做法日漸流行,甚至在此之上云服務商的容器平臺(如 Amazon ECS、EKS、Google Cloud Engine)也像 Serverless FaaS 一樣允許團隊從管理主機中完全解放出來。在這股容器大潮中,FaaS 是否還有優勢?
概念上來說前面對 PaaS 的論斷仍舊適用于容器。Serverless FaaS 的伸縮性是完全自動化、透明、良好組織的,并且自動進行資源監控和分配;而容器平臺仍舊需要你對容量和集群進行管理。
另外我還得說容器技術也處在不夠成熟和穩定的階段,盡管它越來越接近了。當然這不是說 Serverless 就成熟了,但你終究需要在兩個都屬前沿的技術方向中做出選擇。
還有個值得一提的是不少容器平臺支持了自動伸縮的容器集群,Kubernetes 有內建的 Horizontal Pod Autoscaling 功能,AWS Fargate 則承諾會有“Serverless 容器”。
總的來說 Serverless FaaS 和托管容器在管理和伸縮性方面的差別已經不大,在它們之間的取舍更多看風格取向和應用的類型。例如事件驅動的應用組件更適合用 FaaS 實現,而同步請求驅動的應用組件更適合用容器實現。我預計很快就會有不少團隊和應用同時采用這兩種架構模式,期待看它們會擦出怎樣的火花。
對比 NoOpsServerless 并非“零運維”——盡管它可能是“無系統管理員”,也要看你在這個 Serverless 的兔子洞里走多深。
“運維”的意義遠不止系統管理,它還包括并不限于監控、部署、安全、網絡、支持、生產環境調試以及系統伸縮。這些事務同樣存在于 Serverless 應用中,你仍舊需要相應的方法處理它們。某些情況下 Serverless 的運維會更難一些,畢竟它還是個嶄新的技術。
系統管理的工作仍然要做,你只是把它外包給了 Serverless 環境。這既不能說壞也不能說好——我們外包了大量的內容,是好是壞要看具體情況。不論怎樣,某些時候這層抽象也會發生問題,就會需要一個來自某個地方的人類系統管理員來支持你的工作了。
Charity Majors 在第一屆 Serverless 大會上就這個主題做了個非常不錯的演講,也可以看看她相關的兩篇文章:WTF is operations? 和 Operational Best Practices)。
對比存儲過程即服務還有一種說法把 Serverless FaaS 看做“存儲過程即服務(Stored Procedures as a Service)”,我想原因是很多 FaaS 函數示范都用數據庫訪問作為例子。如果這就是它的主要用途,我想這個名字也不壞,但終究這只是 FaaS 的一種用例而已,這樣去考慮 FaaS 局限了它的能力。
我好奇 Serverless 會不會最終變成類似存儲過程那樣的東西,開始是個好主意,然后迅速演變成大規模技術債務。
— Camille Fournier
但我們仍然值得考慮 FaaS 是否會導致跟存儲過程類似的問題,包括 Camille 提到的技術債。有很多存儲過程給我們的教訓可以放在 FaaS 場景下重新審視,存儲過程的問題在于:
通常依賴于服務商指定的語言,或者至少是指定的語言框架/擴展
因為必須在數據庫環境中執行所以很難測試
難以進行版本控制,或者作為應用包進行管理
盡管不是所有存儲過程的實現都有這些問題,但它們都是常會碰到的。我們看看是否適用于 FaaS:
第一條就目前看來顯然不是 FaaS 的煩惱,直接排除。
第二條,因為 FaaS 函數都是純粹的代碼,所以應該和其他任何代碼一樣容易測試。整合測試是另一個問題,我們稍后展開細說。
第三條,既然 FaaS 函數都是純粹的代碼,版本控制自然不成問題;最近大家開始關心的應用打包,相關工具鏈也在日趨成熟,比如 Amazon 的 Serverless Application Model(SAM)和前面提到的其他 Serverless 框架都提供了類似的功能。2018 年初 Amazon 還開放了 Serverless Application Repository(SAR)服務,方便組織分發應用程序和組件,也是基于 AWS Serverless 服務構建的。關于 SAR 可以看看我的另一篇文章:Examining the AWS Serverless Application Repository。
本文翻譯的實時更新:https://amio.github.io/server...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/11929.html
摘要:流浪地球里對剎車時代逃逸時代和流浪時代的設定很有意思,類比于云計算行業,我們現在應該處于資源時代的末期,即將進入功能時代。 本文作者:張海龍,CODING 創始人兼 CEO 發完開工利是之后,2019 年算是正式開始了。 2019 年經濟減速的陰云籠罩了所有行業,云計算行業也難獨善其身:上游供應商英特爾將自身業務的疲軟歸咎于數據中心設備行業市場減速;與此同時微軟在 1 月 30 日公...
摘要:導讀近期靈雀云技術專家邵明岐翻譯了所著的一書的部分內容,可以說是對科普與觀察的上佳素材。移動應用程序可以無縫訪問同一個數據庫,以檢索過去的結果和排行榜數據。這些是統計信息,例如執行持續時間和面向客戶的指標,而不是可用磁盤空間或使用率。 導讀:近期靈雀云技術專家邵明岐翻譯了Mike Roberts & John Chapin所著的《What is Serverless》一書的部分內容,可...
摘要:年月,騰訊云宣布推出總價值超過億元的小程序云開發資源扶持計劃,對超過一百萬個小程序開發者提供免費資源扶持,全面助力開發者打造優秀小程序。 『 作為一個不斷發展的新興技術, Serverless 熱度的制高點已然到來。』 或許,Google Trends 所顯示的 3 年猛增 20 倍的 Serverless 搜索量,可以佐證 Serverless 在整個行業中的火爆程度。 showI...
摘要:年月,騰訊云宣布推出總價值超過億元的小程序云開發資源扶持計劃,對超過一百萬個小程序開發者提供免費資源扶持,全面助力開發者打造優秀小程序。 『 作為一個不斷發展的新興技術, Serverless 熱度的制高點已然到來。』 或許,Google Trends 所顯示的 3 年猛增 20 倍的 Serverless 搜索量,可以佐證 Serverless 在整個行業中的火爆程度。 showI...
閱讀 3712·2023-04-25 17:45
閱讀 3426·2021-09-04 16:40
閱讀 999·2019-08-30 13:54
閱讀 2125·2019-08-29 12:59
閱讀 1395·2019-08-26 12:11
閱讀 3272·2019-08-23 15:17
閱讀 1516·2019-08-23 12:07
閱讀 3878·2019-08-22 18:00