低代碼在愛奇藝鵲橋數(shù)據(jù)同步平臺的實踐
本文作者:愛奇藝技術(shù)
本文鏈接:https://juejin.cn/post/6899262277459902472
前言
為應(yīng)對軟件危機,誕生了軟件工程,以期望其達到降低軟件生產(chǎn)成本 、改進軟件產(chǎn)品質(zhì)量、提高軟件生產(chǎn)率水平的目標。自上個世紀 60 年代以來,從模塊化、面向?qū)ο笤O(shè)計到設(shè)計模式,從瀑布流模型到敏捷開發(fā),dev-ops, 軟件生產(chǎn)的指導(dǎo)理論和工程方法都在不斷進步,軟件的生產(chǎn)效率有了很大改善。然而直到今天,業(yè)務(wù)需求的增長和企業(yè)開發(fā)資源緊缺的矛盾依然廣泛存在。
與此同時, 近年來 no-code/low-code 的理念得到越來越多的國內(nèi)外企業(yè)的重視,各類零代碼、低代碼開發(fā)平臺層出不窮。據(jù) Gartner 的研究預(yù)測,到 2024 年低代碼平臺將被應(yīng)用于 65% 的應(yīng)用程序開發(fā)。盡管它也不是解決所有問題的 “銀彈”, 但是低代碼作為一個趨勢,代表了業(yè)界向自動化編碼邁進了重要的一步,在 AI 編程變得普適之前,低代碼能夠大幅提升業(yè)務(wù)交付效率。
本文結(jié)合愛奇藝 App 后端在業(yè)務(wù)數(shù)據(jù)同步方面的實踐,分享基于低代碼平臺高效交付業(yè)務(wù)需求及避免重復(fù)開發(fā)的經(jīng)驗。
Part 01
業(yè)務(wù)背景
首先以移動端為例,我們先簡單回顧下業(yè)務(wù)數(shù)據(jù)在呈現(xiàn)給用戶之前普遍會經(jīng)歷的大致過程:
· 數(shù)據(jù)生產(chǎn)后臺: 運營人員或者自動化程序通過業(yè)務(wù)生產(chǎn)后臺將數(shù)據(jù)生產(chǎn)出來。比如編輯或者用戶發(fā)布的文章、上傳的視頻,或者爬蟲程序自動抓取網(wǎng)絡(luò)上的資源,數(shù)據(jù)生產(chǎn)后臺將這些數(shù)據(jù)存放的數(shù)據(jù)庫中,并提供讀取服務(wù)供下游業(yè)務(wù)獲取數(shù)據(jù)。當(dāng)數(shù)據(jù)發(fā)生修改后,通過消息通知下游更新數(shù)據(jù);
·**數(shù)據(jù)同步:**業(yè)務(wù)部門通過數(shù)據(jù)同步服務(wù)將生產(chǎn)后臺產(chǎn)生的數(shù)據(jù)進行轉(zhuǎn)換、聚合等加工處理,寫入到數(shù)據(jù)庫和分布式緩存里;
· 數(shù)據(jù)庫 & 緩存: 存儲各類業(yè)務(wù)數(shù)據(jù)供業(yè)務(wù)后端接口讀取;
·**后端接口:**接受 App 前端的請求,從緩存、數(shù)據(jù)庫以及第三方接口讀取各類業(yè)務(wù)數(shù)據(jù),按業(yè)務(wù)需要進行各種組裝處理。
·**App 前端:**請求后端接口并解析返回的數(shù)據(jù),并在設(shè)備上進行渲染呈現(xiàn)給用戶。
出于整體組織效率考慮,一般來說,數(shù)據(jù)生產(chǎn)部門主要專注于數(shù)據(jù)生產(chǎn)的場景,對于數(shù)據(jù)最終如何使用無需過多專注。而實際通常來說,最終呈現(xiàn)給用戶的數(shù)據(jù)是豐富多樣的,這通常意味著我們需要聚合不同生產(chǎn)方的數(shù)據(jù),出于性能上的考慮,這種聚合完全交由后端接口在響應(yīng)用戶請求時實時訪問多方數(shù)據(jù)源接口來聚合是不現(xiàn)實的。同時面向用戶的業(yè)務(wù)往往并發(fā)流量較高,基于高并發(fā)以及高可用的需要,數(shù)據(jù)往往會存儲在不同的數(shù)據(jù)庫中間件里并保持一致性。基于這樣的背景,數(shù)據(jù)同步服務(wù)承擔(dān)了數(shù)據(jù)從生產(chǎn)側(cè)交付給消費側(cè)的橋梁角色,這使得生產(chǎn)部門能更加專注于內(nèi)容生產(chǎn)環(huán)節(jié)的迭代,而消費側(cè) (一般是后臺接口) 專注于如何快速交付業(yè)務(wù)接口以及保證服務(wù)接口的高性能和高可用。
Part 02
挑戰(zhàn)
在業(yè)務(wù)早期,數(shù)據(jù)同步處理的數(shù)據(jù)類型和數(shù)據(jù)量不算太高,這種模式下各個部分職責(zé)劃分也比較清晰,各個業(yè)務(wù)環(huán)節(jié)迭代都比較高效。然而隨著業(yè)務(wù)不斷發(fā)展,需求場景不斷豐富,逐漸出現(xiàn)了一些問題。主要表現(xiàn)為:
**人力瓶頸:**數(shù)據(jù)同步模塊承載的業(yè)務(wù)數(shù)量來源越來越多, 光就本人所在團隊來說目前已經(jīng)有 30 數(shù)據(jù)同步業(yè)務(wù),而絕大部分業(yè)務(wù)需求的都需要對底層數(shù)據(jù)進行調(diào)整,數(shù)據(jù)同步環(huán)節(jié)的開發(fā)人力逐漸成為瓶頸;
**迭代周期緊迫,項目質(zhì)量難以保證:**由于業(yè)務(wù)需求對底層數(shù)據(jù)依賴關(guān)系通常并不能直觀的識別出來,這造成了產(chǎn)品同學(xué)在交付需求文稿時容易遺漏對數(shù)據(jù)層的分析,甚至業(yè)務(wù)開發(fā)同學(xué)在早期需求評估階段也無法準確識別出對哪些基礎(chǔ)數(shù)據(jù)有依賴,這導(dǎo)致在版本臨近交付時才能識別出底層數(shù)據(jù)的需求依賴, 這就意味著留給數(shù)據(jù)同步環(huán)節(jié)的開發(fā)時間非常緊迫。同時這個節(jié)點測試團隊的排期也已經(jīng)確定了,測試資源往往不能充分保證,這些因素對項目質(zhì)量帶來了一定的風(fēng)險。比如,有時為了快速交付業(yè)務(wù)需求,會直接在原有程序里新集成業(yè)務(wù)上不關(guān)聯(lián)的新需求,從而在不同業(yè)務(wù)之間形成了不必要的耦合,為項目后期維護增加了風(fēng)險和復(fù)雜度。
**存儲中間件的管理維護成本增加:**數(shù)據(jù)同步模塊負責(zé)將各類業(yè)務(wù)數(shù)據(jù)到落地存儲中間件,而下游眾多的業(yè)務(wù)接口需要訪問這些中間件來獲取數(shù)據(jù),這使得接口需要了解數(shù)據(jù)存儲的細節(jié)。一旦需要調(diào)整存儲方案 (比如中間件依賴的虛機要下線維護, 需要遷移集群),除了遷移存量數(shù)據(jù),數(shù)據(jù)同步模塊和眾多業(yè)務(wù)接口均需要調(diào)整,而調(diào)整的第一步,僅僅確認幾十個項目里哪些需要調(diào)整的工作量就不容小覷,更不用說進而再制定并實施跨越眾多項目的協(xié)同遷移計劃。為此我們開發(fā)了一些基礎(chǔ)數(shù)據(jù)接口和封裝數(shù)據(jù)訪問的 sdk, 這在一定程度上解決了問題, 但另一方面也新增加了基礎(chǔ)數(shù)據(jù)接口和相關(guān) sdk 的維護成本。
**重復(fù)編碼的場景較多:**比如,每一個同步業(yè)務(wù)需要開發(fā)監(jiān)聽消息隊列,訪問生產(chǎn)方接口的代碼,同時非業(yè)務(wù)必要能力開發(fā)比如重試、限流、監(jiān)控等,在每個具體業(yè)務(wù)都需要實現(xiàn)。對這個問題,我們一度寄希望于通用的同步模板項目來解決。但實踐下來,模板的通用性和業(yè)務(wù)的多樣性之間存在矛盾,同時每個業(yè)務(wù)仍然需要創(chuàng)建項目開發(fā)、測試代碼,仍然有較高維護成本。放眼整個公司,還有很多兄弟團隊也有大量類似的場景,比如 pc 端,h5 端和我們可能都依賴相同的上游生產(chǎn)方,存在大量相同場景的重復(fù)實現(xiàn),這種情況下如何避免重復(fù)開發(fā)呢?
Part 03
方案調(diào)研
基于上述這些問題,我們希望尋求維護成本更低、開發(fā)效率更高的解決方案。為此我們對數(shù)據(jù)同步相關(guān)產(chǎn)品進行了調(diào)研,結(jié)果發(fā)現(xiàn)大部分都是面向異構(gòu)數(shù)據(jù)庫的同步,或者只能支持批處理任務(wù),抑或不能方便擴展訪問外部接口, 綜合下來并沒有發(fā)現(xiàn)能較好適配我們業(yè)務(wù)場景的。當(dāng)然調(diào)研的這些產(chǎn)品很多特性為我們提供了重要的參考,比如 dataX 的插件機制和 Spring Cloud Data Flow 的編排能力給了我們很多啟發(fā)。
在后續(xù)的調(diào)研中,近年來逐漸興起的低代碼開發(fā)平臺方案走進了我們的視野。低代碼開發(fā)平臺是無需編碼(0 代碼或無代碼)或通過少量代碼就可以快速生成應(yīng)用程序的開發(fā)平臺。它允許終端用戶使用易于理解的可視化工具開發(fā)自己的應(yīng)用程序,而不是傳統(tǒng)的編寫代碼方式。構(gòu)建業(yè)務(wù)流程、邏輯和數(shù)據(jù)模型等所需的功能,必要時還可以添加自己的代碼。完成業(yè)務(wù)邏輯、功能構(gòu)建后,即可一鍵交付應(yīng)用并進行更新。
結(jié)合我們的業(yè)務(wù)遇到的問題,我們期望通過低代碼平臺以較低成本實現(xiàn)如下目標:
**1. 快速交付能力。**能夠通過可視化編排來快速實現(xiàn)業(yè)務(wù)邏輯。
**2. 避免重復(fù)開發(fā)。**這里有三層含義:
(1)功能單元復(fù)用:同樣的功能,無論是中間件的訪問,還是某些業(yè)務(wù)接口的訪問, 只需要開發(fā)一次即可,新的業(yè)務(wù)需求里如果有相同的場景,比如訪問同一個公共訪問的接口,能夠直接復(fù)用之前的工作;
(2)業(yè)務(wù)場景復(fù)用:不同業(yè)務(wù)團隊有類似的業(yè)務(wù)場景時,可以快速移植,只需要調(diào)整少量參數(shù)即可實現(xiàn);
(3)CI 流程復(fù)用:所有業(yè)務(wù)的開發(fā)和上線能夠復(fù)用相同的構(gòu)建、部署流程,從而降低維護成本。
**3. 能夠靈活擴展。**比如使用到之前未支持的中間件,需要能夠方便的集成到已有的功能體系里來, 并且能在后續(xù)業(yè)務(wù)里復(fù)用。
**4. 高可用。**穩(wěn)定性是業(yè)務(wù)的基石, 對數(shù)據(jù)同步來說,異常重試、限流、監(jiān)控、告警等基礎(chǔ)能力必不可少。
5. 方便查看業(yè)務(wù)對中間件的依賴**。**比如能查看一組 redis 集群被哪些業(yè)務(wù)使用,一個業(yè)務(wù)使用了哪些中間件資源,方便后期的維護。
Part 04
愛奇藝鵲橋平臺介紹
基于前文所述背景,鵲橋平臺的設(shè)計思想主要是:
·封裝可復(fù)用的邏輯節(jié)點, 通過對這些邏輯節(jié)點可視化的進行編排快速落地業(yè)務(wù)流程;
·通過平臺化復(fù)用基礎(chǔ)能力;一次開發(fā),所有業(yè)務(wù)應(yīng)用都受益。
例如可以將消息消費,消息實體解析和特定接口的讀取分別封裝成可以復(fù)用的邏輯節(jié)點,在實現(xiàn)業(yè)務(wù)邏輯時,只需要將這些邏輯節(jié)點進行組合串聯(lián)即可。在運行階段,數(shù)據(jù)在每個邏輯節(jié)點被加工處理并按順序向下游傳遞,也可以根據(jù)業(yè)務(wù)需要增加判斷分支,這樣業(yè)務(wù)可以通過類似畫流程圖的方式快速交付。
如上圖所示,鵲橋主要有管理后臺和同步引擎兩個部分組成。管理后臺供業(yè)務(wù)開發(fā)同學(xué)完成業(yè)務(wù)邏輯的編排和發(fā)布。主要功能有:
- 操作簡單,提供了可視化的業(yè)務(wù)編輯器,可以通過拖拽的方式完成業(yè)務(wù)開發(fā);業(yè)務(wù)編排完成并發(fā)布后,會生成業(yè)務(wù)描述配置信息并存入云配置中心后續(xù)供同步引擎使用;如下圖所示為業(yè)務(wù)開發(fā)的編輯器,最左側(cè)是各自邏輯插件的列表,可以直接拖到中間的畫布上組合形成完整的業(yè)務(wù)處理流程。通過右側(cè)的屬性配置表單可以為每個邏輯節(jié)點指定業(yè)務(wù)相關(guān)的配置參數(shù),比如限流配置,重試配置,關(guān)聯(lián)服務(wù)授權(quán)信息等。
- 提供實體映射模板管理功能。映射模板描述了如何將一個 json 數(shù)據(jù)轉(zhuǎn)換為業(yè)務(wù)需要的數(shù)據(jù),開發(fā)同學(xué)可以在后臺對模板進行調(diào)試。可以通過實體轉(zhuǎn)換邏輯節(jié)點按照映射模板來完成字段的轉(zhuǎn)換。后期新增和修改字段邏輯時,只需要調(diào)整模板重新發(fā)布即可生效,不用再拉分支修改代碼,從而更加快速的完成需求交付。當(dāng)前線上已經(jīng)發(fā)生多次 10 分鐘內(nèi)交付業(yè)務(wù)需求的案例。
- 提供邏輯節(jié)點插件管理。擴展插件實現(xiàn)約定的編程接口并在后臺里導(dǎo)入后,就可以在業(yè)務(wù)編輯器里使用。需要指定插件所在的倉庫坐標、邏輯實現(xiàn)類全路徑名,同時在錄入時可以定義插件的屬性配置表單。一般數(shù)據(jù)同步業(yè)務(wù)都是后端開發(fā)同學(xué)來完成,后端一般比較熟悉相關(guān)業(yè)務(wù)邏輯,相對來說完成插件后臺的邏輯擴展不存在門檻,但是由于需要將邏輯插件和可視化編輯器進行集成,涉及到前端頁面的開發(fā),這往往是后端同學(xué)不熟悉的領(lǐng)域。為了避免后端同學(xué)學(xué)習(xí)前端的成本,我們將屬性表單的生成做成了拖拽式的,無需前端技術(shù)基礎(chǔ)也可以快速完成表單的開發(fā)。
- 中間件資源的管理??梢詫I(yè)務(wù)需要的中間件資源導(dǎo)入后臺,之后在開發(fā)業(yè)務(wù)時,可以在對應(yīng)邏輯節(jié)點的屬性配置表單里通過下拉框選擇到。同時平臺自動維護了業(yè)務(wù)和中間件的依賴關(guān)系。
- 管理后臺和公司相關(guān)基礎(chǔ)支持平臺打通,最大限度的避免重復(fù)性人工流程。比如和應(yīng)用運維平臺打通實現(xiàn)一鍵部署;和日志平臺打通,自動完成業(yè)務(wù)日志的投遞;和監(jiān)控告警平臺打通,業(yè)務(wù)應(yīng)用創(chuàng)建后自動注冊到監(jiān)控告警平臺。
同步引擎完成對數(shù)據(jù)的處理。首先在應(yīng)用構(gòu)建階段會基于業(yè)務(wù)配置分析當(dāng)前需要使用的的邏輯節(jié)點插件列表并將列表內(nèi)的插件和引擎核心模塊一起打包;應(yīng)用部署后,引擎在啟動階段會加載配置中心的業(yè)務(wù)配置,完成中間件資源訪問的初始化,并邏輯節(jié)點進行初始化,這一步主要是加載業(yè)務(wù)配置里為每個邏輯節(jié)點實例設(shè)置的配置參數(shù),并執(zhí)行插件實現(xiàn)的初始化邏輯。初始化正常結(jié)束之后,引擎將進入運行階段,開始處理線上數(shù)據(jù)。數(shù)據(jù)從起始節(jié)點進入業(yè)務(wù)流程后,依次執(zhí)行各個邏輯節(jié)點。引擎在運行過程中會定時上報心跳給監(jiān)測服務(wù),一旦心跳超時,會觸發(fā)告警通知業(yè)務(wù)開發(fā)同學(xué)及時處理。而業(yè)務(wù)指標 (比如 tps、成功率、耗時)) 的監(jiān)控數(shù)據(jù)則會投遞給監(jiān)控系統(tǒng)。
如上所述,管理后臺面向開發(fā)人員提供業(yè)務(wù)開發(fā)維護能力,同步引擎負責(zé)解釋和執(zhí)行編排好的業(yè)務(wù)邏輯。業(yè)務(wù)同學(xué)無需再針對每個業(yè)務(wù)需求都按照常規(guī)方式 “拉分支 à 修改代碼 à 提測 à 上線” 的流程, 只需要簡單拖拽和配置即可,業(yè)務(wù)交付效率大大提升。同時穩(wěn)定相關(guān)的基礎(chǔ)能力已經(jīng)通過平臺化進行了沉淀和復(fù)用,在保證業(yè)務(wù)穩(wěn)定的同時降低了維護成本。
自愛奇藝鵲橋平臺上線以來,目前已經(jīng)承載了近 20 個數(shù)據(jù)同步業(yè)務(wù),30 應(yīng)用實例,集成了 30 業(yè)務(wù)邏輯節(jié)點。為相關(guān)業(yè)務(wù)的快速迭代提供了穩(wěn)定支撐。后續(xù)我們會將存量的同步業(yè)務(wù)移植到該平臺來降低維護成本。
總結(jié) & 展望
本文主要介紹了鵲橋平臺的主要功能,就目前來說鵲橋?qū)鹘y(tǒng)方式小時級到天級的開發(fā)耗時縮短到分鐘級,極大提升了開發(fā)效率;同時開箱即用的高可用能力保證了業(yè)務(wù)的穩(wěn)定性。
后續(xù)我們考慮從如下幾個方向繼續(xù)優(yōu)化迭代:
- 進一步提供數(shù)據(jù)訪問層服務(wù)代碼的自動生成,進一步降低開發(fā)成本;
- 支持在私有云平臺上部署以為更多的業(yè)務(wù)團隊賦能;
- 結(jié)合平臺形成公司內(nèi)部的業(yè)務(wù)數(shù)據(jù)集市,避免不同業(yè)務(wù)團隊間的重復(fù)開發(fā)。
參考文獻:
**1.**The Rise of No/Low Code Software Development—No Experience Needed?
**2.** https://zhuanlan.zhihu.com/p/128581398
**3.**https://baike.baidu.com/item/軟件危機/564526?fr=aladdin
本文作者:愛奇藝技術(shù)
本文鏈接:https://juejin.cn/post/6899262277459902472