導讀
由于網約車業務本身的復雜性以及我們垂直式的領域化架構約束,網約車服務端技術團隊在對端渲染業務需求的迭代過程中,碰到了一系列的問題,影響了研發效率。本文從這些具體問題入手,分析產生的原因,介紹我們的解決思路和方案,以及方案的建設落地過程。
1. 服務端架構演進回顧
過去幾年,滴滴網約車為了滿足不同用戶的個性化出行需求,逐步推出了越來越豐富的品類和功能。隨著品類功能的不斷增加,我們系統的復雜度也越來越高,為了應對這一挑戰,網約車服務端技術團隊構建了一個「出行平臺」,內部又稱灣流平臺。灣流平臺的演進主要經過了以下幾個階段。
灣流平臺1.0(2017-2018)
在1.0階段,滴滴網約車的主要業務重心是豐富品類,為用戶提供更多選擇,其中包括專車、豪華車、優享等。在這個階段,灣流平臺還是一個單體服務,主要面臨的挑戰是如何快速新增品類并支持多品類之間的差異化開發。
為了應對這些挑戰,我們引入了配置化和插件化。配置化使得新增品類可以快速上線并進行復用,提高開發效率。插件化則能夠隔離不同品類之間的差異邏輯,確保各品類的獨立性和靈活性
灣流平臺2.0(2018-2020)
在2.0階段,隨著品類的不斷豐富和個性化功能的增加,開發團隊也不斷壯大,系統規模逐漸龐大,但日常的迭代效率和穩定性出現了明顯下降。為了解決這些問題,我們從兩個方向對灣流平臺進行了改造。
首先,按照領域驅動設計(DDD)的思路,對單體服務進行了拆分,降低整體系統的復雜度,同時也解決了團隊成員并行開發導致的上線沖突和排隊的問題,提高了開發效率。
其次,在領域服務內部,我們進行了功能的聚合和抽象,通過將具有相似功能的業務進行聚合,并對其進行抽象,可以避免功能的重復開發,進一步提高了開發效率和代碼的可維護性。
灣流平臺3.0(2020-至今)
在3.0階段,我們開發了一套名為DuKang的業務框架,它將API的業務邏輯分為兩個層次。首先是流程層,用于串接狀態流轉,提供了通用的流程實現,不同的品類可以根據自身需求定制自己的流程,以滿足差異化的業務要求。
其次是能力組件層,負責完成各個垂類功能。組件內使用策略模式實現不同的行為,例如播單組件內部提供了延遲播單、實時播單等不同方式,不同的品類可以根據自己的需求選擇適合自己的方式。同時,組件也支持插件機制,可以讓品類注入獨有的模式。
通過Dukang框架,我們能夠有效約束各服務系統的實現,保持統一的規范,讓不同的領域服務可以復用能力組件,提高開發效率和代碼的復用性。
灣流平臺詳細的建設思路,可以參考之前的文章「滴滴出行平臺業務架構演進」,系統的架構簡單示例如下:
2. 新問題和挑戰
在討論新問題挑戰之前,我們先統一一些基本概念。
頁面:指用戶在終端上看到的整體區域,包含各種UI控件,例如打開app看到的乘客首頁、司機接單后趕來的等待接駕頁等。
組件:頁面中獨立展示的功能區塊,通常具有特定的業務屬性,例如下圖的小助手組件,主要用于展示當前場景下的一些重要業務提示和部分營銷活動。
模板:組件內的不同UI展示樣式,依賴于組件的定義和存在。
功能:表示一些具體的業務場景,例如保障車隊功能、自選車功能等。
數據源:提供組件渲染數據的后端服務接口。
在灣流平臺的持續建設過程中,渲染類需求的迭代效率始終上不去,經過進一步的深入分析,我們發現雖然領域服務能夠通過能力層實現功能邏輯的復用,但在做對端的渲染邏輯時出現了一些問題。不同位置的組件是由不同領域服務負責的,而這些領域服務各自有自己的渲染規范,因此,同一個功能想要在不同組件上進行展示時,就需要按照這些組件的渲染規范進行適配,例如有的組件要求直接通過接口返回渲染數據,而有些則要求在平臺上進行數據配置,這就導致一個功能在渲染對接上需要花費大量成本。同時,除了服務端系統內部的問題外,還有一些外部溝通協作、數據開發等挑戰。
下圖是當前系統內渲染處理現狀,具體的問題可以結合下圖進行討論。
多端問題
滴滴涵蓋了多個終端,包括Android、iOS和小程序等。由于我們劃分了不同的領域服務,每個領域服務都需要直接向終端提供相關展示數據,例如,售賣領域服務提供首頁相關數據,交易撮合領域服務提供等待應答頁的相關數據等。然而,這就導致了所有領域服務需要同時與所有終端進行對接,增加了溝通和協作的成本,影響迭代效率。
同時,網約車產品在大多數情況下要求多終端的體驗保持一致,然而,由于各端獨立開發和實現,又沒有地方統一進行管控,導致不一致的問題經常出現。例如,相同的標簽展示內容在長度超過限制時,iOS會截斷展示,而Android則采用跑馬燈展示等。多端實現不一致同樣也會影響我們的迭代效率,例如當產品希望對線上展示內容進行動態更換時,由于各端實現不同,導致動態化能力參差不齊,產品不得不針對各端進行差異化實現;還有同一個功能上線后,由于各端埋點實現不一致,收集的數據差異很大,每次都需要排查原因,甚至需要為不同端制定不同的數據分析策略。總之多端一致有利于產品體驗的提升,也能提升效率。
渲染邏輯管理困難
端上的組件位置是有限的,但是功能卻是不斷累積的,這導致在一個組件上需要根據不同的業務場景,展示不同的內容。經過統計,一些熱點組件上,擁有四五十種展示形式,上百種展示場景,面對如此復雜的情況,流量分發、優先級排序等管理十分復雜,而且所有的領域服務都需要重復實現這些復雜的邏輯,存在大量的重復工作。
功能跨流程接入難
有很多功能需要在全流程進行透出感知,比如拼車權益卡,在冒泡、等待應答、行程結束等很多階段都需要進行感知透出,這些階段的頁面由不同的領域服務處理,這些服務又歸屬于不同的團隊,在渲染接入上都有自己獨立的一套規范,導致拼車權益這樣一個功能接入跨流程的展示時,需要和不同的領域服務進行對接,而且需要進行逐一適配,接入成本很高。
數據看清難
各個組件的前后端埋點都是由不同團隊的開發同學進行自定義實現,缺乏統一的規范,下圖以拼車權益示例,可以看到,雖然各個位置都有埋點,但是大家的規范都不一樣,想要把這些數據串起來非常的困難,每次要看數據時,都需要數據產品單獨提需求進行開發實現,周期長,成本也很高。
以上就是我們在渲染上遇到的一系列問題,從上面的問題中可以看到,當前架構中最核心的問題,是系統各個層級間缺乏統一的渲染標準和規范,導致出現了很多的重復工作以及相互間信息打不通,主要可以歸納為這三個方面:
前端 & 后端:如何構建統一的組件認知,如何保證多端一致,如何減少多終端的協作成本。
后端:如何管理組件內復雜的功能展示邏輯,如何保證單一功能在全流程進行感知時,可以快速接入。
數據 & 前端 & 后端:如何建設統一的前后端數據規范,如何快速看清數據
3. 解決思路
解決這幾個問題的核心思路是進行標準化,通過不同層次的標準化配合,形成一套統一的跨端渲染平臺,詳細的方案思路如下所示。
組件標準化
組件標準化的思路是將我們頁面按功能模塊劃分成不同的組件,然后對這些組件進行UI規范和數據交互協議的統一,各端再根據統一的UI規范和交互協議進行組件的開發,同時在研發流程和研發模式上進行管控,讓各終端架構層面保持統一,盡可能地實現各端體驗的一致。針對多端實現一致的問題,Android和IOS也在探索跨端技術等方式,本文不對此展開。
有了這些多端統一的標準化組件之后,為了實現組件的復用以及減少終端和后端的溝通協作成本,我們建設了組件管理平臺和渲染網關。終端研發在管理平臺上對頁面進行配置,配置頁面上有哪些組件,這些組件通過什么樣的形式進行布局,組件的數據從哪來等等。有了這些配置之后,終端進行頁面渲染時,不再和各個組件下游服務交互,而是和渲染網關進行交互,渲染網關會根據終端傳入的頁面標識,在配置后臺拿到對應頁面的配置,代理請求下游服務,拿到各組件的數據統一進行下發。通過這樣的形式,可以有效地減少終端和各后端的溝通協作成本,同時這種標準化構建的組件,可以很方便地進行跨頁面的復用,提升迭代效率。
組件標準化除了對開發的收益之外,對產品業務同樣有很大的幫助,之前的產品迭代過程缺乏集中的沉淀,導致每次新功能需要做展示時,即使展示樣式跟之前的功能很類似,但由于沒有地方查閱,依然會找UI重新設計,研發重新開發實現。這也是導致一個組件上展示樣式爆炸式增長的主要原因。進行標準化之后,產品業務能夠在平臺上看到組件上當前所有的展示樣式,新功能可以選擇復用之前的模板,提升研發效率,同時也能集中對組件和模板進行管控,保持體驗的統一。
通過組件的標準化,整體的需求開發模式變成了如下的形式:
組件標準化建設過程,主要是渲染網關和組件管理平臺的建設,下面重點展開介紹下這兩部分的詳細方案:
渲染網關
渲染網關主要提供了兩個接口,layout接口和data接口,layout接口負責下發頁面的布局信息,包括頁面的一些靜態配置以及有哪些組件等信息,data接口則負責獲取組件渲染所需的數據。在實際運行過程中,考慮到性能和體驗的問題,在layout接口,會將核心組件的數據也進行返回,端上拿到layout的數據之后就能夠進行頁面的渲染,對于頁面上一些非核心可異步加載的組件,端上在拿到layout數據后,會再請求data接口獲取這些組件的數據。詳細的交互如下所示。
組件管理平臺
組件管理平臺主要是提供一個配置后臺,管理組件相關的內容,主要功能包括:
頁面管理,管理頁面標識和頁面組件關系等,可以在頁面管理里配置對應頁面包含哪些組件,并且可以進行一些組件實驗和灰度的配置,頁面也提供了版本管理的能力。
組件管理,對組件進行定義,并且對組件的模板進行管理,包括模板的UI規范、IDL交互協議等。
數據源管理,對下游數據源進行注冊、參數映射轉換等,組件在注冊到頁面時會配置對應的數據源,這樣網關就能根據配置直接代理請求拿到組件數據。
組件全景圖,為產品業務打造的組件視圖,業務和產品可以在上面追蹤到當前app有哪些頁面,每個頁面上是由哪些組件組成,每個組件上支持哪些展示樣式,也能看到有哪些功能會在這個組件下進行展示,這些功能的流量是如何分配的。
除了上面提到的核心管理能力外,管理平臺在開發體驗上也提供了一些能力,比如多版本功能,可以實現類似git的多分支并行配置開發測試;網關接口文檔和mock能力,由于所有組件交互協議是托管在平臺上的,平臺會基于此實現接口文檔和下游組件數據的mock功能,提高開發聯調效率。
功能接入標準化
功能接入標準化的主要思路是統一一套標準的渲染處理邏輯,不同領域服務進行接入使用,這樣不僅能夠減少領域服務間的重復建設,也能夠讓功能接入方式統一,不再需要進行適配。為了統一渲染處理邏輯,我們在Dukang框架基礎上擴充了渲染框架能力,將渲染流程固化為上下文構建->功能過濾->功能決策→功能渲染。其中上下文構建是組裝渲染所需的必要上下文數據,功能過濾是根據地域、時間、品類等規則過濾掉當前場景下不展示的功能,功能決策是對剩余的功能進行優先級排序,選擇最終展示的功能,功能渲染則是選中的功能進行數據的填充。除了渲染框架以外,我們還沉淀了一些標準可復用的能力,比如開城、白名單、物料管理等等,這些能力的相關配置我們統一建設了功能管理平臺進行集中管理。
下面介紹下渲染框架和功能管理平臺的詳細建設方案。
渲染框架
渲染框架主要思路是通過一套統一的功能執行流程,對功能進行標準化約束,框架限定了功能的執行流程依據上下文構建->功能過濾->功能決策->功能渲染,框架約束的只是執行流程,具體邏輯依然是相關功能閉環實現。比如功能過濾,如果只是簡單的開城過濾,業務方可以直接使用標準的開城能力;如果有一些不能抽象的復雜策略,業務方可以在自己的包中編碼實現。這樣既能保持功能的標準化定義,也能保持業務的靈活性。
功能管理平臺
功能管理平臺主要提供功能管理能力,平臺的主要功能如下:
功能展示策略配置,結合沉淀的城市、品類、場景等展示規則,配置不同功能對應的展示策略
功能優先級配置,配置組件下功能間的優先級,優先級支持多個分組,比如不同城市,優先級可能是不一樣
功能文案物料配置,配置對應功能展示所需的文案以及相關物料,這部分由于不同功能的配置方式差別很大,我們結合了內部的一個通用配置平臺實現,在通用配置平臺上,rd先根據實際需求,進行功能的文案和物料的配置模板開發,功能管理平臺和該通用配置平臺打通,將對應的配置頁面集成進來,形成統一的配置平臺。
功能全鏈路視圖,該視圖主要提供給產品業務使用,之前由于缺少統一的規范和沉淀,一個功能在哪些地方進行了透出,各個地方的效果轉化如何,很難在一個集中的地方看到。通過我們的標準化之后,我們可以提供功能的全鏈路視圖,方便的看到每個功能在哪些組件上進行了透出,對應的流量分布是怎樣的,轉化漏斗如何等等。
數據標準化
對組件和功能接入進行標準化之后,數據標準化就水到渠成了,我們只需要在每個階段的日志中,記錄前面定義的頁面、組件、模板、功能等唯一標識,同時打通數據鏈路,按照統一的規范進行數據上報、采集、清洗和聚合,就能夠形成一套標準的數據方案,在后面的功能開發過程,不需要再進行額外的數據開發,根據組件或功能的標識就能夠看到需要的數據。
埋點協議統一
埋點協議統一的核心就是讓不同服務的埋點信息能夠聚合起來,只要大家采用一套固定協議,約定好聚合的字段,通過數據采集清洗等步驟進行聚合,就可以實現數據的統一。我們制定了前端上報、網關下發日志、數據源服務日志等一系列的協議,統一了頁面、組件、模板和功能等標識。整體的思路如下所示,通過平臺統一管控埋點統一配置,各個服務利用sdk的方式對上報埋點進行統一。
數據鏈路打通
打通從終端到后端服務的數據鏈路,通過標準的協議,將數據聚合到統一的數倉中,進而形成統一的數據看板。主要數據鏈路示意如下所示:
總結
綜上所述,我們通過組件、功能接入和數據的標準化,完成了整個跨端統一渲染平臺的建設,目前該平臺還在持續建設推廣中,渲染網關、組件管理平臺、渲染框架、埋點規范等已經建設完成,功能管理平臺、數據鏈路還在建設中。當前該統一渲染平臺已經接入了20+頁面,未來將繼續覆蓋到所有的渲染場景。
平臺的整體的系統架構圖如下所示:
-
API
+關注
關注
2文章
1507瀏覽量
62219 -
架構
+關注
關注
1文章
517瀏覽量
25504 -
網約車
+關注
關注
3文章
222瀏覽量
11394
原文標題:只會 CRUD?滴滴這 DDD 架構建設方案太強了!支持 iOS/Android/網頁多種終端
文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論