聊聊轉轉商品到手價設計
一、背景介紹
1.1 問題
- 搜索結果落地頁,按照價格篩選及排序,結果不太準確;
- 用戶按照價格篩選后的商品與實際存在的商品不符,可能會缺失部分商品,影響到用戶購物體驗。
1.2 到手價模塊在促銷架構中所處的位置
在整體架構中,商品的到手價涉及紅包,活動等模塊的協同工作。通過將商品售價、紅包、活動等因素納入綜合考慮,計算出最終的到手價,為顧客提供良好的購物體驗。
二、設計目標
- 體驗:用戶及時看到商品的最新到手價,提升用戶購物體驗;
- 實時性:由原來的半小時看到商品的最新到手價,提升到3分鐘內。
三、技術方案核心點
3.1 影響因素
影響商品到手價的主要因素:
- 商品,發布或改價;
- 紅包,新增/刪除或過期;
- 活動/會館,加入或踢出。
3.2 計算公式
如圖所示,商品詳情頁到手價的優惠項明細可用公式總結如下:
商品的到手價 = 商品原價 - 活動促銷金額 - 紅包最大優惠金額
四、落地過程及效果
隨著業務需求的變化,系統也需要不斷地增加新功能或者對現有功能進行改進,通過版本演進,可以逐步引入新的功能模塊或優化現有模塊,以滿足業務的需求。
商品的到手價設計也是遵循這樣規則,從開始的v1.0快速開發上線,響應業務;到v2.0,v3.0進行性能優化,升級改造,使用戶體驗更佳,更及時。
4.1 v1.0流程
v1.0流程一共分為兩步:
- 定時任務拉取拉取特定業務線的全量商品,將這批商品全量推送給各個接入方;
- 促銷系統提供回查接口,根據商品id等參數,查詢商品的到手價;
4.2 v1.0任務及接口
- v1.0任務執行時間長,偶爾還會出現執行失敗的情況;而在正常情況下用戶大概需要半小時左右才能感知到最新的商品到手價;
- 需要提供額外的單商品及批量商品接口查詢到手價,無疑會對系統產生額外的查詢壓力,隨著接入方的增加,接口qps會成比例增加;
4.3 v2.0設計
針對v1.0版本長達半個小時更新一次到手價問題,v2.0解決方案如下:
- 實時處理部分
商品上架/商品改價;
商品加入/踢出活動;
商品加入/踢出會館;
這部分數據的特點是,上述這些操作是能實時拿到商品的infoId,基于這些商品的infoId,可以立即計算這些商品的到手價并更新出去。
商品發布/改價,加入活動/會館,踢出活動/會館;接收這些情況下觸發的mq消息,攜帶商品infoId,直接計算到手價。
- 3min任務,計算特定業務線的全量商品到手價
紅包: 新增/更新/刪除/過期;
這部分數據的特點是,一是不能很容易能圈出受到影響的這批商品infoIds,二是有些紅包的領取和使用范圍可能會涉及絕大部分的商品,甚至有些時候大型促銷會配置一些全平臺紅包,影響范圍就是全量商品。
綜上,結合這兩種情況,以及現有的接口及能力實現v2.0;
推送商品的到手價,消息體格式如下,包括商品id,平臺類型,到手價:
[
{"infoId":"16606xxxxxxx174465",
"ptType":"10","
realPrice":"638000"}
]
首先在Redis維護全量商品,根據商品上架/下架消息,新增或刪除隊列中的商品;其次將全量商品保存在10000隊列中,每個隊列只存一部分商品:
queue1=[infoId...]
queue2=[infoId...]
...
queue9999=[infoId...]
右圖顯示的是每個隊列存儲的商品數,隊列商品數使其能保持在同一個量級。
多線程并發計算,每個線程只計算自己隊列的商品到手價即可;同時增加監控及告警,查看每個線程的計算耗時,右圖可以看到大概在120s內各線程計算完成。
注意事項:
- 避免無意義的計算: 將每次變化的紅包維護在一個隊列中,任務執行時判斷是否有紅包更新;
- 并發問題: 當任務正在執行中時,此時恰巧商品有變化(改價,加入活動等),將此次商品放入補償隊列中,延遲執行;
綜上,結合這兩種場景可以做到:
- 某些場景影響商品的到手價(如改價等),攜帶了商品infoId,能做到實時計算并立即推送最新的到手價;
- 拆分多個商品隊列,并發計算;各司其職,每個線程只計算自己隊列商品的到手價;
- 降低促銷系統壓力,接入方只需要監聽到手價消息即可。
4.4 v3.0設計
可以看到隨著商品數的增加,計算耗時也成比例增加。
解決辦法:
- 使用分片,v2.0是將一個大任務,由jvm多線程并發執行各自隊列的商品;v3.0則是將這個大任務,由多個分片去執行各自隊列中的商品,使其分布式執行來提高任務的執行效率和可靠性;
- 擴展性及穩定性強,隨著商品的增多,可以適當增加分片數,降低計算耗時。
5 總結
- 系統擴展性 數據量日漸增大,系統要能做升級擴展;
- 系統穩定性 業務迭代,架構升級,保持系統穩定;
- 完備的監控告警 及時的監控告警,快速發現問題,解決問題;
- 演進原則 早期不過度設計,不同時期采用不同架構,持續迭代。