大數據

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

作者:閒魚技術-蘭昊

前言

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

業務痛點

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

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


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

演進過程

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

通信一體

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

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

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

編程模型一體

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

前後端分工

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

工程一體

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

成本

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

提速效果

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

未來

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

Leave a Reply

Your email address will not be published. Required fields are marked *