忽如一晚上春風來,千樹萬樹梨花開
,雲原生的浪潮伴隨着雲計算的迅速發展彷彿一晚上之間,迅速侵襲了技術的每一個角落。每一個人都在談論雲原生,談論雲原生對現有技術的變革。
Kubernetes已經成爲容器編排的事實標準,Servicemesh正在被各大廠商爭先恐後的落地實踐,Serverless從一個一直以來虛無縹緲的概念,到現在,也被擺在檯面,有隱隱約約崛起的勢頭。
只是沒想到,在後端悶頭搞容器化、上Kubernetes、嘗試Servicemesh的時候,Serverless卻先在前端火了起來。從今年的GMTC全球前端技術大會上,Serverless主題的火爆就可見一斑。筆者也看過一些網上流行的講Serverless的文章,觀點大同小異,實踐幾乎沒有,誤解與謬論滿篇飛。本文倒無心挑起爭論,只是試圖從一個雲計算研發的視角出發,聊一聊咱們眼中的Serverless。前端
前端爲何想要上Serverless,其實也很好理解,node.js的普及、前端工程化以及BFF的興起,愈來愈多的前端須要關心服務的構建、部署、運維,服務的日誌、監控報警等等,嚴重拖累了前端的開發效率,讓前端花不少時間在服務器上排查問題,無疑是痛苦而低效的。
對於前端來講,最原始的訴求是,我不肯意管服務器等底層資源,哪臺節點宕機了,麻煩不用通知我;流量太大了,服務須要擴容了,我也不想關心;我只須要寫好代碼,就能夠自動部署到服務器上,代碼有bug,能讓我看日誌和監控排查問題就行。
其實這也不僅僅是前端的夢想,不少後端或者數據類的研發,也有一樣的需求。不過咋看很美好,可是仔細想一想,有一些後端的業務很複雜,服務間調用關係以及各類特異化需求其實很難適用於Serverless,想徹底不關心底層的服務器,有點困難。
因此,Serverless並不是銀彈,關鍵是看業務場景和需求,就算只有50%的業務適合,能解決這50%業務的問題,那也是了不得的成就。node
瞭解Serverless的同窗,或多或少都聽過Faas,Faas即Function as a service,通常都稱爲函數計算。
做爲開發人員,只須要寫一個函數,就能夠在例如AWS Lambda等各類函數計算平臺上運行起來,真正實現了對服務器的無感知,同時能夠對外快速暴露API接口,能夠基於函數級別的自動擴縮容,能夠監聽各類事件進行觸發。
並且Faas結合雲平臺的webIDE,若是webIDE設計的足夠好,能夠給咱們帶來雲平臺上更方便的開發體驗,結合雲上的各類工具和生態,將來會有更大的想象空間。
不過,顯而易見,以函數爲最小粒度,有一些侷限性。
微服務是以功能職責爲劃分,拆分紅一個一個專一於特定功能和需求的服務,爲了解決微服務之間的網絡調用和流量管理,引入了不少服務治理等相關的功能和組件,能夠想象一下,若是把服務模塊再拆分爲函數的粒度,函數之間的調用關係無疑會爆炸,再思考一下,如何把老的服務改形成Faas形態,如何複用函數之間的邏輯,如何管理大量函數代碼,這無疑對開發者帶來了不少困擾。
因此,Faas不太適合通常後臺長期運行的web服務型應用,真正適合的是那些數據計算、批處理等業務,這些業務邏輯比較單一,運行完能夠中止,並且更適合Serverless中基於事件觸發的特性,冷啓動的延時也無所謂。
Faas的一個基本特徵是無狀態,那實際上的數據或者狀態該如何存儲呢,因此說到Faas通常都會說起Baas,即Backend as a service,不過相似的Xaas的名詞太多了,Baas這個名詞看着就像是有人爲了強行補充Faas沒有乾的活兒而起的。所以有些人粗暴的總結Serverless = Faas + Baas,固然若是你要強行認爲Serverless就是函數計算,那這個也沒有問題。
不過,咱們的觀點是:Faas只是Serverless的一種特例。在這個世界上,除了Faas,還有更多的無狀態工做負載適合以Serverless的形態去運行。git
除了服務的粒度不同以外,無狀態工做負載和Faas通常都具備如下Serverless的特性:github
既然是Serverless,開發者真正關心和麪對的是代碼層面,因此無論是函數仍是一個代碼工程,一鍵構建和部署是咱們的終極指望。
Kubernetes生態下有各類CI/CD解決方案,可是缺少更加一鍵式的工具能夠幫咱們將代碼(函數)迅速轉變成部署的服務。因此,一個足夠好用的本地client工具、一個完善而高效的CI/CD平臺很重要。對於Faas,可讓用戶便捷的將函數部署到Serverless平臺,對於無狀態負載,則能夠根據用戶需求暴露一些構建的自定義配置和流程。web
在Kubernetes上通常服務實際的運行都或多或少的須要咱們建立不少的Kubernetes資源,例如service、ingress等,而Serverless會作更多的自動化操做,以便更方便的提供服務。例如,Serverless平臺會自動提供流量入口和路由,部署完成後能夠迅速對外提供服務,同時提供相似藍綠髮布、灰度等流量管理等功能。算法
毫無疑問,Kubernetes也有HPA能夠提供自動擴縮容。不過,HPA敢讓服務副本數縮爲0嗎?固然不敢,試想一下,若是服務的副本數爲0,至關於再也不運行了,用戶的流量如何導入呢,用戶連服務的接口都調不通了,HPA更沒有metric數據來感知去擴容服務了。HPA沒法縮容爲0,對於某些短運行的計算類服務來講,是沒法接受的,由於這樣就不能真正的作到無服務,不實際運行時不佔資源不計費。
固然Serverless能夠作到,讓服務在沒有請求時自動縮爲0,在有流量的時候從0啓動,或者流量增大時快速的擴容,迅速應對流量的變化。
不過,還有一個Serverless業界都很關注的點,就是服務從0擴容爲多副本時啓動的延時時間,通常稱爲冷啓動的問題。若是冷啓動時間太長,對於用戶的第一次請求確定有很大影響,業內也有不少大廠在作一些優化。可是若是不是直接面向用戶流量的服務,例如我只想跑個數據處理算法,其實也不在意這幾百毫秒的啓動延遲,若是是相似前端的web服務,恐怕大部分人仍是寧願空跑一個單副本的服務,也不肯意冒這個風險吧。小程序
Serverless的另一個特徵是基於eventing事件進行觸發,事件其實是一個比較抽象的說法,不少東西均可以理解爲事件。例如,用戶的請求能夠認爲是一個事件,git的webhook能夠認爲是事件,kafka上有了消息能夠理解爲一個事件,包括Kubernetes的各類資源操做等等都是。因此,其實事件觸發咱們並不陌生,咱們的平時開發和設計架構裏常常都會有意無心的使用到事件觸發的機制,只是太過日常,反而沒有人去注意和抽象出這麼一個理念。
如今你們都在倡導雲原生,不少服務都是往雲上遷移和部署,事件觸發機制在雲上能夠有更多的擴展性和想象力。例如,咱們的Serverless應用能夠監聽雲上的中間件或者基礎組件的事件,經過這些事件,觸發特定的Serverless應用,從而打通雲上的Paas服務,實現雲上服務的一體化。 後端
總結下來,雖然目前Serverless很火但咱們更應該靜下心來思考,爲何會有Serverless的誕生,Serverless最原始的需求和驅動力在哪?是Kubernetes不夠好用仍是Servicemesh不夠友好?
Kubernetes被認爲是下一代的分佈式操做系統,操做系統上必然會運行各類各樣千奇百怪的程序,有的須要直面系統內核,有的只是提供用戶更好的UI,不過,有一類程序能夠以更便捷的方式去編譯、運行,而提供這一切的工具與平臺就是Serverless。
因此,Serverless其實只是一種雲原生應用更爲特殊的實現和表現方式,也有不少的應用並不適合以Serverless的方式去運行。無服務器當然是願景,大量的封裝和抽象讓開發者無需感知不少東西,但這個宇宙運行的規律可能並不是直白的線性系統,混沌和複雜性纔是常態。若是有人告訴你,Serverless是全部應用的終極目標,那隻能引用一句長者的話,too young, too simple
。前端工程化
基於Serverless的特性,咱們也能夠推導出比較適合Serverless的應用都有哪些:緩存
其實還有不少,不過須要指出的是,這些都能在咱們常規的容器雲平臺上構建部署運行,只不過,有了Serverless更高層次的抽象和封裝,咱們能夠更快的開發構建部署,服務能夠有更好的運行姿態,從而一步步接近咱們想象中的那個只用寫代碼,不關心服務器的美好願景。
做爲Faas鼻祖的AWS Lambda其實早就已經推出了,但最近的幾年內其餘雲廠商才慢慢跟上推出函數計算服務。 相信國內的不少公司也在嘗試Faas或者Serverless架構,不過能夠猜想出你們或多或少都心存疑慮或者有不放心之感,不敢真正的放上本身的線上服務。
目前看來,雖然Serverless市面上都吹的很火,但實際落地的寥寥可數,星星點點的一些火花,仍是難以造成燎原之勢。Serverless這片土地十分遼闊,可是各大雲廠商卻都是在本身和本身過家家,至於其餘人怎麼玩的,就不怎麼關心了。
因此,目前一個很大的問題就是咱們在一家函數計算平臺跑了本身的服務以後,基本上就和這個平臺綁定了,特別是若是你還用到Eventing,因爲都是基於平臺內部特定的事件觸發機制,遷移成本仍是比較高的。
終極緣由,目前尚未一個強勢而大一統的框架和平臺,可讓你們甘願臣服。想當年,容器編排領域興起,Kubernetes和Mesos大戰,兩邊各自有人站隊,雲廠商也各自押寶,現在Kubernetes一統江湖,你們都默默的創建起了基於Kubernetes的容器雲平臺,因而圍繞着Kubernetes的雲原生生態蓬勃發展。
因爲沒有統一的平臺,針對Serverless目前還存在的一些侷限,你們作的優化和改進也是各自爲戰,難以落地生根。
雖然現在已然是2019年了,但咱們仍是看到了一些但願和將來的苗頭。CNCF雲原生計算基金會的Landscape中專門對Serverless分出一頁(https://landscape.cncf.io/format=Serverless
),上面總結了Serverless相關的各類平臺和框架,其中目前最爲火熱和最有前景的即是Knative了。Google Cloud已經基於Knative推出了Cloud Run,阿里雲的Kubernetes容器服務也最近引入了Knative的內測,這讓咱們無疑看到了將來統一Serverless平臺的但願。
Knative是谷歌開源的Serverless架構方案,旨在提供一套簡單易用的Serverless平臺,把Serverless 標準化。Knative不侷限於Faas,而是指望可以運行全部的無狀態工做負載。像其餘絕大部分的Faas或者Serverless平臺同樣,Knative也是基於Kubernetes,不過,Knative還基於Istio或者Gloo網關等實現流量的分發和管理。
還在不久以前,Knative分爲三個組件:
Build負責將代碼轉換成咱們須要的容器鏡像,Serving則是提供Serverless的運行方式,Eventing則致力於提供標準化的事件觸發機制。
不過,如今Build模塊已經被棄用,被由Build的設計思路而發起的Tekton項目替換(參考:《Kubernetes原生CI/CD工具:Tekton探祕與上手實踐》)。固然你也可使用其餘合適的CI/CD工具替代。
Serving模塊主要作的工做本質上就兩個:
以基於istio爲例,Knative自動建立istio的ingressgateway,服務的service等,將流量導入新部署的服務,而不須要手動的建立各類service,ingress暴露服務和流量入口。同時,將不一樣版本對應不一樣的deployment,能夠方便的實現藍綠、灰度等發佈部署方式。以下圖所示:
Knative有自身基於流量請求算法的metric自動擴縮容(KPA)的方式,也支持Kubernetes原生的HPA實現自動擴縮容。同時,在服務縮容爲0以後,Serving會將服務流量路由到冷啓動的組件,緩存請求,而後擴容服務,再將流量導入啓動後的服務副本。
Knative Eventing則聯合 CNCF Serverless WG制定一套事件格式規範並推廣(https://github.com/cloudevents/spec/blob/master/spec.md#design-goals
),只須要各個雲廠商都按照這個規範,咱們的Serverless服務就能夠進行跨平臺的事件觸發,也不會被特定的雲廠商綁定。 固然,Knative的具體使用和實現細節很難用簡單的幾句話解釋清楚,若是有興趣,歡迎關注咱們後續對Knative深度剖析的系列文章。