全鏈路營銷|基於事件驅動的流程編排系統 策略中心繫統

papering發表於2024-10-15

全鏈路營銷|基於事件驅動的流程編排系統 https://mp.weixin.qq.com/s/RHXyGaGyp_CK7FJPDqS3Cg

全鏈路營銷|基於事件驅動的流程編排系統

阿里妹導讀

本文主要介紹了 AE 策略中心的技術方案選型與落地實戰。

專案背景

全鏈路營銷是去中心化的運營方式,給使用者發放精細化的營銷權益,打造策略中心繫統。根據使用者的行為記錄使用者的喜好商品,在滿足策略中心規則後,透過 C 端鏈路的觸發實現營銷權益發放和權益表達。

圖片

架構設計

架構調研

當前營銷各應用都是採用 TMF 框架,由中臺提供標準的節點,營銷業務層進行節點編排,每個節點都提供相應的擴充點,可以讓不同營銷工具實現不同的營銷玩法。

圖片

上圖可以看出營銷計算的流程是比較固定的,業務迭代一般在當前流程的節點上進行擴充,TMF 提供的擴充點就是採用策略模式。比如文案構建節點,不同的營銷工具需要返回不同的文案,根據營銷工具型別匹配文案構建類,執行業務規則。

但是全鏈路營銷面向的是玩法層,所以每次迭代的業務流程都是不固定的,對使用者的行為要求是不固定的,對下游的依賴也是變化的。所以根據不同的玩法模板,執行不同的業務流程節點,這樣做後續的擴充性會比較好。

全鏈路營銷具有兩個鏈路:資料準備和權益發放,資料準備階段是使用者行為規則校驗透過後透過 MQ 訊息觸發,權益發放階段是在使用者在訪問某個資源位時,由上游呼叫策略中心觸發。

使用者的每個行為對我們來說都屬於事件,只不過有的是同步觸發,有的是非同步觸發,所以依賴不同的事件來編排不同的業務節點,編排方式可以透過配置中心或者 Java 硬編碼的形式,擴充性和靈活性更高,整體建設了一個基於事件驅動的流程編排系統。

系統架構

策略中心將不同事件透過不同的渠道(channelCode)進行標識,不同的 channelCode 觸發不同的流程編排。

策略中心的程式碼架構整體分為 4 層:

  • 接入層:
    • 使用者的行為校驗,由行為規則域統一收斂,滿足規則後傳送 MQ 訊息通知策略中心
    • 使用者觸發某個資源位的行為,由上游同步通知策略中心
  • 服務層:分渠道進行事件處理,然後統一調到領域層進行策略執行
  • 領域層:策略域包含多個子域,可自主編排多個子域的域能力,最後對外提供策略域能力
  • 基礎層:基礎設施層,包含外域依賴和儲存依賴兩個部分

圖片

流程設計

策略中心整體程式碼流程實現,如下圖所示:

  1. 行為事件:代表使用者完成了某個行為規則,MQ 訊息中攜帶 ruleKey 作為 channelCode,策略中心會透過渠道查詢策略活動,構建策略例項,完成資料的準備階段,包括查詢使用者操作的商品、演算法召回、處理商品折扣等,最後將策略例項的相關資料(商品、流程)儲存到 Redis。
  2. 資源位事件:代表使用者點選了某個資源位,API 的入參中有 channelCode,策略中心同樣進行活動查詢、策略構建,然後從 Redis 中讀取資料準備階段的資料,填充到策略例項,開始進行權益的發放。

圖片

設計說明:

    • 策略例項的驅動邏輯固定,不同玩法對應不同的策略模板,模板會編排不同的節點形成執行器鏈,新增一種玩法只需要新增一個策略模板即可,不會對其他玩法產生影響,擴充性好。
    • 分散式鎖保證同一個策略例項在同一時刻只能被一個執行緒執行,如果行為事件和資源位事件同時執行,會造成資料覆蓋的問題。
    • 不涉及資料覆蓋問題的場景不需要加鎖,所以可以透過入參或者策略模板配置來決定是否加鎖。

模型設計

領域模型

策略域的聚合為 TacticsInstanceContext,也就是上文一直提到的策略例項,聚合根是 TacticsActivity 策略活動。每個策略例項 TacticsInstanceContext 中包含一個策略活動和相關的執行引數以及執行結果,執行引數包含買家 ID、渠道、是否加鎖、是否僅執行最優策略等資訊,所以一個策略活動和一個使用者唯一對應一個策略例項。

TacticsInstanceContext 只包含基礎的策略執行資料,但是策略層有多個子域,各個子域對 Context 的依賴不同,所以需要對策略例項做能力的擴充,常見的方式有:

  • Context 中提供 map 擴充欄位,將所有節點所需的資料統一放入擴充欄位中,Context 中提供充血方法獲取對應的資料。

  • 提供能力擴充的介面,增加 Context 子類實現擴充介面,節點執行前判斷入參是否有該能力,在進行執行。

我們採用介面擴充的方式解決該問題,因為專案的核心設計思想就是策略 + 工廠模式,可以根據不同的策略模板(templateType)構建不同的 Context。

比如全鏈路營銷 3.0 版本需要使用者的商品資料,所以進行介面 IItemContext 的擴充:

圖片

策略模板

每種玩法對應一種策略模板,目前有全鏈路營銷 2.0 和全鏈路營銷 3.0 兩個模板,所以透過模板工廠去獲取模板的配置:

圖片

上圖可以看出,getProcessorChain() 提供了核心的流程編排能力,因為每個事件對應一個 channelCode,所以流程編排是基於事件標識來完成,程式碼示例:

public List<String> getProcessorChain(String channelCode) {    List<String> processorChain = Lists.newArrayList();    // channelCodeA 或 channelCodeB 理論上都是一個可配置的Set集合,這裡進行簡化    if ("channelCodeA".equals(channelCode)) {        // 查詢商品        processorChain.add(QueryacticsProcessor.PROCESSOR_NAME);        // 處理商品營銷資料        processorChain.add(HandleItemPromotionTacticsProcessor.PROCESSOR_NAME);        // 記錄行為事件消費成功        processorChain.add(EventTacticsProcessor.PROCESSOR_NAME);    } else if ("channelCodeB".equals(channelCode)) {        // 校驗行為事件是否消費成功        processorChain.add(CheckEventTacticsProcessor.PROCESSOR_NAME);        // 規則校驗        processorChain.add(RuleCheckTacticsProcessor.PROCESSOR_NAME);        // 查詢資產        processorChain.add(QueryAssetTacticsProcessor.PROCESSOR_NAME);        // 權益發放        processorChain.add(SendBenefitTacticsProcessor.PROCESSOR_NAME);        // 構建結果        processorChain.add(BuildResultTacticsProcessor.PROCESSOR_NAME);    }
return processorChain;}

節點模型

介面類:

public interface TacticsProcessor {  /**     * 節點名稱     */    String getProcessorName();
/** * 策略例項匹配校驗 */ boolean validate(TacticsInstanceContext instanceContext);
/** * 策略例項執行邏輯 */ void process(TacticsInstanceContext instanceContext);
}

擴充子類:

圖片

冪等設計

業務玩法是迴圈發放權益,但是隻有當前使用者不存在可用的資產(未領取、過期、核銷等),才進行發放。

權益系統可以保證一個冪等 ID 只會進行一次的資源扣減和資產的寫入動作,並且當一次請求失敗時,權益系統內部會主動重試或回滾,所以策略中心為了防止超發問題,做了兩件事:

  • 保證冪等 ID 的唯一性,可重入性;
  • 當存在可用的資產時,直接返回該資產,不進行權益發放;

圖片

當使用者資產表查詢出現抖動或者其他情況時,我們將發放的次數置為 0,第幾次發放 willSendCnt 置為 1。如果使用者是第一次領取,那麼會執行真正的權益發放,符合業務流程;如果使用者非首次領取,因為相同的冪等 ID 只會扣減一次資源,所以不會造成超發。

專案總結

本文主要介紹了 AE 策略中心的技術方案選型與落地實戰。從最初版的邏輯平鋪的技術設計,到基於事件驅動的流程編排系統,我們做了系統架構的最佳化和提升,未來可擴充性更強,業務迭代只需要增加新的的策略模板和節點即可,不會影響其他策略模板邏輯,符合開閉原則。

相關文章