成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

嗶哩嗶哩直播通用獎勵系統(tǒng)揭秘

開發(fā) 架構(gòu)
通用獎勵系統(tǒng)的設(shè)計需要從分別從需求側(cè)和供給側(cè)兩個方向入手:一是發(fā)放場景接入,二是獎品類型接入,獎勵系統(tǒng)為二者制訂了接入標準,方便進行后續(xù)的擴展維護。

背景

B站直播平臺近年來迅猛發(fā)展,為了吸引更多觀眾和優(yōu)質(zhì)主播,直播平臺通常會推出多樣玩法(包括節(jié)日活動、任務(wù)、榜單、抽獎),以激勵用戶參與和創(chuàng)造高質(zhì)量內(nèi)容,拉動平臺營收,豐富直播生態(tài)。諸多玩法都存在一個共同的場景:給用戶發(fā)放獎勵。為了滿足獎品種類以及發(fā)放場景的多樣性,我們設(shè)計了通用獎勵系統(tǒng),用于支撐各類上層業(yè)務(wù)。本文將介紹直播獎勵系統(tǒng)的技術(shù)架構(gòu),從需求分析到實現(xiàn)細節(jié),全面解析其背后的技術(shù)方案。

圖片圖片

需求分析

通用獎勵系統(tǒng)的設(shè)計需要從分別從需求側(cè)和供給側(cè)兩個方向入手:一是發(fā)放場景接入,二是獎品類型接入,獎勵系統(tǒng)為二者制訂了接入標準,方便進行后續(xù)的擴展維護。

圖片圖片

從業(yè)務(wù)接入來看,獎勵系統(tǒng)需要滿足各類上游場景的發(fā)放,如:榜單截榜后發(fā)獎、任務(wù)完成發(fā)獎、抽獎發(fā)獎、競猜開獎發(fā)獎等諸多場景,因此接入方式既要足夠標準化又要兼容差異化。

從獎品類型來看,獎勵存在多樣性,既包含頭像框、頭銜、房間皮膚等權(quán)益類獎品,又包含電池、金倉鼠、包裹道具等價值類獎品,不同的獎品各自所需的配置屬性不同,由不同的下游發(fā)放,且每個下游吞吐能力也不一致,獎勵系統(tǒng)在處理獎勵發(fā)放時需要分別設(shè)置不同的發(fā)放限流閾值以防止擊垮下游。

從發(fā)放時效來看,業(yè)務(wù)能級有高低之分,高能級的業(yè)務(wù)場景發(fā)放延遲會造成用戶體驗下降,甚至?xí)l(fā)客訴輿情,因此需要有獨立的發(fā)放通道專門用于保障高優(yōu)業(yè)務(wù)。

最后作為一個值得被信任的獎勵系統(tǒng),一定要滿足這三個特點:低延遲、不超發(fā)、不漏發(fā)。

架構(gòu)介紹

基于獎勵上游業(yè)務(wù)方多、峰值流量高、穩(wěn)定性要求高的特點,為求高峰值流量下獎勵系統(tǒng)的穩(wěn)定可靠,方案選型時選擇了基于消息隊列削峰、異步處理請求的總體方案。以下是獎勵系統(tǒng)整體架構(gòu)圖:

圖片圖片

系統(tǒng)架構(gòu)包括:

  • 接入層:負責(zé)制定業(yè)務(wù)接入標準,提供業(yè)務(wù)源注冊、獎勵發(fā)放、回收、獎品佩戴、取消佩戴等功能;
  • 配置層:按照業(yè)務(wù)所需配置各類獎勵包裹,如:排行榜發(fā)獎、主播任務(wù)發(fā)獎、獎池抽獎發(fā)獎,同時還負責(zé)新獎勵類型的配置接入;
  • 服務(wù)層:處理接入層的獎勵請求,拆分包裹,記錄發(fā)放狀態(tài),管理發(fā)獎二級隊列,調(diào)度不同的獎品下游進行獎勵發(fā)放;
  • 存儲層:架構(gòu)中依賴的存儲方案
  • databus 作為MQ提升吞吐量
  • mysql負責(zé)存儲基本配置、獎品和包裹的映射關(guān)系以及發(fā)放記錄
  • taishanKV存儲獎品擴展配置
  • redis 負責(zé)提供二級隊列、延遲重試隊列
  • hdfs 存儲獎勵配置和發(fā)放記錄離線數(shù)據(jù),提供分析、篩查等功能
  • 離線層:數(shù)平oneservice數(shù)據(jù)檢索、掃描異常發(fā)放記錄狀態(tài)補發(fā)獎勵、系統(tǒng)日志、相關(guān)數(shù)據(jù)埋點

詳細設(shè)計

發(fā)獎流程按照:業(yè)務(wù)上游 → 一級隊列 → 二級隊列 → 發(fā)放下游 四個模塊串行,簡單直觀,業(yè)務(wù)方僅需配置獎勵,再調(diào)用接口投遞發(fā)獎消息即可,非常便捷,串行流程如下圖所示:

圖片

針對需求中的三個特點系統(tǒng)分別進行了如下設(shè)計:

  • 低延遲:提供不同通道的隔離發(fā)放,針對高優(yōu)業(yè)務(wù)可選擇Fast通道,防止發(fā)放量過大的低優(yōu)業(yè)務(wù)影響高優(yōu)業(yè)務(wù)的發(fā)獎時長;
  • 不超發(fā):獎勵中心設(shè)計了全鏈路冪等,上游消息攜帶 source + msg_id,中間寫庫設(shè)置DB唯一鍵防止重復(fù)消費,下游提供支持冪等的發(fā)放接口,確保獎勵無論怎么重試都不會被超發(fā);
  • 不漏發(fā):層層重試,因獎勵系統(tǒng)存在多重異步,針對每一步都設(shè)置相應(yīng)的重試策略,避免中途鏈路中斷產(chǎn)生漏發(fā)。

古希臘哲學(xué)家赫拉克利特曾說過:"The only constant is change.",意思就是:唯一不變的是變化。這句話提醒我們要接受變化和不確定性,并在這種情況下保持適應(yīng)能力,設(shè)計系統(tǒng)也是如此,外部的變量太多,不能僅僅停留在理想狀態(tài)思考問題,因此獎勵系統(tǒng)在容錯上做了不少細節(jié)設(shè)計:

1.快慢隊列

某天凌晨收到大量客訴,反饋直播獎勵到賬延遲,排查下來是運營上了一個用戶觀看直播10min獲得抽獎券的任務(wù),0點10分過后,大量的發(fā)獎消息涌入隊列,當時獎勵系統(tǒng)沒做消息隔離,造成高優(yōu)業(yè)務(wù)的發(fā)獎消息消費延遲。

圖片圖片

圖片圖片

直播按業(yè)務(wù)能級可以劃分高優(yōu)和低優(yōu)兩類業(yè)務(wù),一般低優(yōu)類業(yè)務(wù)因門檻較低所以獎勵發(fā)放量比較大,如:用戶觀看直播獲得抽獎券。而高優(yōu)類業(yè)務(wù)往往獎勵發(fā)放量比較少,如:用戶消費電池參與活動獲得獎勵。不同的是這兩類業(yè)務(wù)各自對發(fā)放時效的敏感度,低優(yōu)業(yè)務(wù)對時效不敏感,可接受延遲發(fā)放;高優(yōu)業(yè)務(wù)時效敏感,獎勵延遲到賬易導(dǎo)致用戶體驗降低,甚至帶來客訴。

獎勵系統(tǒng)提供了讓業(yè)務(wù)自主選擇快慢通道的能力,上游可根據(jù)業(yè)務(wù)是否容忍延遲來選擇快慢通道,可滿足不同場景下的業(yè)務(wù)需求。

2.冪等

一級消息處理器接到消息后首先獲取獎勵包裹子獎勵,如果這一步出現(xiàn)異常,會直接返回消息重試信號,等待消費者重試。

接著將包裹中包含的所有獎勵進行封裝,再按 uid%64 進行分庫寫表,這里會通過DB組合唯一鍵 souce + msgId + awardTypeId + awardId + uid 實現(xiàn)發(fā)獎冪等判斷,如果已經(jīng)存在發(fā)獎記錄則跳過本次寫入,之后再根據(jù)快慢隊列各自的發(fā)獎鏈路進行二級隊列轉(zhuǎn)投,防止因某個下游發(fā)獎處理過慢導(dǎo)致整體消費吞吐量下滑造成的消息積壓。

慢通道消息會按照獎品類型進行隊列分配,一種獎品類型分到一組redis list隊列,具體隊列key的數(shù)量由初始化配置決定,而快隊列則是選擇databus,直接分成三個不同等級隊列,這么選擇的原因主要有以下兩點:

  • 快通道對獎勵可達性和時效性要求較高,因此選用高可用的MQ作為承載方式,但使用MQ需要單獨申請producer和consumer,這在運維部署上面增加了成本,因此只申請了高、中、低三個二級隊列,避免了每次新增獎品類型都需要單獨部署資源,針對不同的獎品類型會按照配置進行隊列分配,比如涉及金錢的獎品類型會放入Fast隊列,優(yōu)先保障;一些已知的慢下游會主動配置放到Slow隊列,避免拖慢整個發(fā)放隊列,其他的獎品類型默認進入Default隊列;
  • 慢通道對獎勵的時效性要求較低,redis list 不會增加運維負擔(dān),對于應(yīng)用來說只是從邏輯上劃分了多個隊列,非常便于擴充新獎品類型,但redis的可用性比起MQ稍顯不足,一旦出現(xiàn)意外情況可能會丟失數(shù)據(jù),因此需要有離線補償?shù)氖侄危@會犧牲獎勵發(fā)放的時效性,因此僅針對慢通道的獎勵采用這種模式。

3.可重試

二級隊列消費者隨時監(jiān)聽二級隊列消息,收到發(fā)獎消息后根據(jù)不同的獎品類型進行下游發(fā)放交互,拿到結(jié)果后更新DB狀態(tài)(如果失敗則會累計重試發(fā)放次數(shù)),更新產(chǎn)生的binlog會被canal監(jiān)聽,如果遇到發(fā)放異常需要重試的情況會將消息寫入三級隊列,此隊列主要用于獎勵重試,基于 redis zset 結(jié)構(gòu)設(shè)計的延遲隊列進行指數(shù)退避重試發(fā)獎,按照 2^0s → 2^1s → 2^2s → ... → 2^12s,自動重試13次,大概在2小時左右,如果還未恢復(fù),則判定為下游不可用,不再重試發(fā)獎等待人工介入。

圖片圖片

4.離線補償

只要發(fā)獎記錄落表成功,無論如何都需要走到最終的發(fā)獎,因此我們專門為此設(shè)計了離線補償方案,通過job定時撈取離線庫未發(fā)放完成的狀態(tài)記錄進行重試發(fā)放,如此可保證在最壞情況下的兜底,最大程度保證獎勵的可達性。

5.業(yè)務(wù)接入

為了降低上游接入成本,獎勵中心設(shè)計了一套易于理解且接入簡單的消息格式,同時支持面向未來擴展,消息格式如下:

MQ消息體
{
    "source":"(int64)業(yè)務(wù)來源,由獎勵中心頒發(fā)",
    "msg_id":"(string)消息id,同一個投遞來源下的消息id需要保證唯一",
    "uids":"([]int64)發(fā)獎勵的目標uid,支持單條消息給多人發(fā)獎",
    "package_id":"(string)獎勵包裹ID,內(nèi)部封裝了多個子獎勵",
    "msg_time":"(int64)業(yè)務(wù)方時間戳,默認不傳用下游接收到的時間處理",
    "extra_data":"(string)擴展字段,json格式,用于面向擴展",
    "business_type":"(string)業(yè)務(wù)類型,統(tǒng)計使用",
    "business_id":"(string)業(yè)務(wù)ID,統(tǒng)計使用",
    "expire_time":"(int64)動態(tài)過期時間戳,此時間會覆蓋package內(nèi)配置的過期時間"
}
  
extra_data 格式:
{
    "lottery":{
        "count":"(int64)發(fā)放包裹數(shù)量,在已有包裹獎勵配置的數(shù)量上再*count得到最終發(fā)放數(shù)量"
    },
    "send_gold_seeds_package":{
        "room_id":"(int64)送出的直播間id",
        "ruid":"(int64)送出的主播ID"
    }
}

以上消息基本滿足語義:給xx用戶發(fā)放xx獎勵,易于理解,消息體內(nèi)已經(jīng)約定了冪等鍵,按照 source + msg_id 組成聯(lián)合冪等鍵,防止超發(fā),此外還支持了 extra_data 用于針對一些特定場景,比如動態(tài)數(shù)量、動態(tài)直播間等場景,如果未來有擴展需求可基于此持續(xù)迭代。

6.獎勵配置

上面的發(fā)放條件內(nèi)包含package_id,代指獎勵包裹,其內(nèi)部封裝了我們發(fā)獎所需要的所有獎品參數(shù),通過可視化面板進行獎品配置:

圖片圖片

獎品配置主要分為4個部分:

  • 包裹ID :通過編輯不同的編號產(chǎn)生不一樣的包裹ID,如果想把多個獎品放入同一個包裹可以給它們設(shè)置相同的編號;
  • 基本屬性:選擇獎勵類型,再根據(jù)類型對應(yīng)的屬性分別配置獎勵I(lǐng)D、數(shù)量、有效期,不同的類型屬性不同,取決于服務(wù)端下發(fā);
  • 擴展屬性:不同的獎品類型附帶的發(fā)獎參數(shù)也不相同,擴展屬性根據(jù)獎勵類型進行附加,以便在發(fā)放時作為參數(shù)攜帶;
  • 顯示配置:用于C端展示;

針對上述結(jié)構(gòu),我們抽象出獎勵的基本結(jié)構(gòu)體如下:

// AwardType 獎品類型
type AwardType struct {
    // 類型ID
    TypeId int64 `json:"type_id"`
    // 類型名
    TypeName string `json:"type_name"`
    // 對C端展示類型名(為空則展示 TypeName)
    ShowTypeName string `json:"show_type_name"`
    // 類型值(用于標記擴展字段)
    TypeVal string `json:"type_val"`
    // 獎勵I(lǐng)D控件類型 none:無 select:下拉 input:輸入
    AwardIdControl string `json:"award_id_control"`
    // 獎品是否存在數(shù)量配置 0:否 1:是
    IsNum int64 `json:"is_num"`
    // 是否存在有效期配置 0:否 1:是
    IsTime int64 `json:"is_time"`
    // 有效期配置
    TimeConfigData []*AwardTypeTime `json:"time_config_data"`
    // 擴展屬性控件配置
    ExtendPropControl []*ExtendPropControlItem `json:"extend_prop_control"`
}
  
// SelectItem 擴展屬性下拉數(shù)據(jù)選項
type SelectItem struct {
    Id   string `json:"id"`
    Name string `json:"name"`
}
  
// ExtendPropControlItem 擴展屬性
type ExtendPropControlItem struct {
    // 屬性名
    PropName string `json:"prop_name"`
    // 顯示表頭名
    ColumnName string `json:"column_name"`
    // 控件類型 switch、input、select
    PropControl string `json:"prop_control"`
    // 控件下拉數(shù)據(jù),僅限控件類型為 select 會用到
    PropSelectData []*SelectItem `json:"prop_select_data"`
}
  
// AwardTypeTime 獎品有效期配置
type AwardTypeTime struct {
    // 有效期類型id
    TimeType int64 `json:"time_type"`
    // 有效期類型說明
    TimeTypeDesc string `json:"time_type_desc"`
    // 有效期值控件 (none:無 datepicker:日期選擇框 input:文本框)
    TimeValControl string `json:"time_val_control"`
    // 有效期單位控件 (none:無 select:下拉框)
    TimeUnitControl string `json:"time_unit_control"`
    // 有效期單位數(shù)據(jù)
    TimeUnitData []*SelectItem `json:"time_unit_data"`
}

服務(wù)端可以通過接口告知配置后臺應(yīng)該如何渲染配置面板,從而在新增獎品類型的時候無需后臺介入開發(fā),提升生產(chǎn)效率。

7.新獎品類型接入

作為一個通用的獎勵系統(tǒng),快捷高效地接入新的獎品類型應(yīng)該放在首要位置考慮,系統(tǒng)設(shè)計了標準的獎勵發(fā)放和回收接口,用于實現(xiàn)快速接入新類型能力,如圖所示:

圖片圖片

AwardTypeFunc為獎勵接口,AwardTypeDefaultFunc 為默認實現(xiàn),下面繼承自AwardTypeDefaultFunc的各個struct為具體獎勵,在這里真正實現(xiàn)下游接口的調(diào)用。

獎勵發(fā)放接口拿到上游獎勵包裹配置數(shù)據(jù)和發(fā)放消息參數(shù)后,先進行參數(shù)驗證,計算獎勵的過期時間,調(diào)用下游接口進行獎勵發(fā)放,由于下游接口實現(xiàn)標準各不統(tǒng)一,如不支持批量用戶發(fā)放,還需要獎勵自身做一層適配轉(zhuǎn)換,最終給到上游結(jié)果,結(jié)果返回發(fā)放成功的用戶ID、發(fā)放失敗的用戶ID、需要重試的用戶ID以及失敗的具體錯誤明細,上游再根據(jù)返回值做對應(yīng)的流程操作。

8.數(shù)據(jù)監(jiān)控

系統(tǒng)目前做了獎勵發(fā)放記錄相關(guān)的埋點,可以觀測到一段時間范圍內(nèi)各個獎品類型的發(fā)放情況,通過監(jiān)控可分析出單品斜率過高的獎勵,從而針對治理(提速、隔離、限速)。

圖片圖片

未來規(guī)劃

獎勵系統(tǒng)經(jīng)過多次迭代逐步演化成如今的多層次架構(gòu),未來還需要在以下幾個方向分別進行建設(shè):

  1. 獎勵配置復(fù)雜度過高導(dǎo)致配置準確性無法保障,需要接入配置自檢能力,盡早檢測出配置問題,避免線上事故;
  2. 系統(tǒng)的監(jiān)控粒度覆蓋不夠全面,如:獎勵發(fā)放異常監(jiān)控、上游發(fā)放來源監(jiān)控、各個隊列的生產(chǎn)消費情況監(jiān)控;
  3. 測試環(huán)境自動化回歸。
責(zé)任編輯:武曉燕 來源: 嗶哩嗶哩技術(shù)
相關(guān)推薦

2019-04-24 09:48:54

2022-12-13 07:32:46

2023-07-04 07:11:30

數(shù)據(jù)分析中臺

2015-10-30 17:48:55

2023-04-26 00:59:49

嗶哩嗶哩工程優(yōu)化

2022-11-30 10:33:03

直播技術(shù)

2021-06-04 14:56:36

App青少年模式未成年人

2022-04-08 14:21:56

App個性化推薦算法推薦管理

2020-04-26 19:57:08

天翼云

2021-08-21 14:30:58

機器學(xué)習(xí)bilibili股價

2021-08-23 11:15:20

Python機器學(xué)習(xí)bilibili
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 日韩国产精品一区二区三区 | www.操com | 久久精品中文 | 国产高清视频在线观看 | 人人看人人搞 | 亚洲精品国产综合区久久久久久久 | 国产精品99久 | 精品久久久久久久 | 97久久精品午夜一区二区 | 国产精彩视频一区 | 中文字幕精品一区二区三区精品 | 99久久久国产精品 | 一区二区三区四区国产 | 在线观看视频亚洲 | 麻豆视频在线免费看 | 国产一级视频在线观看 | 中文字幕韩在线第一页 | a在线观看 | 四虎影院在线播放 | 精品麻豆剧传媒av国产九九九 | 日日摸夜夜添夜夜添精品视频 | 欧美日韩久 | 日韩欧美网| 狠狠涩| 毛片一区二区三区 | 婷婷精品 | 91精品免费视频 | 日本三级电影在线看 | 欧洲av一区 | 久久成人一区 | 91精品国产乱码麻豆白嫩 | 国产视频精品视频 | 亚洲欧美激情精品一区二区 | 久久久久免费精品国产小说色大师 | 日韩一级免费电影 | 2021天天干夜夜爽 | 国产精品视频一 | 久久久久久久久久毛片 | 日韩在线一区二区 | 成人av一区二区三区 | 中文字幕一区二区三区精彩视频 |