背景
目前云音樂已經(jīng)建立了基于 GraphQL 的 BFF 研發(fā)模式,在探索前后端協(xié)同的 BFF 研發(fā)模式上,起到了一定的作用和影響。然而,這種研發(fā)模式并未解決業(yè)務(wù)側(cè)研發(fā)人員的核心痛點,同時又引出了一些新的問題,主要體現(xiàn)在以下幾方面:
BFF 場景下業(yè)務(wù)邏輯的編排訴求
-
邏輯編排能力低:由于 GraphQL 是用于 API 查詢的 DSL,比較側(cè)重數(shù)據(jù)聚合和選擇;當(dāng)存在一定的業(yè)務(wù)邏輯時,諸如對輸入?yún)?shù)、輸出結(jié)果做相應(yīng)的處理,需要增加邏輯判斷等,只能在 Groovy 腳本中實現(xiàn);由于腳本實現(xiàn)沒有相應(yīng)規(guī)范,很容易導(dǎo)致大量業(yè)務(wù)邏輯會通過腳本實現(xiàn),造成腳本濫用。
-
資源開銷成本高:不論是測試接口還是業(yè)務(wù)實現(xiàn)接口,都會產(chǎn)生機(jī)器資源開銷,目前存在大量無流量應(yīng)用和實例,造成資源浪費。
-
交互復(fù)雜,上手成本高:由于產(chǎn)品概念較多且交互復(fù)雜,中間實現(xiàn)鏈路較長,導(dǎo)致接口調(diào)試不便,排查問題困難。
-
角色分工不清晰,服務(wù)治理能力弱:前端研發(fā)人員主要負(fù)責(zé) API 接口搭建、自測,從而完成接口的交付;但在引擎服務(wù)集群穩(wěn)定性、流量水位方面缺少評估經(jīng)驗,而這部分內(nèi)容服務(wù)端研發(fā)人員相對更擅長點;另一方面,由于前端和服務(wù)端研發(fā)人員需要關(guān)注的領(lǐng)域和內(nèi)容不同,一些運維操作通常都需要跨平臺使用,導(dǎo)致服務(wù)治理困難。
服務(wù)的沉淀與復(fù)用
在活動玩法場景下已存在簡單的輕量級流程編排能力,但由于接入復(fù)雜、平臺使用困難,目前使用并不廣泛;與此同時,在該場景下一些固化配置和邏輯處理也并未沉淀成為服務(wù)資產(chǎn),導(dǎo)致相應(yīng)業(yè)務(wù)邏輯的復(fù)用能力較低。
全鏈路低代碼建設(shè)
另一方面,云音樂已經(jīng)構(gòu)建了 Tango 低代碼搭建平臺。Tango 在 UI 層已經(jīng)極大地提升了需求交付和研發(fā)效率,但在基礎(chǔ)邏輯編排、基礎(chǔ)服務(wù)編排、乃至模型驅(qū)動 UI 的基礎(chǔ)資源編排方面還是一片空白,構(gòu)建服務(wù)端低代碼產(chǎn)品,建立全鏈路低代碼研發(fā)模式是重要建設(shè)目標(biāo)。
思考
BFF 的應(yīng)用場景是根據(jù)當(dāng)前業(yè)務(wù)需要,對多個微服務(wù)接口返回的數(shù)據(jù)進(jìn)行組裝,會承載一些業(yè)務(wù)邏輯判斷或數(shù)據(jù)格式轉(zhuǎn)化,方便客戶端(包括:PC Web,H5,App,小程序等)消費的架構(gòu)模式,其主要是為了解決多訪問終端業(yè)務(wù)耦合問題。
云音樂當(dāng)前的 BFF 的研發(fā)模式只是交付 C 端部分業(yè)務(wù)場景的方式之一,其他 C 端場景以及大量 B 端場景也或多或少都存在相類似的訴求,但交付需求的方式依舊是傳統(tǒng)的研發(fā)方式。相比較前端可通過組件、模塊、頁面模版、樣板間、微前端架構(gòu)等眾多方式快速復(fù)用 UI 和交互能力,服務(wù)端想沉淀和快速復(fù)用一些服務(wù)資產(chǎn)時,存在諸多不便。這些不便主要體現(xiàn)在:接口實現(xiàn)規(guī)范較多,統(tǒng)一實施難以落地;微服務(wù)較多邊界較模糊且占用資源不一,一些場景下又需要將多個微服務(wù)合并成一個微服務(wù)。
那么在云音樂當(dāng)前研發(fā)現(xiàn)狀下,有沒有一種方式,即能實現(xiàn)自由組裝服務(wù)資產(chǎn),清晰地表達(dá)服務(wù)間依賴關(guān)系和對應(yīng)業(yè)務(wù)場景邏輯;又能通過一定的手段沉淀和復(fù)用服務(wù)資產(chǎn),在給定輸入值后可自動調(diào)用依賴服務(wù)輸出結(jié)果;與此同時,還可搭配 Tango 低代碼搭建平臺,在整體研發(fā)鏈路上進(jìn)一步降低開發(fā)成本,提升交付質(zhì)量和效率。
答案是存在的,那就是:基于流程編程 (Flow-based programming)
關(guān)于 FBP
基于流程編程是一種特殊形式的數(shù)據(jù)流程編程范式,其可以將程序表達(dá)為具有輸入和輸出的有向圖,圖內(nèi)每個節(jié)點具備一定的中間運算過程,并通過特殊邏輯關(guān)聯(lián)將節(jié)點銜接起來,當(dāng)給定輸入時,就會自動執(zhí)行并輸出結(jié)果。
典型的 FBP 程序圖表達(dá)如下圖所示:

通過對 FBP 程序的圖表達(dá)分析不難發(fā)現(xiàn),這種有向圖包含著明確的輸入和輸出節(jié)點、中間依賴節(jié)點、以及節(jié)點間連接關(guān)系,其是可以通過流程圖的方式表達(dá)的。
解法
為了解決當(dāng)前研發(fā)現(xiàn)狀所面臨的諸多問題,基于 FBP 的理念和流程圖可視化編輯能力,云音樂公技低代碼團(tuán)隊發(fā)起了 TangoFlow 項目。項目旨在通過組裝式架構(gòu),整合云音樂服務(wù)端技術(shù)棧,提供基礎(chǔ)邏輯編排能力,以網(wǎng)關(guān) API、統(tǒng)一 SDK 等方式暴露編排結(jié)果;從長遠(yuǎn)目標(biāo)來看,期望構(gòu)建符合云音樂研發(fā)現(xiàn)狀的服務(wù)端低代碼平臺,結(jié)合 Tango 搭建平臺在提升需求交付效率和吞吐率、降低交付成本的同時,建立起完整的全鏈路低代碼研發(fā)模式。
架構(gòu)設(shè)計
我們期望開發(fā)者在平臺創(chuàng)建好流程后,借助可視化搭建能力對服務(wù)資產(chǎn)進(jìn)行編排組裝,通過接口將圖信息傳給服務(wù)端;服務(wù)端得到圖信息后再將其轉(zhuǎn)化為 DSL 并發(fā)送給流程引擎,引擎在得到 DSL 后會自動解析和執(zhí)行并以特定方式暴露編排結(jié)果,從而提供給客戶端消費,用戶使用流程大致如下:
用戶使用流程.png
那么基于以上思考、期望目標(biāo)以及用戶使用核心鏈路,我們明確了 TangoFlow 的產(chǎn)品架構(gòu),整體設(shè)計如下:
TangoFlow 架構(gòu).jpg
技術(shù)選型
構(gòu)建基礎(chǔ)邏輯編排能力,首當(dāng)其沖是要實現(xiàn)可視化的流程圖編輯能力。在對比了社區(qū)眾多相關(guān)流程圖編輯產(chǎn)品后,決定使用螞蟻開源的 X6 圖編輯引擎,其主要有以下優(yōu)勢:
-
核心功能穩(wěn)定,持續(xù)迭代并完善自身能力 -
開箱即用,組件和插件完備,便于定制,也可通過相應(yīng)注冊機(jī)制靈活擴(kuò)展能力 -
事件驅(qū)動,有完備的事件機(jī)制來處理相關(guān)交互邏輯 -
數(shù)據(jù)驅(qū)動,支持圖內(nèi)的節(jié)點和關(guān)系的序列化和反序列化 -
豐富的案例實現(xiàn),可快速查看和在線調(diào)試運行
產(chǎn)品設(shè)計
由于流程編排本質(zhì)上是抽象輸入、輸出、服務(wù)為節(jié)點組件,通過可視化拖拉拽將這些組件按流程圖方式組織,從而完成對應(yīng)的邏輯表達(dá)需求。鑒于社區(qū)不乏相關(guān)優(yōu)秀的產(chǎn)品,比如 XFlow、LogicFlow、ProcessOn、Figma、語雀、ioDraw等, 通過對這類產(chǎn)品的抽象和總結(jié),最終確定 TangoFlow 的可視化編排界面結(jié)構(gòu)如下圖所示:
編排產(chǎn)品設(shè)計.png
頂部導(dǎo)航
頂部導(dǎo)航需要展示一些核心的信息,同時也需要承載一些核心操作以及其他跳轉(zhuǎn)入口,主要體現(xiàn)在以下幾方面:
-
核心信息:所屬應(yīng)用、編排的流程、分支信息等 -
核心操作:分支切換、撤銷/重做、畫布縮放、 保存、發(fā)布等 -
其他入口:回到首頁、前往 APM、問題反饋等
物料
物料面板不僅需要顯示有哪幾類、哪些節(jié)點組件,同時也需要節(jié)點組件具備拖拽至畫布內(nèi)自動添加和顯示的能力。通過對流程圖的抽象分析,我們將流程中包含的節(jié)點分為以下幾大類:
-
觸發(fā)器:流程對應(yīng)的輸入節(jié)點,其主要是暴露網(wǎng)關(guān)服務(wù)端 HTTP 服務(wù) -
邏輯控制:一些常見的邏輯表達(dá),如 if-else、switch、for 迭代邏輯等 -
基礎(chǔ)服務(wù):適配云音樂的服務(wù)資產(chǎn),如:RPC 接口、Groovy 腳本、網(wǎng)關(guān) API 接口等 -
數(shù)據(jù)結(jié)果:流程對應(yīng)的結(jié)束節(jié)點,其主要是控制 BFF 服務(wù)輸出的內(nèi)容格式和數(shù)據(jù)結(jié)果。
畫布
畫布作為流程編排的核心能力,不僅需要提供流程節(jié)點的展示、節(jié)點組合嵌套、節(jié)點連接關(guān)系表達(dá)外,同時也需要承載一些快捷交互能力,諸如節(jié)點信息編輯、節(jié)點菜單、畫布菜單、邊標(biāo)簽設(shè)置等。
屬性設(shè)置
通過對流程中涉及每個節(jié)點的屬性抽象,產(chǎn)出相應(yīng)的節(jié)點屬性配置;由于每個節(jié)點所對應(yīng)的屬性配置是不同的,每個屬性在設(shè)置時所需的 UI 組件也不盡相同,這就要求屬性設(shè)置是一個動態(tài)表單,且需要具備足夠的靈活度以及擴(kuò)展能力。
控制臺
在對流程進(jìn)行調(diào)試時,控制臺區(qū)域不僅需要展示請求入?yún)⒑洼敵鼋Y(jié)果,也需要展示引擎運行 DSL 時的調(diào)用過程,方便在調(diào)試出錯時能快速定位具體是哪一部分發(fā)生異常。
相關(guān)實現(xiàn)
基于以上產(chǎn)品設(shè)計和一些核心功能要求,最終的的 TangoFlow 的編排界面展示如下:
節(jié)點屬性
得益于 X6 的強(qiáng)大能力,很簡單通過 json 配置便可實現(xiàn)一個節(jié)點的樣式及相關(guān)交互能力。一個 IF 節(jié)點的 json 配置如下圖所示:
IF 節(jié)點配置.png
-
markup: 指定了渲染節(jié)點時使用的 SVG 片段,表明在該片段存在那些標(biāo)簽元素 -
width:節(jié)點在畫布中的寬度 -
height:節(jié)點在畫布中的高度 -
attrs:對 markup 中定義的元素選擇器的 SVG 屬性描述 -
data:與節(jié)點關(guān)聯(lián)的業(yè)務(wù)數(shù)據(jù),主要是抽象出來的節(jié)點名稱、類別、業(yè)務(wù)屬性等,可通過 props 透傳給屬性面板使用 -
ports:連接樁,即節(jié)點上的固定連接點 -
tools:節(jié)點工具,可以增強(qiáng)節(jié)點的交互能力
通過舉一反三的方式其他節(jié)點的配置也是如此,整體便可組成所需節(jié)點的屬性配置 list 數(shù)據(jù);在明確節(jié)點屬性后,便可使用注冊方法來注冊畫布所需的節(jié)點了,畫布組件的實現(xiàn)和節(jié)點注冊示例代碼如下:
節(jié)點注冊.png
節(jié)點拖拽
由于 X6 已提供了 Dnd 插件,可快速實現(xiàn)往畫布內(nèi)拖拽節(jié)點自動顯示的交互方式。整體實現(xiàn)思路是:在拖拽事件觸發(fā)時,需要先調(diào)用創(chuàng)建節(jié)點方法,再通過節(jié)點對象進(jìn)行節(jié)點屬性修改和業(yè)務(wù)數(shù)據(jù)設(shè)置,最后調(diào)用 dnd.start() 方法。核心實現(xiàn)代碼如下:
節(jié)點拖拽.png
節(jié)點/畫布菜單
當(dāng)需要鼠標(biāo)右鍵點擊顯示節(jié)點菜單時,可通過往節(jié)點添加自定義工具實現(xiàn),效果圖如下:
節(jié)點菜單.png
實現(xiàn)自定義工具的思路如下:
Canvas 組件內(nèi)設(shè)置固定的 dom 節(jié)點用以渲染相關(guān)內(nèi)容,部分示例代碼如下:

實現(xiàn)自定義菜單,可通過繼承 ToolsView.ToolItem 來覆蓋內(nèi)部一些具體邏輯,核心實現(xiàn)代碼如下:

在注冊節(jié)點時,注冊節(jié)點工具,示例代碼如下:

配置節(jié)點工具 tools 屬性,示例參考:

節(jié)點提示
同樣當(dāng)需要鼠標(biāo) hover 顯示節(jié)點提示信息時,也可通過往節(jié)點添加自定義工具實現(xiàn),實現(xiàn)思路與實現(xiàn)節(jié)點菜單一致,此處不做過多贅述,展示如下:
節(jié)點提示展示.png
實現(xiàn)節(jié)點提示時需要注意以下幾點:
Canvas 組件內(nèi)設(shè)置固定的 dom 節(jié)點用以渲染相關(guān)內(nèi)容,示例代碼如下:

-
由于是自由畫布,需要考慮提示框的顯示位置,可相對于節(jié)點位置來顯示。
-
需要注意節(jié)點鼠標(biāo)進(jìn)入和節(jié)點鼠標(biāo)移出與節(jié)點鼠標(biāo)按下、節(jié)點連接樁移入等其他事件的影響。
節(jié)點提示組件的核心實現(xiàn)代碼如下:
節(jié)點提示實現(xiàn).png
節(jié)點組合設(shè)置
embedding 是實現(xiàn)節(jié)點組合嵌套的核心,具體配置可參考文檔說明;當(dāng)需要檢查節(jié)點是否允許被組合嵌套時,可通過 validate 方法實現(xiàn),實現(xiàn)代碼如下:
embedding 是實現(xiàn)節(jié)點組合嵌套的核心,具體配置可參考文檔說明;當(dāng)需要檢查節(jié)點是否允許被組合嵌套時,可通過 validate 方法實現(xiàn),實現(xiàn)代碼如下:

以下兩類邏輯控制節(jié)點便是借助組合嵌套實現(xiàn):
Switch 判斷:有固定的 I/O 連接樁,通過屬性配置增加 case 枚舉條件,僅支持嵌套 If 和基礎(chǔ)服務(wù)節(jié)點,展示如下:

For 迭代器:有固定的 I/O 連接樁,可指定迭代對象、對象類型以及迭代返回值格式,支持嵌套 If、Break、Contine 和基礎(chǔ)服務(wù)節(jié)點,展示如下:

邊標(biāo)簽設(shè)置
邊標(biāo)簽設(shè)置是基于內(nèi)置的 edge-editor 實現(xiàn)的,通過雙擊邊可自動添加邊標(biāo)簽;不過由于該小工具并未判斷限制,鼠標(biāo)雙擊可創(chuàng)建多個標(biāo)簽;如果想每次只修改和保存一個,可在對應(yīng)的 setText 方法內(nèi)先刪除再添加,示例代碼如下:
邊標(biāo)簽設(shè)置.png
連接檢查
connecting 是實現(xiàn)節(jié)點連接交互的核心,具體配置可查閱相關(guān)文檔,當(dāng)需要對節(jié)點間是否允許連接時,可通過 validateEdge 來實現(xiàn),避免一些非法連線如:節(jié)點回環(huán)、從輸出到輸入等,實現(xiàn)代碼如下:

屬性面板
在產(chǎn)品設(shè)計章節(jié)有提到屬性面板需要具備足夠的靈活度以及擴(kuò)展能力,鑒于 Tango 已經(jīng)實現(xiàn)相關(guān)屬性表單能力,此處可直接引入使用,具體使用和實現(xiàn)方式參見 setting-form
調(diào)試能力
流程在搭建完成后,還需要在線調(diào)試和驗證。實現(xiàn)調(diào)試的思路是:借助 graph.toJSON() 方法導(dǎo)出節(jié)點和邊的 json 格式數(shù)據(jù),在通過接口將這些節(jié)點數(shù)據(jù)傳遞給服務(wù)端,服務(wù)端拿到 json 數(shù)據(jù)后轉(zhuǎn)化為 DSL 并執(zhí)行,從而實現(xiàn)流程的在線調(diào)試能力。目前,TangoFlow 支持了以下三種方式的調(diào)試能力:
流程調(diào)試,通過設(shè)置輸入?yún)?shù)或者請求頭信息,對整體流程進(jìn)行調(diào)試,界面展示如下:

節(jié)點調(diào)試,對當(dāng)前的服務(wù)節(jié)點進(jìn)行在線調(diào)試,頁面展示如下:

遠(yuǎn)程調(diào)試,即指定某一環(huán)境對應(yīng)的集群內(nèi)機(jī)器后進(jìn)行流程調(diào)試
Mock 機(jī)制
mock 的能力主要是為了方便在線調(diào)試,確保流程在調(diào)試過程盡可能的暴露問題和快速通過測試,在進(jìn)行調(diào)試時設(shè)置的 mock 數(shù)據(jù)也會一并發(fā)送至服務(wù)端,服務(wù)端在進(jìn)行 DSL 轉(zhuǎn)化時,會自動讀取 mock 數(shù)據(jù)并寫入 DSL 內(nèi)。
對于基礎(chǔ)服務(wù)節(jié)點來說應(yīng)具備請求參數(shù) mock 和響應(yīng) mock(固定返回 mock 值),而對于輸出節(jié)點只需具備響應(yīng) mock 即可,在開啟 mock 能力后節(jié)點會自動顯示 mock 標(biāo)記,頁面展示如下:

發(fā)布卡點
針對流程每次的發(fā)布,我們制定了嚴(yán)格的發(fā)布部署模型;流程發(fā)布會經(jīng)過開發(fā)、回歸、卡點、預(yù)發(fā)、線上、完成這六個階段;在開發(fā)和回歸環(huán)境,可以存在多個分支發(fā)布部署;當(dāng)一個分支需要發(fā)布上線時,需要先經(jīng)過卡點環(huán)節(jié)的各項檢查;只有卡點環(huán)節(jié)通過,才會被允許進(jìn)行預(yù)發(fā)和線上環(huán)境的部署,并且流程線上發(fā)布的通道內(nèi)只能存在一個分支;在線上環(huán)境部署后,線上環(huán)境測試通過,點擊完成即可結(jié)束當(dāng)前分支的發(fā)布生命周期。
通過此發(fā)布部署模型,確保了流程發(fā)布的穩(wěn)定性,整體實現(xiàn)如下圖所示:

總結(jié)
以上是借助 X6 在構(gòu)建云音樂低代碼流程編排能力時的一些實踐歷程,其強(qiáng)大的圖編輯和自定義能力,使得可快速實現(xiàn)符合業(yè)務(wù)需要的流程編排訴求。在實現(xiàn)某一具體場景的編排產(chǎn)品時,個人覺得需要注意以下幾點:
-
明確編排能力的核心訴求,并確定優(yōu)先級 -
多參考和分析其他類似的優(yōu)秀產(chǎn)品相關(guān)能力,然后多嘗試用一些設(shè)計工具實現(xiàn) -
做更多的技術(shù)預(yù)研,分析各個相關(guān)工具的優(yōu)缺點,明確其擅長的應(yīng)用場景 -
相比代碼實現(xiàn),前期的產(chǎn)品設(shè)計和技術(shù)預(yù)研至關(guān)重要
未來展望
隨著當(dāng)前編排能力的趨于成熟穩(wěn)定,在繼續(xù)完善全鏈路低代碼建設(shè)的同時,也會在 AIGC 方向探索更多的可能,不斷地重塑產(chǎn)品能力,未來主要包含以下方面:
-
繼續(xù)整合服務(wù)端相關(guān)技術(shù)棧資源,借助編排的方式實現(xiàn)對相關(guān)資源的最大化利用 -
結(jié)合 Tango 完備的前端搭建體系,構(gòu)建模型驅(qū)動 UI 的研發(fā)模式,進(jìn)一步提高需求交付效率 -
集成 AIGC 能力,借助 AI Agent 能力根據(jù)用戶的自然語言輸入,自動識別用戶意圖從而完成一系列動作
未經(jīng)允許不得轉(zhuǎn)載:RPA中國 | RPA全球生態(tài) | 數(shù)字化勞動力 | RPA新聞 | 推動中國RPA生態(tài)發(fā)展 | 流 > X6 在云音樂低代碼流程編排中的實踐
熱門信息
閱讀 (14728)
1 2023第三屆中國RPA+AI開發(fā)者大賽圓滿收官&獲獎名單公示閱讀 (13753)
2 《Market Insight:中國RPA市場發(fā)展洞察(2022)》報告正式發(fā)布 | RPA中國閱讀 (13055)
3 「RPA中國杯 · 第五屆RPA極客挑戰(zhàn)賽」成功舉辦及獲獎名單公示閱讀 (12964)
4 與科技共贏,與產(chǎn)業(yè)共進(jìn),第四屆ISIG中國產(chǎn)業(yè)智能大會成功召開閱讀 (11567)
5 《2022年中國流程挖掘行業(yè)研究報告》正式發(fā)布 | RPA中國