騰訊游戲業(yè)務(wù)竟然是這樣利用低代碼平臺的 | ArchSummit
點擊上方“服務(wù)端思維”,選擇“設(shè)為星標(biāo)”
回復(fù)”669“獲取獨家整理的精選資料集
回復(fù)”加群“加入全國服務(wù)端高端社群「后端圈」
在 2020年11月13-14日落地的 ArchSummit 全球架構(gòu)師峰會 2021(深圳)上,我們邀請到了騰訊 IEG 數(shù)據(jù)產(chǎn)品開發(fā)組負(fù)責(zé)人葉鑫林來分享他們的低代碼實踐。此次分享中他著重介紹了低代碼平臺的設(shè)計理念,如接口元數(shù)據(jù)自動注冊、SQL 賦能、基于 Mock 的前端快捷配置等,希望對你有所啟發(fā)。
當(dāng)大家談到低代碼的時候,常常只會想到邏輯可視化的平臺、UI 可視化的平臺,但是低代碼還有更多的可能,我們還可以引入很多其他模塊,例如,數(shù)據(jù)處理、接口、測試、人工智能等等。今天我將基于數(shù)據(jù)處理、接口、邏輯可視化,以及 UI 可視化這四方面來展開分享,并闡述我們案例中低代碼平臺中所有子平臺之間是如何協(xié)作的。
低代碼可以解決哪些業(yè)務(wù)問題?
假設(shè)有這樣一個場景,當(dāng)我們需要統(tǒng)計騰訊某游戲業(yè)務(wù)的城市登錄人數(shù),并且需要提供可以運(yùn)營或可以檢索的頁面。
一般的開發(fā)流程是這樣的,首先將任務(wù)派發(fā)給數(shù)據(jù)開發(fā),基于大數(shù)據(jù)的方案統(tǒng)計登錄人數(shù),接著找到后臺開發(fā)進(jìn)行數(shù)據(jù)接口開發(fā),然后尋找前端人員進(jìn)行 Web 頁面開發(fā)。
如果基于低代碼的方案來實現(xiàn),我們希望這些任務(wù)可以由一個非開發(fā)人員來獨立完成。他可以在數(shù)據(jù)平臺進(jìn)行數(shù)據(jù)統(tǒng)計,在邏輯可視化平臺完成接口開發(fā),然后在 UI 可視化平臺配置界面,最后整體交付這個需求。當(dāng)然,要實現(xiàn)上述過程,我們還有很多問題要解決。
例如,當(dāng)統(tǒng)計每個城市的登錄人數(shù)的時候,登錄信息日志一般只有 IP,并不會顯示城市,這使得產(chǎn)品人員不得不將 IP 轉(zhuǎn)換成城市,但這有很大的難度;其次,當(dāng)數(shù)據(jù)平臺輸出數(shù)據(jù)之后,如何將它轉(zhuǎn)換成接口?最后,即使有了接口,非開發(fā)人員還需要知道前端調(diào)用的接口參數(shù)、輸出以及對應(yīng)到的 UI 等等。
上面的這一切,對于一個非技術(shù)人員來講比較困難。
這里一共有三個問題需要解決。
首先,是否存在強(qiáng)大的 SQL 可以提供給用戶,這個 SQL 可以直接將 IP 轉(zhuǎn)換成城市?
其次,當(dāng)有了原數(shù)據(jù)之后,是否可以直接給到接口?是否可以針對傳統(tǒng)的 CURD 的方法直接生成接口?
最后,當(dāng)有了接口之后,UI 平臺是否可以簡化,不需要進(jìn)行復(fù)制粘貼。
那么針對這三個問題,我們采用了以下這套方案。

這套方案的整體架構(gòu),包含四個部分,第一層是微服務(wù)底座,中間是邏輯可視化,再向上是數(shù)據(jù)平臺,最上層是 UI 平臺。所有的基底都是微服務(wù)。
這里我們首先引入本方案中兩個比較重要的概念——元數(shù)據(jù)和 Mock。

元數(shù)據(jù)包含了數(shù)據(jù)的存儲、表、字段等元信息,大家都比較熟悉,這里不深入闡述,但是本方案中的 Mock 與業(yè)界稍微有些不同,業(yè)界通常使用 Mock 來做開發(fā)聯(lián)調(diào)和單測。
比如,當(dāng)后端的接口沒有開發(fā)完成的時候,它可以通過 Mock 將請求打到 Mock CGI,然后將返回接口傳遞過來;或者是當(dāng)我們并不希望觸發(fā)真實的請求,可以在 CI/CD 里進(jìn)行單測(如下圖所示)

不過這將帶來另外一個問題,那就是 Mock 如何進(jìn)行收集,我們都知道,很多接口不可能都依靠人力輸出。

騰訊的方案是:首先用戶的請求作為輸入,接著經(jīng)過網(wǎng)關(guān),網(wǎng)關(guān)將 Input 傳遞到整個微服務(wù),然后網(wǎng)關(guān)拿到返回結(jié)果,接著網(wǎng)關(guān)會把結(jié)果傳遞到客戶端,這個時候請求已經(jīng)完成了。
接下來將 Input、Output 以及微服務(wù)的接口注釋,推薦給 Mocks server,Mocks server 會進(jìn)行清洗,得到標(biāo)準(zhǔn)的 Mock 的數(shù)據(jù)(標(biāo)準(zhǔn) Mock 數(shù)據(jù)包含用戶的請求方式、地址、輸入以及輸出)。
這里會有一些性能相關(guān)的難點,采集任務(wù)不能影響微服務(wù)的性能,一些常見的解決方案已貼在上圖 Tips 中,比如,在這個網(wǎng)關(guān)里面需要進(jìn)行抽樣上報、增量上報以及異步上報等。
假設(shè)我們需要拉取一份數(shù)據(jù),目前開發(fā)人員已經(jīng)開發(fā)了拉取數(shù)據(jù)源的接口(接口已經(jīng)部署在微服務(wù)),這時候如何生成 Mock?
首先我們通過反射拿到接口的注釋,接著拿到參數(shù),然后通過注釋匹配。當(dāng)然我們會先對這一份注釋進(jìn)行清洗,然后得到字段對應(yīng)中文名的 TV 對,接著嘗試匹配。如果匹配不上,它會有一個單詞庫,再次嘗試匹配,直到拿到中文名為止,最后我們會得到一個標(biāo)準(zhǔn)的 Mock 自動化的方案流程。
經(jīng)過這樣一套流程,所有接口一旦經(jīng)過調(diào)用,我們馬上經(jīng)過自動化采集,得到了所有接口 Mock。接口的請求,參數(shù)的上傳,以及返回的結(jié)果我們都了如指掌。
那我們該如何使用這些自動采集的 Mock 數(shù)據(jù)呢?接下來一起看看低代碼的第三個問題。

首先,我們需要更強(qiáng)大的 SQL。
一般來講,當(dāng) SQL 無法滿足計算邏輯的時候,我們就需要找開發(fā)人員開發(fā)一個 UDF,比如一個"IP 轉(zhuǎn)城市"的函數(shù),它會注冊到 SQL 的執(zhí)行引擎,你便可以使用這個函數(shù)了。但這樣的方案是需要開發(fā)人員進(jìn)行開發(fā)支持的。
低代碼的方案應(yīng)該怎么設(shè)計呢?我們提供 SQL 的方案是將微服務(wù)注冊進(jìn)執(zhí)行引擎,整個引擎是 Spark SQL 的引擎,它會代替開發(fā)人員發(fā)起微服務(wù)的調(diào)用,會上傳參數(shù),然后再調(diào)度到微服務(wù)里面。Mock 幫助人工進(jìn)行了最快速的 UDF 的注冊,無需要任何成本,馬上便可以通過 SQL 調(diào)用微服務(wù),
例如,當(dāng)我們使用 SQL 調(diào)取微服務(wù)的時候,首先需要知道地址、輸入?yún)?shù)、以及返回值。這個接口返回 data 和 count,為什么你接口返回城市一定是 data?這些都是一些我們在進(jìn)行注冊的時候需要做的工作。

這里有個視頻,大家可以看一下。
00:30
例如選擇一個獲取黑名單的任務(wù),它馬上注冊微服務(wù),這個 UDF 是一個微服務(wù),它就可以被 SQL 使用,大家可以判斷他是不是黑名單了。
整個過程中,用戶只需要非常簡單的四個步驟,SQL 馬上就可以具備微服務(wù)的調(diào)度能力。
此處也會有一些性能上的挑戰(zhàn),當(dāng)使用 Spark 調(diào)用微服務(wù)的時候,性能會出現(xiàn)一些問題。因為如果使用非常傳統(tǒng)的調(diào)動方法,它是一個串行的過程,那么我們這里提了可以供大家參考的方案。

UDF 注冊之后,我們會直接執(zhí)行 SQL,但不會馬上調(diào)用 UDF,將它標(biāo)記起來,呈現(xiàn)出來是一個偽執(zhí)行的狀態(tài),SQL(無 UDF)產(chǎn)生一個中間結(jié)果,我們會將這個中間結(jié)果重新分區(qū),把它打得更散更平均,這樣后續(xù)每個分區(qū)執(zhí)行分派到的 UDF 任務(wù)個數(shù)將會更近平均,避免一些數(shù)據(jù)傾斜的情況。最后在我們偽標(biāo)記的 UDF 的基礎(chǔ)上,我們會啟用整個的異步調(diào)度方案,使用異步 HTTP 完成微服務(wù)調(diào)用,并配套相應(yīng)的緩存以及限流的策略,整體提升請求效率和成功率。
截至到這里,我們通過 SQL+ 微服務(wù)提供了更強(qiáng)大的 SQL,通過了 UDF 的快速注冊,提供給產(chǎn)品人員非常簡潔的操作。這個時候,第一個問題就被完美地解決了。
接下來分享第二個問題的解決方案,CURD 是否還需要開發(fā)接口?
我們通過數(shù)據(jù)平臺產(chǎn)生的數(shù)據(jù)之后,接著需要 CURD 接口。業(yè)界有很多生產(chǎn) CURD 接口的方案,騰訊的 APIJSON 開源方案,它可以做到零代碼生成接口和文檔,并且整個生成過程是自動化。
當(dāng)企業(yè)有元數(shù)據(jù)的時候,馬上就可以獲得接口,不過這個接口暫時不能滿足運(yùn)營系統(tǒng)的需要。這時候需要引入規(guī)則引擎。
我們可以將接口進(jìn)行簡單地編排,采用了 BPMN2.0 協(xié)議實現(xiàn)了同步和異步雙引擎,因此整個規(guī)則引擎可以做任務(wù)流的事情。

Mock 可以幫助整個組件的快速注冊,因為每一個節(jié)點都是微服務(wù),這種 Mock 節(jié)點就可以快速注冊,同時整個微服務(wù)在調(diào)試的過程中,我們生成了任務(wù)工作流,當(dāng)邏輯執(zhí)行完之后,它也會馬上去進(jìn)行 Mock 注冊。
當(dāng)然,當(dāng)我們有了簡單的 CURD 過程,我們可以選擇編排一些參數(shù)校驗。比如,對時間做要求、對權(quán)限做要求,當(dāng)然也可以做一些錯誤返回等的編排工作,最終通過規(guī)則引擎生成完整的查詢接口。
那么經(jīng)過了這一步驟,我們就具備了 SQL 和接口,這時候可以將接口放到頁面呈現(xiàn)。

上圖是我們UI平臺的架構(gòu),跟常規(guī)的低代碼平臺大同小異,這里介紹兩個點:通信邏輯模型和Mock加速前端配置
首先是通信邏輯模型,這個模型解決了組件與組件的通信與行為相應(yīng),當(dāng)一個組件拖出來到頁面后,會馬上分配一個唯一實例 ID,每個實例都會有屬性,會有系統(tǒng)事件或自定義事件。
比如我們現(xiàn)在要實現(xiàn)點擊搜索按鈕后表格組件自動從后端重新獲取最新數(shù)據(jù)并呈現(xiàn)。
那么,我們配置的邏輯大概是這樣的:按鈕實例的 OnClick 事件可以配置觸發(fā)表格實例的 HTTP 時事件。Table 實例的 HTTP 的事件實現(xiàn)拉取數(shù)據(jù)以后,將它寫進(jìn) Value 里面,實現(xiàn)了整個 Table 的數(shù)據(jù)刷新輸出。
其次是 Mock 加速前端配置,有了 Mock 之后,在配置前端的時候可以省去了很多復(fù)制粘貼的工作。當(dāng)我拉取一個表格,可能有很多字段,復(fù)制粘貼將會非常崩潰,這里有 Mock server 的快捷配置以及預(yù)覽,當(dāng)用戶配置完之后,便可以馬上預(yù)覽,來檢查你的配置是否和你的預(yù)期。

我們是如何通過 Mock 快速地配置?
例如,當(dāng)我們配置表格的時候,地址、請求方式、上報參數(shù)、表格輸出等均需要配置。這對于一個配置人員來講,其實成本非常高的,尤其是當(dāng)碰到非常極端的案例的時候,例如,當(dāng)你碰到具備 20 多個字段的時候,它的配置工作將會非常令人崩潰。
00:33
我們的方案是這樣的,一起來看一下這個視頻。
首先拉取一個表格,然后選擇一個微服務(wù)地址,然后自動地獲取參數(shù)。
所有的上報參數(shù),其返回都會全部自動填上,以及基于 Mock 的實時預(yù)覽,馬上就可以擁有。
通過使用 Mock,平臺也可以透過 Mock 平臺進(jìn)行真實的預(yù)發(fā)布環(huán)境的預(yù)覽。
今天的主要三個挑戰(zhàn)都已經(jīng)解決了,有了這樣方案之后,其實對于產(chǎn)品人員來講,可以搞定很多內(nèi)容。
騰訊游戲低代碼的整個數(shù)據(jù)平臺大概支撐了 3000 個任務(wù),后端沉淀的原子接口有 1000 個,整個邏輯可視化模板有 200 個,頁面 600 個等等。
在我們的平臺上層,支撐著很多的應(yīng)用。比如客服系統(tǒng),大家知道王者榮耀的客服系統(tǒng)往往非常復(fù)雜,它會有郵件贈送福利。假設(shè)用戶 30 天沒有領(lǐng)取,這個郵件就會頂替掉,但是有些人會打電話投訴要求補(bǔ)發(fā)福利,這個時候客服需要檢查日志去檢查是否已經(jīng)領(lǐng)取?
這一系列流程之前都是依賴人工,但是現(xiàn)在當(dāng)我們將平臺傳遞給客服的時候,他們利用這套平臺配置邏輯就可以輕松搞定。
當(dāng)然,在平臺的上層,我們也支持運(yùn)維安全 SOAR 以及安全監(jiān)控的一些事情。

說完我們的實踐,談?wù)勎覀兊恼雇?/p>
今天我分享的兩個關(guān)鍵點是元數(shù)據(jù)和 Mock,我們經(jīng)過這兩個元素的頻繁交互,達(dá)成了整個平臺的融合。
回顧整個平臺架構(gòu),我們發(fā)現(xiàn)平臺的所有東西都是微服務(wù),并且所有的微服務(wù)都可以變成 API 使用,整個 SQL 也變得非常的強(qiáng)大。整個數(shù)據(jù)平臺輸出的數(shù)據(jù)都有 CURD,也貢獻(xiàn)回了微服務(wù),微服務(wù)里面的 CURD 同樣貢獻(xiàn)給規(guī)則引擎。這是一種相輔相成的關(guān)系。
最后一部分是關(guān)于我對低代碼未來趨勢的一些思考?,F(xiàn)在低代碼百花齊放,有非常多的低代碼平臺,業(yè)界需要一些規(guī)范,以及如何保證低代碼平臺的質(zhì)量。

上圖是我們整個的騰訊的低代碼架構(gòu)圖。
首先,我們整個騰訊提出了一些方案——騰訊有 UI 可視化邏輯,還有 DSL 整個語言,生產(chǎn)環(huán)境、開發(fā)環(huán)境以后,便會有配套的前端以及后端的 SARS 的能力。整個的低代碼可以用來配置 Web 和 App,可以通過提供一些 Pass 的服務(wù),也可以通過 Open API 或者鉤子做很多事情。
當(dāng)然這里介紹兩個執(zhí)行引擎。作為低代碼,我們有一個基于 Schema 的解析引擎和編譯引擎。解釋引擎可以用 Schema 直接執(zhí)行,編譯引擎更多是從性能角度考慮。編輯引擎可以根據(jù) Schema 轉(zhuǎn)成可運(yùn)行的代碼,希望大家可以了解一下。
其次,再談一下 Schema 與 DSL 的這樣關(guān)系,DSL 可以通過 Pass 模塊轉(zhuǎn)換成 Schema,Schema 是可以被解釋引擎和編譯引擎識別的。在面向用戶的使用方式上,我們支持整個可視化編輯,也就是說,大家可以在頁面進(jìn)行拖拉拽。當(dāng)然如果你不喜歡,也可以無風(fēng)險、無損失地切換到 DSL。
最后,對于一些中小企業(yè)來說,當(dāng)企業(yè)選擇了低碼平臺時候,便馬上會被這個平臺綁架。因為企業(yè)的所有邏輯全部配置在了低代碼平臺,由于其他平臺無法識別 Schema,所以根本無法遷移。
目前騰訊低代碼提出了一個思想——Schema 可以不一樣,因為不同的執(zhí)行引擎或編譯引擎是不同的,它們的 schema 規(guī)范必然也不一樣。但是 DSL 是更上層的語言,就是大部分?jǐn)?shù)據(jù)都支持標(biāo)準(zhǔn)的 SQL 一樣,我們可以抽象 DSL,站在整個低代碼的行業(yè)的角度與立場去抽象 DSL。在我的平臺里面剛才我們講了,其實 Schema 是可以轉(zhuǎn) DSL 的,當(dāng)他真正地想從平臺導(dǎo)出的時候,它其實就可以把 Schema 轉(zhuǎn)成 DSL 打包帶走,然后在另外一個平臺里面導(dǎo)入。
我相信如果大家都這樣做,低代碼綁架業(yè)務(wù)的問題就迎刃而解,整個低代碼的生態(tài)會變得更加健康。
這是我今天的分享,謝謝大家。
— 本文結(jié)束 —
● 漫談設(shè)計模式在 Spring 框架中的良好實踐
關(guān)注我,回復(fù) 「加群」 加入各種主題討論群。
對「服務(wù)端思維」有期待,請在文末點個在看
喜歡這篇文章,歡迎轉(zhuǎn)發(fā)、分享朋友圈
