优酷播控实践:基于规则引擎的投放管控模型
簡介:?我們在很多場景下需要規(guī)則引擎將規(guī)則運算和業(yè)務(wù)解耦,但規(guī)則引擎不是銀彈。如果規(guī)則很簡單,或者變化頻次非常低那么使用 if-else 可能是最行之有效的實現(xiàn)方式,引入規(guī)則引擎反而增加維護成本。需要根據(jù)具體的業(yè)務(wù)形態(tài)選擇是否使用規(guī)則引擎,以及要是什么樣的規(guī)則引擎。
作者| 阿里文娛高級開發(fā)工程師 王士欣
一、規(guī)則引擎介紹
1. 為什么需要規(guī)則引擎
在很多企業(yè)的業(yè)務(wù)系統(tǒng)中,經(jīng)常會有大量的業(yè)務(wù)規(guī)則配置,而且隨著企業(yè)管理者的決策變 化,這些業(yè)務(wù)規(guī)則也會隨之發(fā)生更改。例如,通信運營商的優(yōu)惠活動:
1)用戶的每月使用總額比上月提高 1 成,超出部分可以享受 6 折優(yōu)惠;
2)長途話費超出 200 的,超出部分可以享受八折優(yōu)惠。
如果用代碼實現(xiàn),if-else 可以很容易的實現(xiàn)上面的判斷邏輯。當規(guī)則變化時我們需要修改 這個 if-else 判斷邏輯。如果只是這樣的邏輯改起來也簡單。那么如果再添加新的規(guī)則呢?比如:
1)用戶的每月使用總額比上月提高 1 成,超出部分可以享受 6 折優(yōu)惠;
2)長途話費超出 200 的,超出部分享受八折優(yōu)惠;
3)網(wǎng)費超出 200 的,市話可以享受 5 折優(yōu)惠,但有一個最高上限,即最多優(yōu)惠 50 元;
4)使用增值服務(wù)的用戶,每月月租減少 10 元;
5)對于月消費不確定的用戶可以簽訂保底合同,即每月必須要消費到一定的額度,如果不 足將以保底額度來進行計算,超出的費用可以給予半價優(yōu)惠。
雖然規(guī)則就這五條,編程得話會有很多的 if 語句,并且有很多嵌套的 if-else 語句,而且很 難實現(xiàn)且難維護。當規(guī)則需要變更時,為避免牽一發(fā)動全身,需要投入很多精力對改動進行測試。
這時就需要規(guī)則引擎將規(guī)則計算邏輯和業(yè)務(wù)系統(tǒng)解耦。
2. 什么是規(guī)則引擎
規(guī)則引擎是一種推理引擎,它是根據(jù)已有的事實,從規(guī)則知識庫中匹配規(guī)則,并處理存在 沖突的規(guī)則,執(zhí)行最后篩選通過的規(guī)則。因此,規(guī)則引擎是人工智能(AI)研究領(lǐng)域的一部分, 具有一定的選擇判斷性、人工智能性和富含知識性。目前,比較流行的規(guī)則引擎有商業(yè)規(guī)則引 擎 iLog 和開源規(guī)則引擎 drools。
3. drools 規(guī)則引擎簡介
Drools 具有一個易于訪問企業(yè)策略、易于調(diào)整以及易于管理的開源業(yè)務(wù) 規(guī)則引擎,符合 業(yè)內(nèi)標準,速度快、效率高。業(yè)務(wù)分析師或?qū)徍巳藛T可以利用它輕松查看業(yè)務(wù)規(guī)則,從而檢驗 已編碼的規(guī)則是否執(zhí)行了所需的業(yè)務(wù)規(guī)則。其前身是 Codehaus 的一個開源項目叫 Drools,最 近被納入 JBoss 門下,更名為 JBoss Rules,成為了 JBoss 應(yīng)用服務(wù)器的規(guī)則引擎。
簡而言之,drools 是一個被廣泛應(yīng)用的、高效的開源規(guī)則引擎。使用 drools 有一定的學(xué)習(xí) 成本,初次接觸時各種名詞:kie、fact、rete、Agenda、rules 等讓人眼花繚亂。最常見的 drools 架構(gòu):
上圖中,rules 即人工設(shè)置的規(guī)則文件,facts 為業(yè)務(wù)參數(shù),inference engine 即推理引擎,即 做具體的規(guī)則匹配運算。
使用 drools 步驟:
1)準備規(guī)則文件,Drools 支持四種規(guī)則描述文件,分別是:drl 文件、xls 文件、brl 文 件和 dsl 文件,其中,常用的描述文件是 drl 文件和 xls 文件,而 xls 文件更易于維護,更直觀,更為被業(yè)務(wù)人員所理解;
2)系統(tǒng)啟動時,使用 drools 的 sdk 加載規(guī)則文件并編譯成字節(jié)碼。這需要我們封裝 drools的 jar 包,讀取規(guī)則文件并完成編譯動作。編譯完成后規(guī)則文件將作為字節(jié)碼存儲在內(nèi)存中;
3)業(yè)務(wù)系統(tǒng)調(diào)用規(guī)則引擎進行規(guī)則匹配。調(diào)用規(guī)則引擎同樣是使用 drools 的 jar 包提供的api。業(yè)務(wù)系統(tǒng)需要將當前場景下的業(yè)務(wù)參數(shù)傳到規(guī)則引擎。
4. 優(yōu)酷播放控制系統(tǒng)規(guī)則引擎簡介
上面簡述了規(guī)則引擎,以及使用廣泛的 drools,此處沒有做深入介紹,drools 是基于 rete算法實現(xiàn)的,這也是 drools 規(guī)則引擎的精髓所在,感興趣的同學(xué)深入研究 drools 以及 rete 算法。
在優(yōu)酷播放控制場景下,我們并沒有使用 drools 這樣的開源規(guī)則引擎,而是自研了更加輕 量級的規(guī)則引擎。這是從開發(fā)的效率,運營的靈活性,以及實際場景出發(fā)來考慮。比如一組 drools 規(guī)則是解決一個場景下的規(guī)則計算問題,比如優(yōu)惠券發(fā)放,產(chǎn)品積分計算等,都可以根據(jù)需要 編寫一組規(guī)則來實現(xiàn)。而對于播放控制場景,由于各個視頻版權(quán)方的要求等原因,每個視頻的 播放控制策略都可能不同,即對于不同的視頻來說,對應(yīng)的播放策略都是不一樣的。這就沒辦 法使用確定的多組 drools 規(guī)則來 cover 所有視頻的播放控制策略。
此外,播控自研規(guī)則引擎,在性能、可視化、開發(fā)運營效率方面都有很大優(yōu)勢。 下面會來介紹播放控制系統(tǒng)的規(guī)則引擎的實現(xiàn)思路。
二、優(yōu)酷播控規(guī)則引擎技術(shù)實現(xiàn)
優(yōu)酷播放控制系統(tǒng)是在點播和直播場景下對視頻的投放做精細化的控制,包括在搜索、首頁、頻道、推薦、直播,等各個場景下,均需要依賴播放控制系統(tǒng)的投放許可。此外,播放控 制系統(tǒng)還會對版權(quán)保護做精細化控制,根據(jù)端的細分情況,對端上的 drm 版權(quán)保護(Digital Rights Management, 數(shù)字版權(quán)管理),清晰度進行控制。
1. 技術(shù)挑戰(zhàn)
1)性能挑戰(zhàn)
播控系統(tǒng)調(diào)用規(guī)則引擎的 qps 為百萬級別。所以對規(guī)則引擎的性能要求很高。在計算過程 中每多產(chǎn)生一些負荷,就會被無限的放大。系統(tǒng)要求接口 rt 在毫秒級別。
2)投放的精細化控制 上文提到,優(yōu)酷的各個場景都需要依賴播控的播放許可,由于版權(quán)方要求以及支持靈活的
運營策略,播放控制系統(tǒng)需要支持維度高達數(shù)十種,并且在不斷的擴充中。這需要規(guī)則引擎支持可靈活擴展的維度支持。
2. 規(guī)則引擎技術(shù)實現(xiàn)
自研規(guī)則引擎只關(guān)注規(guī)則匹配運算,與業(yè)務(wù)無關(guān)。即規(guī)則引擎會返回當前的參數(shù)與策略是 否匹配,業(yè)務(wù)系統(tǒng)根據(jù)規(guī)則引擎返回的匹配結(jié)果來判斷匹配規(guī)則后的處理邏輯。架構(gòu)如下:
1)相對于 drools 的規(guī)則存儲在規(guī)則文件中,播控自研規(guī)則引擎的規(guī)則存儲在數(shù)據(jù)庫中,定 義規(guī)則表用于存儲于業(yè)務(wù)無關(guān)的規(guī)則。添加策略的頁面示例如下圖所示,將原因分類即一個規(guī) 則維度,內(nèi)容分類為開一個規(guī)則維度。落庫時以 key-value 的形式存儲在數(shù)據(jù)庫。比如下圖中的 原因分類,在 db 中的 key=reasonType,value=H。
上文中提到過,每個視頻的投放規(guī)則都可能不同,所以需要針對各個視頻配置專屬的投放 規(guī)則。即定義視頻和投放規(guī)則的關(guān)聯(lián)表。用于存儲視頻和規(guī)則的關(guān)聯(lián)關(guān)系。
2)當系統(tǒng)啟動時,規(guī)則引擎讀取規(guī)則表中的全部規(guī)則,解析后存儲在規(guī)則引擎持有的容器中。
3)當業(yè)務(wù)系統(tǒng)接收到接口請求查詢投放規(guī)則時,首先會根據(jù)視頻查詢所屬于當前視頻的規(guī)則。
4)查詢到所屬視頻的規(guī)則后,將規(guī)則 id 以及當前用戶的環(huán)境參數(shù)傳遞給規(guī)則引擎進行規(guī) 則運算。規(guī)則引擎將計算規(guī)則是否匹配,返回結(jié)果后業(yè)務(wù)系統(tǒng)再封裝具體的接口返回結(jié)果。
3. 規(guī)則引擎計算流程
播控規(guī)則引擎支持分層運算,即對一組規(guī)則,劃分多個層次,每一層有一個優(yōu)先級。這個 效果和 drools 的 salience 一樣,drools 中的 salience 表示權(quán)重,權(quán)重越大優(yōu)先級越高。劃分好層 次之后,每一層會有多條規(guī)則,每一條規(guī)則中又包含多個維度。
假設(shè)圖 4 作為一個規(guī)則,那么在數(shù)據(jù)庫中的存儲為:{"reasonType":"H", "contentCategory":" 電視劇;電影;綜藝;少兒"}。規(guī)則引擎解析規(guī)則后存儲在規(guī)則容器中的數(shù)據(jù)結(jié)構(gòu)非常簡單,即 Map>。
圖 5 中的單個維度計算也就變的非常的簡單,假設(shè)當前業(yè)務(wù)參數(shù) contentCategory=綜藝,判 斷當前維度是否匹配,只需一行代碼:
4. 自研規(guī)則引擎優(yōu)勢
1)高性能
從上面的介紹可以看到,規(guī)則的匹配只用到的set.contains 操作,過程中無需額外創(chuàng)建對象, 操作非常的高效。我們在使用這種計算方式之前,是采用了另一種計算方式,需要在計算過程 解析規(guī)則的expression(即規(guī)則表達式),這導(dǎo)致計算過程中會產(chǎn)生一些中間對象,對 gc 產(chǎn)生壓 力。在文章開頭有提到過,規(guī)則引擎的計算 qps 在百萬級別,每次計算產(chǎn)生的 gc 壓力會被放大 到影響系統(tǒng)性能。如下圖,在使用新的計算方式后 gc 次數(shù)降低了一半之多,并且接口 rt 同樣降低了有一半,效果非常明顯。
2)可視化
相對于 drools 的規(guī)則是使用 drl 文件或者 excel 管理,播控的規(guī)則是可以界面可視化操作的(如圖 4)。這對規(guī)則變更是高頻操作的場景較為關(guān)鍵。
3)規(guī)則可調(diào)試
使用過 drools 的人應(yīng)該有這個苦惱,drools 規(guī)則是編寫好規(guī)則文件,然后將文件編譯成 java 字節(jié)碼存儲在drools 容器中。在運行過程中無法調(diào)試,只能通過引擎的返回結(jié)果判斷規(guī)則是否正確,當不符合預(yù)期時定位問題比較麻煩。播控自研的規(guī)則引擎如上所述直接 java 代碼運行支 持 debug,有助于提高開發(fā)效率。
三、總結(jié)
我們在很多場景下需要規(guī)則引擎將規(guī)則運算和業(yè)務(wù)解耦,但規(guī)則引擎不是銀彈。如果規(guī)則很簡單,或者變化頻次非常低那么使用 if-else 可能是最行之有效的實現(xiàn)方式,引入規(guī)則引擎反而增加維護成本。需要根據(jù)具體的業(yè)務(wù)形態(tài)選擇是否使用規(guī)則引擎,以及要是什么樣的規(guī)則引擎。
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的优酷播控实践:基于规则引擎的投放管控模型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何选择分布式事务解决方案?
- 下一篇: 双面黄琳:世界顶级女黑客,两个孩子的迟钝