规则引擎:大厂营销系统资格设计全解
業(yè)務(wù)進(jìn)行營銷活動(dòng)目的是用最少的錢實(shí)現(xiàn)更好的營銷效果,此時(shí)就需要針對(duì)營銷活動(dòng)的資格進(jìn)行控制,其中就包括了用戶身份、用戶所處的環(huán)境等等一系列因素的考慮,且為了防止惡意套取營銷費(fèi)用和做到營銷效果的持續(xù)性,會(huì)進(jìn)行活動(dòng)相關(guān)次數(shù)的控制。此時(shí)為了適應(yīng)業(yè)務(wù)不斷變革的營銷活動(dòng)資格,好的資格設(shè)計(jì)就非常重要。
營銷活動(dòng)業(yè)務(wù)在配置中會(huì)同一時(shí)間存在多個(gè)營銷活動(dòng),用戶進(jìn)入某個(gè)場景,首先需要給用戶展示目前用戶能夠享受的營銷活動(dòng),增加用戶參與此場景的意向,然后用戶參與場景后需要給用戶提示對(duì)應(yīng)的營銷活動(dòng),用戶如果沒有參與成功需要給用戶提示具體沒有參與成功的原因。那么在參與前,具體的場景中需要進(jìn)行用戶資格的校驗(yàn),并且用戶參與后需要進(jìn)行資格記錄。
同時(shí),資格校驗(yàn)?zāi)軌蛴行Х乐褂脩糁貜?fù)參與的問題,通過配置用戶的次數(shù)資格來進(jìn)行校驗(yàn),用戶參與成功一次進(jìn)行記錄,后面用戶參與前對(duì)次數(shù)資格進(jìn)行相關(guān)的校驗(yàn)。
資格分類
資格設(shè)計(jì)先要針對(duì)資格進(jìn)行分類,通過不同的分類進(jìn)行各自分類領(lǐng)域模塊設(shè)計(jì)。分類的原則是分層漏斗分類:優(yōu)先過濾大量不滿足、消耗服務(wù)器資源較少的活動(dòng),再過濾需要消耗服務(wù)器資源較多的活動(dòng),最后是進(jìn)行風(fēng)控資格校驗(yàn)。按照這個(gè)分類原則后面可能會(huì)出現(xiàn)多個(gè)營銷活動(dòng),這個(gè)是另外一個(gè)話題—營銷推薦設(shè)計(jì)。
以上是目前蘇寧金融這邊針對(duì)資格設(shè)計(jì)的分類:靜態(tài)資格、動(dòng)態(tài)資格和風(fēng)控資格。此處風(fēng)控資格校驗(yàn)作為獨(dú)立的一個(gè)分類并且放在最后,主要是由兩個(gè)方面考慮:(1)風(fēng)控的內(nèi)容很多,在蘇寧金融有專門的風(fēng)控中心來進(jìn)行風(fēng)控規(guī)則的制定和執(zhí)行;(2)風(fēng)控返回的風(fēng)控級(jí)別也有很多,營銷活動(dòng)的不同、觸發(fā)風(fēng)控的級(jí)別不同,對(duì)應(yīng)的營銷活動(dòng)處理邏輯也不一樣。
下面針對(duì)以上的分類的靜態(tài)資格和動(dòng)態(tài)資格進(jìn)行相關(guān)的領(lǐng)域模塊具體設(shè)計(jì)探討。
靜態(tài)資格
靜態(tài)資格在蘇寧金融營銷中的定義是:用戶進(jìn)入具體場景、當(dāng)時(shí)用戶屬性標(biāo)簽的一個(gè)靜態(tài)數(shù)據(jù)。
靜態(tài)數(shù)據(jù)的獲取方面主要通過兩個(gè)部分獲取:(1)上游系統(tǒng)的傳遞,這個(gè)數(shù)據(jù)主要是獲取用戶所處的場景數(shù)據(jù),包括但不限于:用戶當(dāng)前進(jìn)行的業(yè)務(wù)及業(yè)務(wù)數(shù)據(jù)、用戶使用終端、網(wǎng)絡(luò)環(huán)境等等數(shù)據(jù)。(2)用戶屬性標(biāo)簽的大數(shù)據(jù)獲取。在蘇寧金融大數(shù)據(jù)中心有一套完整的用戶實(shí)時(shí)標(biāo)簽庫,用戶請(qǐng)求后通過次標(biāo)簽庫實(shí)時(shí)查詢用戶目前的標(biāo)簽。
靜態(tài)數(shù)據(jù)的過濾在技術(shù)方案中適合采用規(guī)則引擎進(jìn)行相關(guān)資格校驗(yàn)。目前在蘇寧金融的營銷系統(tǒng)中使用 Drools,主要是考慮以下幾個(gè)方面:
(1) 業(yè)務(wù)規(guī)則較多,如果使用編碼方式新增規(guī)則就需要進(jìn)行相關(guān)的編碼,增加代碼量和維護(hù)成本。
(2) Drools 的自定義關(guān)系操作符:通過自定義關(guān)系操作符可以針對(duì)不同的業(yè)務(wù)規(guī)則配置需要的操作符還可以針對(duì)每個(gè)活動(dòng)不能匹配的原因進(jìn)行內(nèi)部埋點(diǎn)記錄,方便運(yùn)營進(jìn)行客訴查詢。
(3) 純 java 實(shí)現(xiàn),學(xué)習(xí)成本低。
業(yè)務(wù)配置生成 drl 文件設(shè)計(jì)
關(guān)于生成 drl 文件的設(shè)計(jì),先來看看 drools 引擎原理:
Drools 引擎通過每個(gè)條件進(jìn)行匹配,最終匹配出相關(guān)的活動(dòng),所以在設(shè)計(jì)中需要考慮最終返回的數(shù)據(jù)是活動(dòng)集合。
Drl 文件組成:
通過原理及文件組成,設(shè)計(jì) Drl 文件生成的類圖如下:
writeRuleFile 是入口,通過入口進(jìn)行內(nèi)部方法組裝,此方法需要功能是組裝文件內(nèi)容和寫文件;writeDrlHead 方法為寫文件頭部包、引用和全局變量定義;assembleEvaluatorDefinition 方法是組裝自定義操作符規(guī)則;getActRuleWhenCondition 此方法為拼接規(guī)則字符串;writeActivityRule 此方法為活動(dòng)的規(guī)則寫入。
以上是一種純 java 代碼實(shí)現(xiàn) Drl 文件生成的一個(gè)方式,目的是為了讓大家能夠理解 Drl 文件的結(jié)構(gòu)。實(shí)際操作過程中也可以通過 freemarker 模版來生成對(duì)應(yīng)的 Drl 文件。
Drools 規(guī)則加載
此處規(guī)則加載設(shè)計(jì)可以設(shè)計(jì)為內(nèi)置定時(shí)器掃描規(guī)則生成表是否有新增記錄或者采用分布式集群通知的方式進(jìn)行加載。
目前,蘇寧內(nèi)部的統(tǒng)一配置平臺(tái)采用的是自研的 SCM 平臺(tái),能夠很好地支持實(shí)時(shí)修改,應(yīng)用服務(wù)器集群每臺(tái)應(yīng)用監(jiān)聽具體某個(gè)配置文件的內(nèi)容變更。
應(yīng)用服務(wù)器監(jiān)聽到需要進(jìn)行 Drl 文件 加載后,通過拉取 Drl 文件,并讀取其中的內(nèi)容生成對(duì)應(yīng)的 KieBase。
靜態(tài)資格匹配
為了更加通用性在設(shè)計(jì)中可以設(shè)置規(guī)則匹配的入?yún)?Map 形式,在進(jìn)行匹配前需要把靜態(tài)資格數(shù)據(jù)轉(zhuǎn)化為 Map 數(shù)據(jù)格式,然后在生成的 KieBase 中獲取 KieSession,通過此 KieSession 進(jìn)行規(guī)則匹配。
KieSession 需要設(shè)置全局的一個(gè)集合,來返回匹配到相關(guān)活動(dòng)編碼數(shù)據(jù),同時(shí)需要考慮活動(dòng)是有狀態(tài)和有效期的,所以在拿到靜態(tài)數(shù)據(jù)匹配的活動(dòng)編碼后,需要對(duì)活動(dòng)的狀態(tài)進(jìn)行篩選,拿到的是生效且在有效期范圍內(nèi)的活動(dòng)。
動(dòng)態(tài)資格
此處動(dòng)態(tài)資格主要是指活動(dòng)的次數(shù)和用戶次數(shù)。營銷活動(dòng)為了能夠使更多的用戶能夠參與,防止某些用戶的重復(fù)參與,會(huì)對(duì)用戶的每日、每月、總參與次數(shù)進(jìn)行限制,同時(shí)活動(dòng)的經(jīng)費(fèi)是有限的,為了能夠使?fàn)I銷活動(dòng)效果做的更好,也會(huì)對(duì)活動(dòng)的每日、每月、總次數(shù)進(jìn)行限制。
動(dòng)態(tài)資格設(shè)計(jì)可以分為兩個(gè)維度,一個(gè)是對(duì)象,一個(gè)是周期:
通過上圖設(shè)計(jì),周期維度確認(rèn)好后變更的可能性比較小,可以在前期調(diào)研階段確認(rèn)好周期范圍。不過,對(duì)象變更相比較周期而言會(huì)更頻繁,前期系統(tǒng)上線的時(shí)候確認(rèn)一個(gè)自然人可能只有帳號(hào)、綁定手機(jī)兩個(gè)屬性,后期通過系統(tǒng)的不斷迭代及技術(shù)的不斷進(jìn)步這個(gè)屬性可能會(huì)進(jìn)行擴(kuò)容。所以,在進(jìn)行架構(gòu)設(shè)計(jì)的時(shí)候需要考慮具體對(duì)象的擴(kuò)展性。同時(shí),為了高并發(fā)的查詢、次數(shù)的扣減或者回滾,可以通過緩存來代替數(shù)據(jù)庫的記錄和操作,當(dāng)然為了保證數(shù)據(jù)的可恢復(fù)性,可以設(shè)計(jì)實(shí)時(shí)緩存,異步落庫的操作。
動(dòng)態(tài)資格組裝
資格組裝按照分析,采用抽象類封裝內(nèi)部實(shí)現(xiàn),每個(gè)對(duì)象通過繼承抽象類,實(shí)現(xiàn)具體的抽象方法的方式來實(shí)現(xiàn)。
抽象類 AbstractDimensionDynamic 中有兩個(gè)抽象方法獲取對(duì)象 targetType 和獲取對(duì)象值 targetValue 是在具體類中進(jìn)行實(shí)現(xiàn)。dynamicAssemble 方法是進(jìn)行 dynamicKey 的拼接并組裝動(dòng)態(tài)資格的具體對(duì)象,最終得到動(dòng)態(tài)資格對(duì)象的集合。
AbstractDimensionDynamic 的子類是具體的動(dòng)態(tài)資格對(duì)象,每增加一個(gè)對(duì)象,通過增加子類的方式來實(shí)現(xiàn)。
動(dòng)態(tài)資格服務(wù)
此處設(shè)計(jì)中 DynamicService 對(duì)外提供的是動(dòng)態(tài)資格校驗(yàn)和動(dòng)態(tài)資格扣減兩個(gè)服務(wù),在實(shí)際過程中還會(huì)存在回退的服務(wù),這個(gè)需要自行進(jìn)行擴(kuò)展。
抽象類 AbstractDynamicService 中的 dimensionDynamics 是一個(gè) List,并且注解為 @Autowired,Spring 會(huì)自動(dòng)從容器中取出 DimesionDynamic 的實(shí)現(xiàn)類裝配到 List 類型的 dimensionDynamics 中,從而簡化了依賴注入的過程,并且有新增實(shí)現(xiàn)類的時(shí)候系統(tǒng)啟動(dòng)會(huì)自動(dòng)注入。
@Autowiredprivate List<DimensionDynamic> dimensionDynamics; @Resourceprivate RedisService redisService;復(fù)制代碼
其中的 assembleDynamicRecordList 方法是通過遍歷 dimensionDynamics,組裝需要的查詢或者扣減的動(dòng)態(tài)數(shù)據(jù)記錄;rollback 方法是扣減出現(xiàn)異常或者扣減超過限制后進(jìn)行回滾使用的操作,此方法需要拋出異常,供上游判斷是否需要進(jìn)行處理。
緩存使用 Redis,主要是考慮在 redis 中的 incrBy 和 decrBy 都是原子性操作,這個(gè)在高并發(fā)的場景中防止由于并發(fā)導(dǎo)致的累計(jì)錯(cuò)誤問題。而且 redis 的 mget 命令可以批量查詢,主要是由于 redis 使用基于 RESP 協(xié)議的 rpc 接口,而 redis 本身的數(shù)據(jù)結(jié)構(gòu)非常高效,所以 IO 和協(xié)議解析是個(gè)不容忽略的資源消耗。通過 mget 將多個(gè) get 請(qǐng)求匯聚成一條命令,可以大大降低網(wǎng)絡(luò)、rpc 協(xié)議解析的開銷,從而大幅提升緩存效率。
DynamicServiceImpl 是 DynamicService 的具體實(shí)現(xiàn),并且要繼承 AbstractDynamicService 抽象類。需要實(shí)現(xiàn) dynamicChack 動(dòng)態(tài)資格校驗(yàn)和 dynamicDeduction 動(dòng)態(tài)資格扣減方法。
動(dòng)態(tài)資格校驗(yàn)是通過組裝的動(dòng)態(tài)記錄數(shù)據(jù)集,到緩存中查詢目前存儲(chǔ)的值跟對(duì)應(yīng)動(dòng)態(tài)資格最大值進(jìn)行比較,當(dāng)緩存值大于等于最大值表示動(dòng)態(tài)資格校驗(yàn)不通過。
動(dòng)態(tài)資格扣減使用緩存的 incrBy 進(jìn)行累加,這塊需要針對(duì)每個(gè)累加后進(jìn)行判斷來減少跟緩存的交互,并且需要把已經(jīng)累加的數(shù)據(jù)進(jìn)行記錄,提供回滾資格使用。
以上是針對(duì)營銷系統(tǒng)的資格設(shè)計(jì)的一個(gè)設(shè)計(jì)思路和相關(guān)實(shí)踐的簡單案例,在具體設(shè)計(jì)中需要考慮的問題比案例中的更加復(fù)雜。比如:用戶資格不滿足原因的輸出、異步動(dòng)態(tài)資格數(shù)據(jù)入庫處理、動(dòng)態(tài)資格校驗(yàn)返回所有不滿足原因等等。這些就需要進(jìn)行相關(guān)的擴(kuò)展和針對(duì)目前公司的基礎(chǔ)配套設(shè)施的情況進(jìn)行選擇設(shè)計(jì)。
總結(jié)
以上是生活随笔為你收集整理的规则引擎:大厂营销系统资格设计全解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Golang 规则引擎原理及实战
- 下一篇: Android/Java中使用Proto