任務系統:活動組件化實踐初探

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"前言"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"隨着伴魚業務和用戶的快速增長,公司運營活動的形式也越來越豐富,從活動的大類上總結有(包括但不限於):團購活動、排行榜&拉票活動、紅包雨活動、預售秒殺活動、抽獎活動等,這些運營活動對於提升轉化、用戶留存和高用戶活躍度等會起到重要作用,因而運營活動佔用了增長部門非常多的研發資源。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其中,形如:“用戶 A 完成了 W 動作發放 X 獎勵(或者觸發某種邏輯)”這樣形式的需求會比較常見。在初期承接的過程中,各自活動獨立開發,有許多重複的開發量,並且即使是重複的部分仍然需要測試同學的介入,各方都有很大的資源投入,並且還會導致整體流程會很長,通常一個活動開發聯調和測試時間需要兩週左右。所以,高效可複用地進行運營活動是 ROI 非常高的一件事情。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"初探"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"前言中提到了活動中經常出現形如:“用戶 A 完成了 W 動作發放 X 獎勵”這樣形式的需求,如下圖所示,我們將滿足這種語法的需求定義爲一個任務:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/aa\/aa5d60a0384fe2c26433c23c57cea66a.png","alt":"stage","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從圖中,可以看到總會出現相似的部分,例如用戶每日錄繪本發放不同的獎勵、用戶邀請購買發放不同的獎勵、用戶自主簽到等。也有很多不同的部分,例如每次的獎勵不盡相同、可以完成的動作週期不同等,並且可能對接很多的上游服務。爲了快速實現配置化,我們從這些需求中整理出了初版任務系統的目標:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不關心具體動作,以數字簡單區分動作。例如活動 A 中 1 指定代表讀繪本、活動 B 中 2 指定代表邀請購買;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"配置基礎的時間規則;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"儲存任務的相關狀態和數據;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"記錄獎勵發放狀態,但是發放的內容由業務自己維護;"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/55\/55dc4e010303b2d7775a59ebc8620897.jpeg","alt":"流程圖","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如圖所示,在初版系統中,業務方需要完成:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"自行綁定數字和動作的關係;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"業務方通過消費 kafka 隊列或者主動查詢獲取動作指標之後傳遞給系統;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"發放獎勵相關邏輯;"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是,經過「繪本 618」的兩期活動的洗禮後,我們發現這種方式雖然是使用了配置化的形式,卻並沒有達成最初的目標,原因有如下幾點:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"動作和數字的綁定關係有很大的理解成本,且配置風險較高;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"維護消費隊列和活動任務的成本和風險較高;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"重複的任務邏輯,測試同學的時間成本沒有減少,與一開始相比,外在表現並沒有特別多的減少開發成本和測試成本。"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"任務系統"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在調研了"},{"type":"link","attrs":{"href":"https:\/\/blog.csdn.net\/BULpreZHt1ImlN4N\/article\/details\/86611085","title":null,"type":null},"content":[{"type":"text","text":"億級 QQ 會員活動運營系統的設計之道"}]},{"type":"text","text":",並結合了遊戲中各式各樣的任務形式,與伴魚運營活動對比之後,我們重新梳理出伴魚任務系統需要支持的核心功能點:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由系統來理解任務達標動作,減少業務方的理解成本;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"時間規則支持,例如:每日可完成2次、每週可完成3次、整個活動只能完成一次等類似的規則;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用戶主動領取和系統自動發放兩種獎勵形式;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"任務基礎狀態的維護;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"支持任務重置的能力;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"支持配置展示內容的能力;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"相關數據記錄;"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"針對於上面的需求,我們做了如下的抽象:"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"任務狀態流轉"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲任務定義如下幾個狀態:未開始—>未完成—>待領取—>已領取—>已結束,具體狀態流轉如下圖:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/e5\/e5101493e32715180172e7a5fe3da0d2.png","alt":"image-20210331214625941","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"動作校驗"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"主要功能是判斷上圖中 "},{"type":"text","marks":[{"type":"strong"}],"text":"未完成"},{"type":"text","text":" —> "},{"type":"text","marks":[{"type":"strong"}],"text":"待領取"},{"type":"text","text":" 階段用戶是否完成了對應動作。爲了簡化和便於理解,我們調研並選中了第三方的規則校驗包 "},{"type":"link","attrs":{"href":"https:\/\/tech.ipalfish.com\/blog\/2021\/04\/21\/task_system\/github.com\/antonmedv\/expr","title":null,"type":null},"content":[{"type":"text","text":"expr"}]},{"type":"text","text":" ,將用戶複雜的動作整理爲固定的 kv 對,通過 expr 包判斷是否達標。例如,我們定義用戶購買繪本 vip 這個動作爲:{buy_pb_vip: true},用戶購買的不同類型 vip 定義爲:{vip_type: forever},{vip_type: year} 等。如果這時有個任務達標動作爲:“用戶購買繪本 vip 且購買的是永久 vip ”,那麼我們就可以這樣配置達標規則: buy_pb_vip == true && vip_type == “forever” 。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"消費並清洗上游隊列"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"每個動作都對應各自的一些指標。那麼如果任務系統需要理解具體指標內容的話,必須有一個角色爲系統輸入這些信息。此處我們考慮了兩個方案:(1)由指標的生產者來構建內容,然後通知到系統。(2)系統主動對接各個消息隊列,進行整體的內容清洗和理解。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"方案(1)對系統的要求會簡單一些,業務數據是由上層構建的。但是這個方案對於業務代碼入侵比較嚴重,並且從數據生產和使用的流程上來說不是特別順暢。因此我們最終選定了方案(2),以消息隊列作爲系統的輸入變量,認爲每個動作通知都是通過消息隊列遞交給系統。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"整體處理流程包括:接收隊列消息 -> 內容清洗 -> 系統使用。例如:繪本購買 vip 隊列消息。消息中會包含用戶的購買時間,購買的 vip 類型等內容。我們將它清洗成爲系統可以理解的 kv 對,然後讓動作校驗部分去使用。如下圖所示,我們對接了各個業務方的上游隊列,當有新的達標動作需求時,我們只需要新增對接的上游隊列,並更新動作校驗部分 kv 對即可。對於系統主流程來說,這個更新無感知,且測試同學的介入可以控制在新增消息隊列的對接上。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/ba\/baf6179319be91d8f424e8057ed7073f.jpeg","alt":"image-20210402175411947","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"配置項劃分模塊"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們整理了所有配置項,並根據不同的相關功能將其分成了下圖中六類配置組:基礎配置,規則配置,獎勵配置,展示配置,庫存配置,路由配置。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/20\/20e3bf0c994bfd76e330eee4c9c7dc7b.jpeg","alt":"image-20210401160156873","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"經過以上的抽象後,我們的任務系統可以提供下面的能力支持:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"業務方可以優雅對接,不需要額外的理解和冗餘開發;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"新動作可以快速支持,不影響主系統;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"系統打通了活動營銷平臺的基礎活動配置中心,發獎中心,靈活組件服務等模塊化服務;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"支持正式環境與測試環境一鍵導入導出;"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"進一步升級"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在承接活動的過程中又漸漸地發現了新的問題:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"初始設計中,期望系統能夠聚合概念,沉澱一些常用指標作爲複選項。例如:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"規則配置:任務週期(每日)+ 可重複次數(1次)+ 可由前端手動完成(是)= "},{"type":"text","marks":[{"type":"strong"}],"text":"每日可被手動完成一次"},{"type":"text","text":";任務週期(每週)+ 可重複次數(10次)+ 可由前端手動完成(否)= "},{"type":"text","marks":[{"type":"strong"}],"text":"每週可被自動完成10次"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"庫存配置:用戶可完成(不限次) + 任務可被完成(不限次) = "},{"type":"text","marks":[{"type":"strong"}],"text":"不限庫存"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"路由配置:路由跳轉(讀繪本頁)= "},{"type":"text","marks":[{"type":"strong"}],"text":"完成讀繪本任務"},{"type":"text","text":";路由跳轉(繪本vip售賣頁)= "},{"type":"text","marks":[{"type":"strong"}],"text":"完成繪本 vip 售賣任務"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"希望用戶能夠脫離具體的指標概念,減少理解成本,相應的數據庫設計也是同樣的思路和方向。但是在實際使用中,概念的聚合和沉澱並沒有達到設計的目標。通常來講:一方面概念的理解並沒有那麼複雜,聚合操作在實際使用中屬於可有可無的狀態;另一方面我們可以認爲每個任務都是獨立存在的,沒有可複選的內容。最終實現方案導致在實際使用中配置起來極爲複雜,不僅沒有達成預想的目標,還增加了額外的維護成本。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"系統支持的粒度仍然不夠"},{"type":"text","text":"。我們遇到了一類新的需求,如下圖。這裏包含兩個方向的要求:對於任務側,用戶不論何時註冊,都有機會參與此活動,任務應該是長時間有效的;對於用戶側,註冊後不同任務的可完成時間區間均不相同,那麼如何區分這兩個方向不同的時間要求呢?這給我們的系統提出了新的挑戰。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/s04.cdn.ipalfish.com\/static\/omp-upload-1617365635161-%E6%B4%BB%E5%8A%A8%E4%B8%BB%E9%A1%B5%E9%9D%A2%20(1).png","alt":null,"title":null,"style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"展示配置的配置項不足。除開基礎的展示內容,對於特殊的跳轉或者任務交互,前端同學仍然需要獨立開發這部分代碼,沒有節省前端同學實際的開發量。按鈕的配置化內容不足以定義前端多樣化的動作。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"系統各層級響應時間,穩定性需要優化。具體表現例如:清洗後的隊列消息堆積,獲取任務列表時延影響用戶體驗"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"獎勵配置邊界模糊。除開基礎的獎勵發放,還支持了對於業務方的回調邏輯,系統無法脫離隨業務的開發任務。這部分的系統邊界不夠清晰。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"針對於以上問題,我們進行了新版本的開發,分別給出瞭如下的答案:"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"模塊重新劃分"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如下圖所示,通過 taskid 這個任務的唯一標識串聯所有配置模塊。"}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"基礎配置回答了一個任務的基本定義;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下一跳(獎勵)配置回答了用戶達標後到底做什麼,並且給出了清晰地邊界;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"按鈕配置用於下發配置給前端,結合波塞冬或者營銷活動 sdk ,實現快速開發;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"展示配置回答了任務欄展示的整體邏輯和內容;"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/66\/6612244721eaa67eddca9d9d600a1b62.png","alt":"image-20210401210153531","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"定義用戶任務箱\/用戶限時任務"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用戶任務箱:我們可以理解爲每個用戶在每個活動下都有一個類似收件箱的邏輯結構,當我們想讓用戶完成任務A的時候,就給他對應活動的收件箱中發佈這個任務,此時只有這個用戶可以看到並且完成該任務A。特殊的,我們又爲被下發的這條記錄額外定義了屬於它自己的限時時間區間,至此我們就完整的解答了前文中粒度不足的問題。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了與之前的普通劃清邊界,我們特殊的定義了一種任務類型爲:可下發任務,代表該任務只能在某些節點發給用戶來讓用戶完成。簡單流程如下圖所示,由業務方爲用戶下發限時任務,並定義用戶的限時完成時間區間,由系統維護內部任務邏輯。對於業務方來說,類似的需求只需要關心三個部分:限時任務什麼時候發給用戶;用戶的限時區間是多久;限時任務的列表信息從哪裏獲取,回答了這三個問題,就能無痛並且快速接入任務系統能力。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/b4\/b41dd764e5b32f95d24796b0c9382980.png","alt":"image-20210401211410926","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"響應優化"}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"增加多級緩存,redis緩存和內存緩存;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"優化清洗隊列 ;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"併發輸出;"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"系統架構設計"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/06\/0693bf80b05d0cf0a41d5dc9171bf81f.jpeg","alt":"任務系統架構設計","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"整體系統分爲以下三個層次:"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"業務層"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"業務層提供系統輸出能力。包括對內部服務和對客戶端的輸出能力"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"系統層"}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"業務處理:封裝業務數據用作輸出;發放達標獎勵;其他狀態變更輸出到消息隊列;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"動作達標處理:動作規則校驗後,按照當前的庫存和週期等邊界條件判斷是否是系統接收的有效合法動作;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"內部數據維護:維護配置數據,用戶指標,任務狀態變更歷史,各級緩存處理和維護;"}]}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"基礎層"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"系統依賴的一些常用第三方服務和能力:包括消息隊列,發獎中心,基礎活動服務,常用組件服務,阿波羅動態配置等。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過這次升級,任務系統的概念得到了豐富和擴大,此處的“任務”,其本質已經成爲了一個觸發器。因此這個版本我們命名爲了 trigger 版本。"}]},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/86\/865c00de67ba0fb43aacc452a9906825.jpeg","alt":"觸發器","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"研發效率比較"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"沒有任務系統:單個活動開發 + 聯調 > 7天;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"任務系統 test 版本:單個活動開發 + 聯調 = 6天;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"任務系統 v1 版本:配置 + 對接新動作 = 2~3天;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"任務系統 trigger 版本:配置 + 對接新動作 = 1~2天;"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從上面可以看出,隨着任務系統的迭代,極大地減輕了運營活動的開發量。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"後續工作"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"清洗隊列的 kv 對和系統內部的用戶常用屬性定義和取值可以在後期直接對接—— 用戶畫像系統中的業務指標和屬性指標;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"消息隊列清洗後再消費的流程仍然存在更加優雅的實現方式;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"支持打通波塞冬前端頁面配置化開發;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"動作觸發爲主的需求和系統可以參考這套處理流程;"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"參考文獻"}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/blog.csdn.net\/BULpreZHt1ImlN4N\/article\/details\/86611085","title":null,"type":null},"content":[{"type":"text","text":"億級 QQ 會員活動運營系統的設計之道"}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/tech.ipalfish.com\/blog\/2021\/04\/21\/task_system\/github.com\/antonmedv\/expr","title":null,"type":null},"content":[{"type":"text","text":"expr 規則校驗"}]}]}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章