2014年6月28日,阿里即將赴美上市的這一年,西溪園區(qū)的一個茶水間里,28個人日夜趕工了三個月后,上線了一個閑置交易平臺——閑魚。今年5月份,在阿里巴巴的年報中對外公布了閑魚的數(shù)據(jù):GMV2000億元,同比增長100%,每天在線賣家數(shù)超過3000萬人。 閑魚已經(jīng)從一個茶水間創(chuàng)業(yè)的內(nèi)部小產(chǎn)品,變成了在C2C領(lǐng)域的領(lǐng)先平臺。
據(jù)艾媒數(shù)據(jù)估計,2020年全年的二手物品交易市場的規(guī)模將達到萬億以上。線上交易的繁榮亟需技術(shù)架構(gòu)做相應的調(diào)整、演進才能支撐業(yè)務(wù)的快速發(fā)展。閑魚對于阿里而言,有比營收更重要的意義,那就是創(chuàng)新。創(chuàng)新不只體現(xiàn)在業(yè)務(wù)模式上,閑魚的技術(shù)架構(gòu)也在探索最新的方向——向Flutter化、云原生/Serverless化發(fā)展。
2009年,從浙江大學畢業(yè)的王樹彬,在UT斯康達工作了三年后,加入阿里巴巴。2017年,王樹彬首次將Flutter引入到閑魚,從2018年開始,王樹彬帶領(lǐng)閑魚技術(shù)團隊在下一盤更大的棋:布局Serverless。顛覆性創(chuàng)新往往是從邊緣性的地方出現(xiàn),而向云原生化/Serverless化升級,對于閑魚是一條全新的路,但趟出了這條路,對于很多做線上交易的公司有著巨大的借鑒意義。
今天,我們就一起聊聊閑魚的云原生故事。
1、為什么要做Serverless?
閑魚是依托阿里電商體系的前臺型業(yè)務(wù),有非常獨特的業(yè)務(wù)特點和用戶訴求,在底層依托阿里系統(tǒng)的同時,在表現(xiàn)層和業(yè)務(wù)層需要探索適合閑魚的、并且更加快速靈活的研發(fā)體系。
按照傳統(tǒng)的開發(fā)方式,閑魚原有的 IT 系統(tǒng)會面臨很多痛點,比如:
客戶端交互層、服務(wù)端業(yè)務(wù)膠水層、領(lǐng)域?qū)舆吔鐒澐植磺逦@就導致很小的業(yè)務(wù)需求就需要整條鏈路的同學參與,協(xié)同成本高,開發(fā)調(diào)試周期長。
服務(wù)端存在巨型應用,研發(fā)耦合、發(fā)布耦合、運維耦合嚴重,甚至系統(tǒng)穩(wěn)定性也受到很大挑戰(zhàn),單個業(yè)務(wù)問題往往會影響整個應用。
運維成本極高。為了保障業(yè)務(wù)的穩(wěn)定性和可用性,阿里對每一個應用上線都有相應的規(guī)范和規(guī)則。哪怕是一個很小的內(nèi)部應用,一天可能只有一兩個訪問量,上線也需要遵守既有的規(guī)范,這勢必會消耗一些固定資源。單個應用消耗的資源可能很有限,但所有應用消耗的資源累積起來也是一個不小的數(shù)字。而對于巨型應用,由于影響面巨大,發(fā)布時要有更加嚴格的流程和步驟,一次發(fā)布至少要耗時6小時,導致運維成本極高。
Serverless 的出現(xiàn),一方面使云端一體化研發(fā)成為可能,很多小業(yè)務(wù)需求的協(xié)同成本可以大大降低。另一方面,Serverless 使業(yè)務(wù)膠水層的巨型應用,有了比微服務(wù)更加合理的拆分方式。
傳統(tǒng)巨型應用的成本(速度)、穩(wěn)定、質(zhì)量相互制約的瓶頸,可以用下面這個三角形來直觀的表示。
云原生/Serverless 這些新技術(shù)的出現(xiàn),可以使應用運維能力下沉,傳統(tǒng)巨型應用的成本(速度)、穩(wěn)定、質(zhì)量相互制約的瓶頸才有可能被打破。閑魚在落地新技術(shù)的過程中,先圍繞 Flutter 重點攻堅了 Flutter 混合工程體系、高性能組件庫。然后圍繞Serverless 重點攻堅云端一體化研發(fā)體系、服務(wù)端業(yè)務(wù)組裝層架構(gòu)體系。
閑魚客戶端基于 Flutter 進行架構(gòu)演進與創(chuàng)新,通過 Flutter 統(tǒng)一 Android 和 iOS 雙端提升研發(fā)效能之后,希望通過 Flutter+Serverless 解決各角色間存在的大量的協(xié)同問題,正是這些問題導致整體研發(fā)效率低,移動端離業(yè)務(wù)越來越遠,服務(wù)端沒有時間做底層領(lǐng)域沉淀。通過 Serverless 的引入,閑魚會明顯看到整體研發(fā)效率的提升。
2、一邊探索,一邊實踐
2018年,閑魚技術(shù)團隊開始探索 Serverless,整體分為四個階段:自建Dart Server、依托FaaS平臺、云端一體化、傳統(tǒng)巨型應用Serverless化。
2018年5月,以 Serverless 思路構(gòu)建了2s內(nèi)冷啟動的 Dart Server 應用框架,用于服務(wù)端業(yè)務(wù)膠水層的輕量化開發(fā)。
2018年底到2019年初,閑魚啟動與Gaia團隊協(xié)同共建基于Gaia平臺的Dart 運行時,并上線了部分業(yè)務(wù)。注:Gaia是基于阿里云的面向淘寶業(yè)務(wù)特點封裝的、用于淘寶業(yè)務(wù)的FaaS平臺。
2019年,閑魚基于Gaia的Dart Runtime標準化,探索 Flutter+FaaS 云端編程一體化,領(lǐng)域接口元數(shù)據(jù)化,最終誕生了 Nexus 等膠水層業(yè)務(wù)框架,并在閑魚20多個業(yè)務(wù)落地。
2020年,閑魚開始進行云端的工程&工具一體化,目標是實現(xiàn)一個工程、多端部署?,F(xiàn)在,王樹彬正帶著技術(shù)團隊攻堅業(yè)務(wù)膠水層的傳統(tǒng)巨型應用治理,使傳統(tǒng)應用向Serverless化遷移,“最快3個月,最晚6個月,我們就會交出一份漂亮的答卷。”
具體來看過去這兩年的時間里,閑魚在Serverless上的實踐成果,主要分為5個方面:
云端編程模型一體化框架(Nexus API)
這個框架的目標是使Flutter、FaaS的編程模型統(tǒng)一,打通UI、交互、數(shù)據(jù)、邏輯。王樹彬提到,一開始說要做Flutter + FaaS一體化的時候,我們對“一體化“這三個字的認知相對比較模糊,只是知道端側(cè)的同學可以用 Dart 這門語言來寫FaaS函數(shù),這其實還停留在語言上的一體化。對于FaaS所能做的事,也僅僅停留在前端實施已久的BFF層面。
我們花了很長時間來討論,基于Dart生態(tài)下,前端的 FaaS 在研發(fā)交付其實并不高效,研發(fā)階段主要面臨的問題是:
編程語言不統(tǒng)一:編程語言本身雖然不是最大的障礙,但這也確實給前端開發(fā)者增加不少門檻,而且更重要的是語言背后的生態(tài)、環(huán)境與體系更是一道高高的墻。
開發(fā)模式與架構(gòu)割裂,環(huán)境復雜:端側(cè)一個工程,F(xiàn)aaS側(cè)也有一個獨立的工程,它們背后有自己的一套構(gòu)建、調(diào)試、集成/發(fā)布的工具鏈;除此之外,F(xiàn)aaS 還有自己配套的環(huán)境、Runtime、框架作為支撐。開發(fā)者面對這樣復雜的 FaaS 研發(fā)環(huán)境與雙重的研發(fā)工作流是無法做到高效交付的。
最終,我們對一體化有了一個比較清晰的共識,那就是要實現(xiàn)兩個核心的一體化:
語言一體化
開發(fā)模式與架構(gòu)一體化
編程語言的一體化可以為開發(fā)者提供一種熟悉的技術(shù)棧,開發(fā)模式與架構(gòu)一體化能幫助開發(fā)者解決工程割裂以及背后復雜的 FaaS 本地運行環(huán)境問題,帶來與原研發(fā)模式基本一致的研發(fā)體驗。
通過這兩個層面的一體化,最終達到開發(fā) Flutter 頁面和開發(fā) FaaS 無明顯Gap。例如,閑魚客戶端Flutter以往是用Redux框架開發(fā),在Nexus API框架下,可以使Redux與FaaS調(diào)用無縫集成。
CLI 開發(fā)工具標準化
云端一體化開發(fā)時,通過 CLI(命令行工具)屏蔽 FaaS 開發(fā)的一些細節(jié),使客戶端開發(fā) FaaS 時的開發(fā)體驗標準化,符合客戶端同學的本地開發(fā)習慣。
基礎(chǔ)服務(wù) BaaS 化
過去兩年,我們在逐漸簡化基礎(chǔ)服務(wù)能力,如對象存儲、消息、搜索。同時,建設(shè)業(yè)務(wù)領(lǐng)域?qū)臃?wù)的元數(shù)據(jù)中心,這些簡化的基礎(chǔ)服務(wù)能力,再加上已有的業(yè)務(wù)領(lǐng)域?qū)臃?wù),使客戶端同學可以快速組裝業(yè)務(wù)。
云端工程一體化
閑魚在成功引入 Flutter 后,在端側(cè)形成了以 Flutter 為主、H5為輔的跨端研發(fā)體系,使傳統(tǒng)的 Android 和 iOS 的兩端研發(fā),合并成一端。在端上的生產(chǎn)力得到釋放時,我們發(fā)現(xiàn)端的同學有機會向下層走一點,使服務(wù)端面向簡單的數(shù)據(jù)組裝邏輯,由端的同學一人閉環(huán)完成,這套模式尤其適用于一些小業(yè)務(wù)的需求。類似的嘗試業(yè)界其實早就有了,例如 GraphQL 框架的流行,前端的BFF層的形成。但有了Serverless,服務(wù)端輕量代碼的開發(fā)可以極大地簡化,所以閑魚選擇這個時機推進云端一體化。
云端一體化涉及到云端編程框架、工具鏈、工程體系、基礎(chǔ)服務(wù)BaaS化、領(lǐng)域服務(wù)下沉,同時,也涉及人員上的組織保障、分工重塑、安全生產(chǎn)培訓等。
傳統(tǒng)巨型應用的Serverless化改造
Serverless不是銀彈,但與業(yè)務(wù)膠水層的特點很匹配,非常適用于解決膠水層的傳統(tǒng)巨型應用的拆分,這也是閑魚正在攻堅的下一個難題。
3、難題與破局
閑魚落地 Serverless 的過程中并非一帆風順。王樹彬提到,在Serverless云端一體化過程中,遇到了一些技術(shù)難題,比如Java富客戶端的異構(gòu)語言訪問、開放環(huán)境如何統(tǒng)一以及客戶端同學對領(lǐng)域接口不熟悉等問題。
在閑魚的Java系統(tǒng)中,存在大量的Java富客戶端應用。針對Java富客戶端的異構(gòu)語言訪問,閑魚以Sidecar的模式,建立Java的Proxy來解決這類問題。
緊接著,為了讓開發(fā)環(huán)境統(tǒng)一,閑魚開發(fā)了自己的CLI工具(GCLI)。GCLI是一個基于支撐 FaaS 研發(fā)生命周期的命令行工具,它定義了閑魚 FaaS 開發(fā)閉環(huán),統(tǒng)一了 FaaS 的研發(fā)環(huán)境,是提升FaaS研發(fā)效率的利器。GCLI 將研發(fā)閉環(huán)拆解成適合Serverless 研發(fā)習慣的開發(fā)指令。為了讓用戶繼承其研發(fā)習慣和工具,閑魚優(yōu)先選擇了基于本地的開發(fā)方案;使用Docker技術(shù)統(tǒng)一開發(fā)環(huán)境,在 Dcoker 內(nèi)聲明Dart FaaS技術(shù)棧依賴的運行環(huán)境(軟件+配置)。借助容器技術(shù),F(xiàn)aaS 的軟件環(huán)境可以移植到任何支持Linux運行的操作系統(tǒng),從而解決了環(huán)境統(tǒng)一的問題;GCLI 通過 FaaS Open API 實現(xiàn)本地和函數(shù)平臺實現(xiàn)互操作,形成完整的研發(fā)閉環(huán)。
最后,針對客戶端同學對領(lǐng)域接口不熟悉的問題,閑魚開發(fā)了領(lǐng)域?qū)拥脑獢?shù)據(jù)中心。
云端一體化重塑了傳統(tǒng)的云、端邊界,減少了協(xié)同,也給人員的分工帶來了更大的靈活性,技術(shù)上的研發(fā)效率、研發(fā)質(zhì)量也明顯提升。而這些改變對于業(yè)務(wù)帶來的直接好處,就是可以讓業(yè)務(wù)有更快的迭代速度、更快地適應市場和用戶需求的變化。
云端一體化目前應用在閑魚的重交互場景以及輕量業(yè)務(wù)場景中,其帶來的技術(shù)效率、質(zhì)量提升更容易以量化的數(shù)據(jù)形式呈現(xiàn)。例如,以典型的中大型業(yè)務(wù)需求抽樣統(tǒng)計,開發(fā)人日降低了30%,千行代碼Bug率降低了20%。如果以零散需求統(tǒng)計,數(shù)據(jù)提升會更加明顯。以往的小需求由于多個同學參與,往往排期需要幾周,而云端一體化后,資源的靈活性明顯提高,使需求響應速度大大提升。
“但是,還有一些問題沒有解決”,王樹彬說,在 Serverless 的巨型應用拆分方面,閑魚遇到的問題更加嚴峻,比如:
微服務(wù)和 Serverless 的選型
在 Functions 之間代碼復用
對函數(shù)的依賴做統(tǒng)一升級
這幾個問題的方案,閑魚還在逐步驗證中,待經(jīng)驗成熟后再向大家詳細分享,歡迎持續(xù)關(guān)注。
4、借鑒與思考
什么樣的公司、應用或場景應該選用 Serverless 的架構(gòu)模式?目前沒有具體的定義,關(guān)鍵在于想清楚。想清楚,就需要平衡好收益、成本、效率和應對市場的能力。其中,成本是企業(yè)更為關(guān)注的因素,這其中包括基礎(chǔ)設(shè)施搭建的成本、運維成本、擴容成本、安全成本等。
Netflix是落地 Serverless 的一個成功的典型,Netflix 在產(chǎn)品設(shè)計上一直都有創(chuàng)新的基因,除了不間斷的 A/B 測試之外,每周都會發(fā)布很多新功能。為了確保這樣高強度的工作成果,就需要一個 API 服務(wù)平臺來幫助客戶端工程師快速而有效地將更改的需求部署到服務(wù)層。FaaS 通過把那些與服務(wù)相關(guān)的所有平臺組件抽象為業(yè)務(wù)邏輯本身來實現(xiàn)這一目標,而 Serverless 模式能夠為Netflix提供一個平臺,即使沒有服務(wù)器和運營經(jīng)驗的工程師也可以開發(fā)高可用的服務(wù)。
采用 FaaS 模式,本質(zhì)上是對交易速度和可能性的定制化。有些應用程序的 FaaS 服務(wù)表現(xiàn)得很好——Netflix API 的情況就是如此,Netflix 運行的是相對統(tǒng)一的微服務(wù),只需要訪問和改變下游服務(wù)的數(shù)據(jù)。然而,如果服務(wù)需要定制化,例如需要改變服務(wù)平臺的各個組成部分,像 RPC、數(shù)據(jù)訪問、緩存、認證等,那么 FaaS 模式可能無法為這些服務(wù)提供足夠的靈活性。
自建 Serverless 平臺對企業(yè)IT人員的要求比較高,同時建設(shè)成本也很高。另外,實施Serverless 需要一個成熟的生態(tài)。絕大多數(shù)情況下,已經(jīng)上云的企業(yè)應該優(yōu)先考慮云廠商的Serverless產(chǎn)品,而沒有上云的企業(yè),需要考慮現(xiàn)有系統(tǒng)的生態(tài)情況是否能與云廠商的Serverless產(chǎn)品兼容。
對于 Serverless 產(chǎn)品的選型,應該綜合幾個方面來看:生態(tài)的成熟度,支持的開發(fā)語言,功能豐富度,收費標準等,關(guān)鍵是結(jié)合企業(yè)自身業(yè)務(wù)發(fā)展的需求。
5、關(guān)于未來
O'Reilly 曾對 Serverless 的應用情況進行了過一次調(diào)查,發(fā)現(xiàn)軟件行業(yè)的開發(fā)者關(guān)注和應用 Serverless 非常多,這在意料之中,但是金融和銀行業(yè)也在高度關(guān)注Serverless,原因之一是越來越多的金融科技初創(chuàng)企業(yè)的誕生,它們承擔了傳統(tǒng)基礎(chǔ)架構(gòu)的責任,并且以更開放的心態(tài),接納和擁抱 Serverless 。
對于拒絕 Serverless 的理由,60% 的受訪者表示是安全問題。因為很多行業(yè)對于 IT 環(huán)境的安全性要求很高,而采用任何新技術(shù)都可能會帶來安全風險。
此外,開發(fā)者另外一層顧慮主要是擔心被廠商綁定,這就導致具備一定規(guī)模的組織會基于開源方案,如 Knative,搭建自己的 Serverless 平臺。而一旦某個開源方案成為主流,云廠商就會主動去兼容開源標準并增大社區(qū)投入。
Serverless 除了對技術(shù)和業(yè)務(wù)產(chǎn)生影響外,對于企業(yè)組織架構(gòu)和技術(shù)人員也提出了新的要求。
首先,Serverless 改變了溝通結(jié)構(gòu)。按照康威定律,組織架構(gòu)需要適應新的溝通結(jié)構(gòu),才是最好的匹配。閑魚以前負責客戶端和服務(wù)端的同學是分開的,在全新的 Flutter+Serverless 的背景下,組織結(jié)構(gòu)也需要做相應的調(diào)整。經(jīng)過討論,閑魚最終決定按照業(yè)務(wù)線劃分,將客戶端、服務(wù)端的同學按業(yè)務(wù)線重新組合到一起。
其次,Serverless 使客戶端的同學有機會更多的了解業(yè)務(wù),這就要求客戶端同學更加具有業(yè)務(wù)敏感度。Serverless 促使客戶端同學擴大了技術(shù)邊界,也需要了解一定的服務(wù)端開發(fā)概念。
最后,Serverless 要求原有的服務(wù)端同學有更好的數(shù)據(jù)建模、領(lǐng)域建模能力,從而有助于底層接口復用度更好。
從最開始不被外界看好,甚至被調(diào)侃為“咸魚”,到如今實現(xiàn)了千萬DAU,盤活了一個萬億級市場,閑魚的出現(xiàn),無論是對前端的電商生態(tài),還是用戶在互聯(lián)網(wǎng)上的生活形式,都產(chǎn)生了重要的影響。
為了支撐起閑魚萬億的交易規(guī)模,王樹彬和技術(shù)團隊正在緊鑼密鼓地進行傳統(tǒng)巨型應用的 Serverless 化改造,“闖過了 Serverless 的這一關(guān),才是我比較滿意的狀態(tài)。”