天天看點

從無到有,閑魚Flutter一體化演進之路

作者:閑魚技術-蘭昊

前言

Flutter一體化研發模式在閑魚落地探索已有半年多了,前面也有多篇文章已經分享過階段性成果,今天我給大家以總的視角來分享下在這個過程中閑魚探索出來的一條路。

業務痛點

時間回到2019年8月。在那之前閑魚上每年會有不少創新型交易模式在做探索,但是交易鍊路代碼年久失修,維護成本很高,無法快速支撐到業務。例如下圖所示:

  • 所有引起金額變化的操作全部都在雲端各做一遍,買賣家訂單狀态判斷以及操作訂單的邏輯也全部都在端上。這樣每次新增交易類型,就會進一步增加端上狀态機的邏輯複雜度。
  • 一個下單頁面需要發出5次網絡請求才能拿到全部的渲染資訊,因為分屬不同領域,是以沒有一個服務端同學願意來包成一個接口。
從無到有,閑魚Flutter一體化演進之路

是以那時候想到嘗試用Flutter一體化的方式來重構交易鍊路,進而在研發上提速,以更好地支撐到創新型業務。

演進過程

整個的演進過程都是圍繞着如何來降低用戶端同學做一體化的成本,對整個研發進行提速,并且解決業務開發過程中的痛點。

通信一體

在下單這個場景,我們設計了如下的通信方式。将每一次的端上改動和目前資料都以request的形式發送給服務端,由服務端算出在該操作下新的價格應該是多少,并以response傳回給用戶端。雙方之間的一紙約定僅僅是靠一個Json。這種情況下,服務端的代碼和用戶端的代碼寫起來,是明顯有不同的目的性的。即我需要知道目前是在寫用戶端代碼還是寫服務端(FaaS)的代碼,然後按照之前的Json結構約定去拼出對方想要的資料結構。

從無到有,閑魚Flutter一體化演進之路

但是,我們希望用戶端同學去寫FaaS層的代碼時盡量不要有明顯的感覺。想到FaaS裡實際上封的是一個個函數,例如用戶端去調增加購買商品數量(僅針對玩家的寶貝),傳回值是全新的state資料,包括價格。那麼其實端上也有一些操作是可以了解為一個個函數,例如彈出一個toast(顯示庫存不足),亦或者是打開一個指定頁面或者喚起收銀台。将雙端的能力函數化後,可以設計出如下圖所示的通信方式。

從無到有,閑魚Flutter一體化演進之路

在這種通信方式理念下,我們設計了一套橫跨FaaS和用戶端的架構用來處理這層通信協定,屏蔽了網絡層具體的Json格式,并且雙端注冊函數的方法以及發出Action的調用方式都是一樣的,讓開發者無感覺調用的函數具體是在哪裡。下圖是一個代碼示例:

從無到有,閑魚Flutter一體化演進之路

程式設計模型一體

在屏蔽了具體通信協定降低通信成本之後,接下來要考慮新的程式設計模型應該如何設計。用戶端同學寫代碼經曆了MVC、MVP、MVVM時代,随着Flutter起來,因為其與Native完全不同的渲染方式,使得Flux的理念得以落地。Flux定義了一套單向資料流的原則,在Flutter一體化下,我們基于前後一體的整體考慮,設計了如下的一套新的程式設計模型。總共包含3個子產品:Render、Converter、Model。其中隻有Render部分在端上,頁面上的渲染資料全部來自FaaS層轉好的ViewModel(State)。當界面上有互動發生要改變State時,就将事件(Event)發出去,最後路由到Model層來處理,Model層根據這個事件可能會去從後端領域裡拉下原始業務資料,然後由架構将資料再交給Converter去轉成渲染所需要的State。通過這樣的方式以前後一體的思路來組織代碼和子產品化代碼。這套設計也得益于前面的工作将通信的成本降低。

從無到有,閑魚Flutter一體化演進之路

前後端分工

前面的一系列工作降低了用戶端同學寫FaaS代碼的複雜度,那麼新的生産關系得以落地和推廣。除了在交易鍊路,我們還在其他一些業務逐漸落地,慢慢地摸索出來了新的一套前後端同學的工作劃分。其中FaaS那層,我管它叫做SFC(Serverless For Client)層,裡面主要負責的還是面向使用者的功能,以支援多變的功能為主。這一層主要負責聚合、裁剪和結構各領域資料,服務于用戶端本身使用者那一層。而服務端同學會更加專注做好領域建設。

從無到有,閑魚Flutter一體化演進之路

工程一體

對于端側開發同學來說,我要開發FaaS代碼和Flutter代碼時需要同時打開兩個IDE來回切換,這也是一個很麻煩的事情,尤其是對State有修改時。基于此,我們做了工程一體的工作,将FaaS業務代碼和Flutter業務代碼放到一個工程目錄下,且都單向依賴通用代碼(例如State和工具方法),Flutter主工程再以git依賴的方式将工程引到工程裡。最後在編譯和部署時,編譯工具分别選擇對應目錄下的代碼進行操作,進而達到了一開始的目的。

從無到有,閑魚Flutter一體化演進之路

成本

通過在通信層、程式設計模型、學習領域和中間件知識、工程組織等方式,可以大大降低用戶端同學寫FaaS層代碼的成本。相比之前用Flutter+服務端的研發模式,一體化的研發模式抹掉了前後端接口約定、mock資料開發、編寫前後端重複代碼、前後端聯調、定位問題時前後端轉交bug、遇到問題前後端溝通修改接口協定等環節。主要都是協作溝通的成本。随之而來的問題是,用戶端同學需要學習業務領域接口,熟悉各個接口的QPS、RT、降級政策,并做好業務整體技術方案的設計。但是這個成本隻在一開始的時候存在,随着熟練度的提升,這塊成本是可以逐漸趨于0的。

從無到有,閑魚Flutter一體化演進之路

提速效果

當我們把交易鍊路的架構更新為一體化的架構後,承接了今年的兩個創新型業務需求,做評審和開發時,都僅需要一位用戶端同學參加,并且隻花了半天不到的時間就完成全部開發了,這對新業務上線來講大大縮短了上線時間。即使有使用者層的bug存在,也隻要一個人來看,因為代碼都是他一個人寫的,他能快速定位到bug的具體位置。

未來

未來我希望用戶端這套新的研發模式能夠在更多的業務場景下落地,去發現更多的問題,讓整個一套基礎建設更加完善,不斷完善出更好的AliFlutter,最後再反哺業務為業務帶來更多價值。

從無到有,閑魚Flutter一體化演進之路