網易輕舟 Serverless 在前端工程化的實踐

作者 | 劉勤龍 / 傅軼

編輯 | 鄧豔琴

今年 1 月,網易數帆輕舟事業部資深開發工程師劉勤龍在 QCon+ 分享了《網易輕舟 Serverless 在前端工程化的實踐》,他介紹了網易數帆旗下輕舟團隊的 Serverless 實踐與思考,爲什麼要做 Serverless 平臺,如何做 Serverless 平臺,包括技術選型、平臺構建、產品形態、產品能力的系統性思考,和 Knative 開源項目的踩坑和優化經驗,並介紹了輕舟 Serverless 平臺的業務價值以及未來的一些規劃。本文根據此次分享整理。

爲什麼要做 Serverless 平臺

觸發這件事情的原因有兩部分,第一是趨勢,因爲前端發展趨勢使得前端工程師的工程化效率正在降低,作爲網易的基礎軟件團隊,網易數帆需要思考能否從基礎軟件層面解決前端的困擾,第二部分是當前前端工程師正面臨服務端渲染的問題。

首先說趨勢,體現在整個前端發展過程中。從以前的 Web 工程師,到前端工程師的職位的出現,當時還只是邏輯分工。第三階段是前端工程師時代,是一個前後端分離的時代。到我們目前正在處於的前後端(BFF)時代,前端工程師需要去負責部分後端的數據。甚至有些公司已經到了全棧工程師的時代,前端工程師需要負責後端所有的數據。

第二階段和第三階段,前端人員不需要關心後端資源,只需要把自己的代碼寫好,由後端或者是運維幫他們去做發佈。但是目前所處的階段,前端人員是需要去關心後端數據的,將來的全棧工程師時代,他們還需要去直接從數據庫裏邊獲取 / 操作數據,這個時候我們會發現,他需要操心低層的資源,因爲他需要把他的程序跑在服務端的後端,而前端工程師實際上不擅長操作和運維後端資源,因此會使得前端工程師的工程化效率降低。

第二點是我們當前正在面臨的問題,因爲前端工程師目前在做服務端渲染(SSR),採用這個技術的時候他需要自己申請機器,自己部署,同時他還得關注機器的狀態,並且他還得時常地翻閱基礎設施提供一些運維指南去做運維,其實這個事情是他們很不擅長的,並且對他們來說是一個負擔。

同時從後端運維的視角來看,前端工程師是在浪費資源。這有兩個原因,第一,很多業務屬於活動類型的;第二,前端工程師在申請機器的時候,他往往按照上限來預留資源,這就導致了大量的浪費。因此這就產生了 “前端工程師在浪費資源” 的問題。但其實前端工程師不是故意的,因爲他們不擅長運維服務器。因此我們需要解決前端工程師正在面臨的痛點。

從前端工程師的角度,他們的核心訴求就是隻寫代碼,聚焦核心業務,去創造核心價值,把一些服務端後端運維的事情完全交付給基礎設施去做,他們不需要去 care 這個事情。Serverless 的先進理念,其精華正是複雜度轉移,使得業務人員能夠聚焦他的核心場景,所以我們想打造一款 Serverless 產品,來解決前端工程師當前的困擾。

如何打造 Serverless 平臺

 技術選型

打造 Serverless 平臺之前,首先要對這個目標做拆解,然後再去做產品選型、技術選型。首先看目標拆解,第一點業務層的需求是即用即上,也就是說前端他想上線一個業務,他不需要去關心太多,他想什麼時候上線就可以什麼時候上線;第二點就是前端工程師不想去做後端資源的運維;第三點實際上不是前端工程師的需求,而是基礎設施層面的一個需求,就是儘量地能支撐好業務,同時也能夠省機器省錢。

這相對應的目標拆解爲:

因此我們的 Serverless 平臺要能夠集成 CI/CD,同時也能夠進行容器化,工作在 Kubernetes 上,具備自動擴縮容的能力。

再看產品選型。既然公有云 Serverless 做得這麼成熟,我們能否直接採用公有云產品來滿足我們業務開發需求?我們的回答是 NO,因爲我們需要去滿足一些定製化的用戶需求,而公有云的 Serverless 產品會受到很多資源包括使用的一些限制;第二個因素是我們的業務存在一些環境依賴,前端所依賴的一些數據庫、中間件,都是運行在網易公司的私有云環境中,這些東西公有云環境上都沒有;第三點也是追求技術自由,避免廠商鎖定。 所以,我們需要在私有云平臺中打造自己的 Serverless 平臺。

在技術選型上,我們基於三個原因選型了 Knative。

 平臺構建

輕舟 Serverless 平臺設計全景圖如下,從下往上有基礎設施層、服務層、應用編排層和業務層。其中我們比較關注的是應用編排層和服務層。整個 Serverless 平臺工作在已有的基礎設施之上,並且我們通過這個 Serverless 平臺後端,把它所需要的資源納入平臺組件能力,比如說 CI/CD、Knative API 網關,把這些資源結合起來,滿足我們 Serverless 的具體需求。

輕舟 Serverless 平臺具體的構成,從下圖可以看到,Serverless 的核心,我們可以理解成額外做的核心組件,包括一個 Serverless 前端控制檯和一個 Serverless 後端。這個核心負責把現有的一些組件聯合起來:通過 CI 去完成鏡像構建的需求;通過 Knative 去做部署;通過 API 網關去做具體業務的數據鏈路打通;同時還需要 Gitlab 來存儲代碼;爲了更高的開發效率,需要集成 Web IDE,這樣前端開發人員可以只在一個瀏覽器上就完成他所有的需求;同時爲了運維能力,需要去支持平臺層面的日誌平臺,以及監控告警的平臺;還需要一些預警,就是 Serverless 跑批和預警的一些組件。

輕舟 Serverless 平臺在這樣的構成下,它具體的流程,我們從業務開發者的視角來看,業務開發者先通過 Web IDE,或者是其他的本地開發工具來完成編碼,再把代碼 Push 到 GitLab 上去,然後就會觸發構建鏡像,或者他可以選擇手動觸發,或者是通過命令行觸發。當然這一步也可以把相關的一些資源,降級的靜態資源,構建到放到對象存儲裏面去。Serverless 控制檯構建完鏡像以後,會通過 Knative 的 Service 去發佈這個程序。整個發佈過程它會主動地拉取剛纔構建的鏡像,去做應用的部署和數據鏈路的打通。這就完成了整個業務的一鍵部署。

一鍵部署的業務流量模型,首先流量從外網打到外層的基於 Envoy 的 API 網關,API 網關會把流量發給內層的 Knative 網關。隨着訪問壓力的增大,我們要求它能夠擴容;而隨着資源處在訪問的低檔期,爲了能騰出更多的資源,我們要求它具備縮容的能力。同時這個 Serverless 平臺還必須考慮,當這一部分產生了異常的情況下,是否具備降級的能力。我們通過外層的 API 網關去做降級和和靜態資源的獲取,通過這種方式,如果 Serverless 平臺或者 Knative 這一層出了問題,用戶可以一鍵切到已經準備好的靜態資源中,不至於讓業務產生異常。

 產品形態的思考

打造 Serverless 平臺還有很多必要的考慮。首先平臺構建形態方面,爲了滿足用戶的效率需求,我們支持了 FaaS 層平臺;爲了滿足業務複雜又多變的需求,我們支持了傳統工程的形態。

其中 FaaS 形態最主要的目的是讓我們的業務方,特別是前端開發者,可以完全在 Web 瀏覽器上編碼、發佈,也就是說他只要身邊有一臺電腦,通過瀏覽器就可以隨時隨地完成他的業務目標,不需要安裝一些開發環境。除了這種方式以外,考慮傳統使用者的訴求,我們也支持集成到 VS Code 中,同時還支持最傳統的通過命令行直接構建 FaaS 的方式,當前我們支持的還只是 Node.js,這個是屬於我們用得比較多的技術棧。

對於傳統工程形態這種方式,Knative 當前是支持的,這種方式最主要的作用是,用戶不需要學習新知識就可以直接使用 Serverless,可以像以前一樣開發代碼,同時它的運營實施比較靈活。一些啓動過程很慢的業務,也完全可以採用傳統工程形態去做,這樣不至於說這類業務沒有辦法在這個平臺上運行。

所以說,我們做了這兩種產品形態來滿足業務方在不同狀況下的使用需求。

 數據路徑的適配

因爲 Knative 網關只能通過子域名的方式去做業務區分,而我們傳統業務,特別是現有的很多線上業務,往往是使用 Host+Path 這種方式去做區分的。爲了滿足用戶的這種使用習慣,我們當然可以修改 Knative 層的開源實現,但是開源又是在不斷迭代的,我們考慮再三,做了一些框架結構,通過外置的一層 API 網關去做具體的 Host+Path 的區分,然後轉換成 Knative 所支持的子域名方式去做應用區分。

同時,我們引入外層的 API 網關還有另一個好處,當 Knative 這一層出問題時,我們可以通過這一層網關去做灰度降級,來保證業務的穩定性。

當然,加一層外置網關也會導致數據鏈路變長,它從外層 API 網關,到內層 Knative 網關,再到 Activator 組件,甚至到 QueueProxy,最後纔到業務容器。這樣會導致 QPS 比較低,這方面後文我們會給出輕舟團隊具體的解決辦法。

 平臺能力的集成

平臺需要的日誌、監控告警、BaaS 等能力,由於輕舟平臺已有現成的封裝,Serverless 平臺直接集成。

此外,爲了適應 Serverless 這種業務場景,我們額外開發了一個預警的組件,去模擬前端業務方發佈一個業務,發佈之後把它給部署到 Serverless 平臺上,然後檢查它能否很好地完成擴縮容。

Knative 的實踐踩坑和優化

接下來分享在打造輕舟 Serverless 平臺的過程中,我們對選型的 Knative 這個開源組件所做的事情,主要分爲三個部分,第一部分是我們在數據面上做了哪些東西,第二部分是我們在控制面做了哪些優化,第三部分是說使用了 Knative 組件,我們遇到了哪些問題,又是如何解決的。

 數據面的優化

我們在數據面做的主要工作是數據鏈路調優。上文也提到 Knative 整個數據鏈路比較長,我們通過對 Knative 的壓測,確定 Knative 的性能有很大的問題。我們通過以下的 5 個步驟來做優化:

通過這 5 個步驟,我們滿足了不同的業務方的需求。一般來講,做完 1 和 2 能滿足差不多滿足一半的業務需求,做完 3 和 4 基本上能滿足絕大部分需求,第 5 步是滿足一些特殊的業務場景的需求。

 控制面的優化

控制面上我們主要解決了 Knative ksvc Ready 時間變長的問題。Knative ksvc Ready 時間變長有兩個原因。第一個原因是 Serverless Knative 網關,我們採用的是輕舟的 API 網關,它的控制面是依賴於 Pilot,而我們的業務集羣又是和服務網格在一起運行的,在默認情況下,Knative 的 Pilot 能感知到服務網格的 VS、DR、SE 這些資源,這就導致了它去做一些無關的資源運算,從而 Knative ksvc Ready 時間變長。

第二原因,Knative 有一個組件叫做 network-istio,這個組件需要對整個數據路徑去做健康檢查,只有在健康檢查成功以後它才把 ksvc 置成 Ready 狀態。但健康檢查有一個特點,它是指數級別回退的,這就導致瞭如果 5 秒內它沒有檢查通過,它就只能在 10 秒內才能發現這個東西是健康的;如果它在 10 秒內還沒有解決這個問題,檢查出來業務已經 Ready 了,它就只能在 20 秒內才能發現業務已經 Ready,這就導致 ksvc Ready 時間變得更長。

我們解決的辦法有兩種,第一種是針對於第一個問題,Knative 網關它只 care 自己的 Namespace 級別的資源,去做一些資源隔離,它不 care 同一個集羣內的服務網格的相關的其他資源。

第二種就是我們調整了 network-istio 健康檢查回退機制,調整成前 20 秒內每秒鐘檢查一次,20 秒以後才進行指數級回退,通過這種方法防止 ksvc Ready 時間慢的問題。

 遇到的困難和解法

Knative 層我們主要遇到了如下的困難:

我們的解法如下:

當然我們在一開始踩這個坑的時候,Knative 社區還沒有解決這些問題,後面我們解決完問題以後,發現社區也已經解決了。所以說我們也是通過檢驗了,因爲我們是儘量地少動 Knative 本身的代碼,也是通過這種升級的方式來解決的。

    收益    

目前輕舟 Serverless 平臺在網易內部已經上線了大概 200 多個前端應用,當然在 2020 年的 Q4 我們也 Release 了一個商業化版本滿足對外的需求。我們做完這個事情以後,前端人員的體驗是怎麼樣的呢?

首先,我們從前端人員那邊收集到的數據,他們以前去部署環境,新員工可能要兩週左右,老員工也要三天左右,有了 Serverless 平臺,整個部署時間統一降低到三分鐘內搞定。

其次,因爲 Serverless 平臺的一些封裝使得了前端人員不再需要關注後端資源,所以說他們從業務選型上,可以考慮一些服務端渲染的技術來提升業務的首屏體驗。

再次,從趨勢上來說,免去運維的困擾更加符合前端趨勢,這讓前端人員可以輕鬆地去開發 BFF 層的一些需求,甚至可以支撐他們往全棧工程師去過渡,通過這些支持給前端提供一個更大的靈活度。

未來展望

展望未來,我們需要在網易公司內部業務場景繼續打磨輕舟 Serverless 平臺,讓它變得更加穩定,功能更加強大,主要聚焦三個方面:

首先我們會提升 Serverless 平臺的產品能力,考慮使用 Knative 的 Eventing 組件,去融合我們的輕舟中間件、對象存儲這些底層設施的資源,來滿足業務更加多變的需求。

其次是我們 Serverless 平臺上線以後,前段時間業務方反饋它整個的調試化過程的效率降低了,所以我們打算提供一些本地的調試套件去解決調試的困擾。

最後,我們會緊跟着 Knative 社區,關注 Knative FaaS Kn 的實現,同時也考慮去對接公有云的一些 Serverless Framwork,一些 API 規範標準,這樣將來如果業務方有需求,它完全可以無感地從私有云平臺上遷到公有云平臺上,所以我們打算做這麼一層封裝。

 作者簡介

劉勤龍,網易數帆輕舟事業部資深開發工程師,雲原生社區 Knative SIG 發起者,8 年服務端開發和優化經驗,負責網易輕舟四層負載均衡數據面設計,參與輕舟服務網格性能優化,目前專注於輕舟雲原生 Serverless 平臺的開發和優化工作,支撐 Serverless 在網易雲音樂、網易嚴選、網易傳媒的落地工作。主要關注 Kubernetes、Istio、Knative、Cilium 等技術領域。

傅軼,網易數帆輕舟事業部高級研發工程師,目前專注網易容器和微服務平臺研發,致力於網易內部容器技術及其生態體系建設,對 Kubernetes、Serverless、日誌服務有深入研究,具有豐富的雲原生分佈式架構設計開發經驗與項目實踐。

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