
作者|陳仲寅(張挺)
出品|阿裡巴巴新零售淘系技術部
本文是阿裡巴巴前端技術專家-張挺,在 JSConf China 「中國開發者大會」上分享的《面向傳統,Serverless 進化之路》,主要講述阿裡集團内部逐漸遷移到 Serverless 體系的過程以及思考。
背景
自 GMTC 以來,國内各個公司在 Serverless 投入都有所變化,騰訊和阿裡雲都鉚足了勁在上面發力,提出了各自的解決方案,騰訊推出了 Serverless 2.0,以及幾天前阿裡雲推出的預留模式,都是對 Serverless 越來越重視的表現。
本文主要介紹兩部分,第一是阿裡在近期做的前端研發更新,為拓展前端的邊界和職能,嘗試做了一次和 Serverless 結合,第二是在這其中,我們嘗試對現有的體系做了思考,希望能将傳統應用快速遷移到 Serverless 體系,享受到 Serverless 紅利。
現狀
阿裡的 Node.js 應用非常多,1600+ 的數量讓維護和治理都變的很麻煩,每一次更新都要推行很久,這不管對架構開發還是平台治理都是不利的。
很多 Node.js 應用都是 BFF 應用,内部平台等,這些應用常年大多都處在負載低(10%以下),沒有流量的狀态,而且維護者大多處在離職或者不積極的狀态,一方面造成了資源浪費,另一方面也給治理造成了困難。
其次,在集團開發傳統應用,需要申請,整個研發流程比較長,需要業務了解預算和資源,牽扯到很多細節。
為此,我們開始了 前端研發更新 這個大項目。
整個前端研發模式更新的目的有兩個,一是為了“前端賦能”,二是為了“前端提效”。
所謂的“前端賦能”,是因為我們希望前端能夠打破現有的技術壁壘,朝着更底層,面向資料的地方去深入探索,在這之中可以從面向 UI,視圖本身變的更加了解業務,從更面全面的視角來了解現有的體系。
而“前端提效”,則是希望讓 Serverless,用更輕量化的方式進行業務研發,降低整個前端參與業務傳遞的門檻,同時,在開發期間,也能減少人力總成本,讓前端減負,業務小步快跑成為可能。
但是阿裡的 Serverless 之路非常困難,不像外界已經有成熟的體系,目前一些原因無法使用公有雲上開放的産品,阿裡雲也無法直接對内部提供服務,同時,内部的中間件在外部都沒有,都需要跨團隊來重建立設。
Node.js 基礎團隊的使命,就是為集團 Node.js 生态提供各種基礎能力,包括但不限于架構,中間件包等,而在 Serverless 體系中,我們要負責架構、工具鍊、運作時、釋出系統,同時也需要和周邊的網關,監控系統等對接。
收益
去年 10 月開始,我們開始進行調研 Serverless 以及了解相關知識,到現在為止,也已經取得了一定的階段性成果,将淘寶和飛豬兩道 BU 的導購鍊路整個遷移到了 Serverless 體系,并且承載了導購鍊路的千萬級流量。
同時,内部系統也進行了一定程度的 Serverless 更新嘗試,不管是重寫還是傳統應用遷移,我們都有了一定的沉澱。
我們最初的目的是希望能降低成本,按照網上 Serverless 的降低成本率能達到 90% 以上,不過導購業務比較特殊,流量比較大,不像那些需要彈性的應用,根據我們的測算,單程序下函數的性能非常不錯,但是由于大促要提前預留一些資源,整體機器成本隻降低到了平時的 70%,而在非大促期間,不需要預留這些資源,就能更低,降到 40% 以下。
現在都說 DevOPS,而 Serverless 最大的好處是減少運維,減少固定伺服器資源,不需要使用者關心排程等,同時也簡化了開發的代碼,專注了邏輯,晚上睡覺會更加的放心,不再擔心機器容量不足而報警。
另一邊,對于我們應用治理的人來說,之前會考慮各種版本碎片化的問題,node 的多版本,架構的多版本,以及啟動腳本、依賴等等問題,而使用 Serverless
之後,我們将這些都固化了,使用者也不關心這些,一切都變的簡單了,我們也隻需要治理運作時一個版本即可。
在業務前端方面,帶來的是挑戰和機遇,一方面,前端的工作量增大了,能幹的事情也變多了,成了一職多能的多面手,也更了解業務了,另一方面,傳統的後端可以從和前端溝通中解放出來,更專注于提供服務。前端從傳統的面向接口程式設計變成了面向服務程式設計,由于集團内都是 RPC 服務,在 RPC 釋出時會有固定的定義和文檔,在調用時有工具輔助生産代碼,大大簡化了調用鍊路。
在流程方面,原來需要在各個環境準備和調研,從一開始申請應用,申請預算,申請環境開始,需要了解各個方面的知識,和不同部門的人打交道,流程審批也很長,而現在隻需要在我們的統一研發平台上直接申請函數組,替代了原本的複雜流程,也提升了整個開發體驗。
同時在編碼中也不再考慮路由,MVC 的事情,這些在網關層配置就好,編寫代碼時會更關注邏輯,和之前的建構釋出不同的是,現在增加了雲端內建測試的步驟,由于函數和前端代碼一樣,是分版本的,也不擔心修改到線上的正常服務,在測試完畢後,隻需要将舊函數的 tag 指向新函數即可,這就完成了整個切流的過程,而一旦碰到問題,把 tag 切回去就行。
這就是我們前端研發模式更新的思考和收益,帶給我們的不僅僅是變化,更多的是流程、思維的革新。
思考
在研發模式更新過程中,我們針對現有的導購業務進行了重構,可以說是使用了 Serverless 的方式進行了重寫,而有一些老的應用,如果整體進行改造,這個成本會非常之大。
這個時候開發者就會有很常見的一個疑問:我原來的應用,怎麼遷移到 Serverless 體系?
而我們的回答是兩種:
- 使用 FaaS + Baas 的方式進行重構,代碼更精簡,就是需要改造成本
- 把整個傳統應用作為一個函數,雖然不夠優雅,但是能解決遷移的問題
把整個應用遷移到函數會有一些限制,會對代碼結構和模型做一些微調,以符合整個 Serverless 的結構,畢竟新的體系和傳統的代碼模型是有所差別的。
阿裡集團采用的是 FaaS + BaaS 的實作方式,而 FaaS 的整體概念和傳統的應用不太一樣。
在概念上,Serverless 比 FaaS 的外延要廣,FaaS 屬于 Serverless 的其中一種實作方式,主要解決的是使用者自定義的代碼邏輯如何做到 Serverless,也可以叫做 Serverless Compute,同時它也是事件驅動架構的一種。
而 CNCF Serverless 白皮書中也說到,Serverless Compute 是一種粒度更細的部署模型,通過一個或者多個 function,用于響應使用者的需求。可以說,粒度小,靈活性高是它的最大特性。
在代碼層面,為了讓使用者更好的了解,我們把傳統代碼的結構進行了分解,傳統的 MVC 類型的代碼,會分為幾層。
- HTTP 服務,原架構(koa/midway/egg…),Node.js 運作時,啟動腳本等,将會變為函數運作時,固化下來
- 原有的 HTTP Router,Web 中間件等,将會由 HTTP 網關承接
- 原有的 Controller,業務邏輯(調用遠端服務),繼續保留,變為函數代碼
- 原有的資料庫,消息隊列,RPC 調用等,都作為 BaaS 服務,使用者隻關心對應的服務,使用同一的 BaaS Client 進行調用
這樣分解過後,我們對新舊兩個體系的代碼結構有了進一步認識,可以開始嘗試修改部分代碼,變成真正的 Serverless。
遷移
傳統的應用,會暴露出一些對外的服務供外部調用,比如 HTTP,定時任務,RPC 服務等等,這些服務一般我們會單獨抽離目錄,并且和其他暴露的服務共享邏輯層代碼,我們也經常稱這些服務為“入口”。
在 Serverless(FaaS) 化的過程中,我們會根據目前部署平台的能力(比如阿裡雲 FC,騰訊 SCF 都會提供 HTTP 服務,定時任務,消息隊列等等),将這些入口代碼變為基于事件驅動的函數。
我們通過建構機制,在釋出時生成不同的包,在共享一份邏輯代碼的同時,部署到不同的環境,這個方案最大的優勢是複用了原有的邏輯部分,可以和傳統應用同步開發,而劣勢也有,就是包依賴混在一起,由于函數對包大小有限制,可能會造成依賴過大等問題。
HTTP 相對于其他的來說會複雜很多,會有很多限制,這個我們在講下遊方案的時候再說。
針對上面的情況,對下遊的資料調用我們也有相應的方案。我們将這些方案取了幾個名字,比如代理模式和網關模式。
▐ 代理模式
首先來看看代理模式。一個傳統的 Web 應用會分為 Router/Controller,以及邏輯層,在代理模式中,我們會保留傳統的應用,隻将原本的邏輯層部分遷移到了雲函數中,暴露出 HTTP 服務。
這樣的好處是代碼變的精簡,改動适中,也易于服務複用,缺點就是依舊會占用一個應用資源作為代理層。
而代理應用一般是通過 HTTP 用戶端代理來實作的隻是使用者體感上需要做一些額外的支援,讓開發者在體驗上感覺到是調用了遠端服務。
▐ 網關模式
第二種方式是網關模式,這個模式下,所有的代碼都會遷移到新的體系,在 Web 層簡單的時候比較适用。
該模式下,所有傳統的 Web Router 會遷移到 HTTP Gateway 上,原本的路由,會話、鑒權等能力都将被網關所控制,而函數本身不需要關心這些,隻需要關心資料即可。
業界現有的 FaaS 模型大多是這種結構,集團内也采用了這類結構去實踐。
在這種模式下,原有的能力會碰到一些問題,舉一些例子:
- 原有的 Web 中間件(koa middlware),會不知道如何處理,中間件大多是做請求流的攔截和消費,這個時候大多會拆成兩部分,一部分被網關所處理,另一部分,隻能交給函數本身,如果有共享的需求,也可以依賴子產品來完成
- 原有的會話維持,一部分平台會進行透傳 cookie,這個時候你依舊可以維持一個 sessionId,同時使用第三方來存儲資料,但是如果網關不做這塊,那麼就很麻煩了
- 請求對象和原有的不同,由于函數擷取的是 event,context 參數,或者原始的 request 對象,和現有的 koa 等架構不是很一緻,上面的方法不一定有,會導緻原有的代碼做出修改和挑戰
▐ 僞裝者模式
那麼有沒有不修改代碼的方案呢?我們嘗試在函數外部進行代碼包裹和資料模拟,讓應用整個跑在函數之上,以一種 “微應用” 的方式繼續存在。
我們把原有的 Web Server(midway/egg),啟動起來,在運作時中通過一個固定的端口轉發,把 FaaS 的請求參數包裹成 HTTP Request 對象,而在出口處,也将 HTTP Response 包裹為函數能讀懂的形式,通過這樣續命的方式來延續傳統應用。而由于阿裡雲上的容器隻讀不能寫,目前還無法直接用這種模式。
這種方式需要調整的是,架構需要使用單程序模型(機器配置,輕量化的要求),應用需要無狀态(函數機制決定),以及沒有長連接配接等高消耗的操作。
總結
關于 Serverless 的問題還有很多,本文也隻是介紹了其中一部分内容,從阿裡目前的狀況講起,分享了從去年到今年的研發模式更新實踐,也介紹了在這其中我們的一些思考,傳統應用遷移到 FaaS 體系下的方式。後續的整套方案也會在經過雙十一的洗禮,大流量的考驗後,開放給大家。
One More Thing
淘系技術部依托淘系豐富的業務形态和海量的使用者資料,我們持續以技術驅動産品和商業創新,不斷探索和衍生颠覆型網際網路新技術,以更加智能、友好、普惠的科技深度重塑産業和使用者體驗,打造新商業。我們不斷吸引使用者增長、機器學習、視覺算法、音視訊通信、數字媒體、移動技術、端側智能等領域全球頂尖專業人才加入,讓科技引領面向未來的商業創新和進步。
請投遞履歷至郵箱:[email protected]
掃描下方二維碼,了解雙十一前網際網路人的一天
▼
更多技術幹貨,關注「淘系技術」微信公衆号~