聊聊轉(zhuǎn)轉(zhuǎn)商品到手價設(shè)計
一、背景介紹
1.1 問題
- 搜索結(jié)果落地頁,按照價格篩選及排序,結(jié)果不太準(zhǔn)確;
- 用戶按照價格篩選后的商品與實際存在的商品不符,可能會缺失部分商品,影響到用戶購物體驗。

1.2 到手價模塊在促銷架構(gòu)中所處的位置
在整體架構(gòu)中,商品的到手價涉及紅包,活動等模塊的協(xié)同工作。通過將商品售價、紅包、活動等因素納入綜合考慮,計算出最終的到手價,為顧客提供良好的購物體驗。

二、設(shè)計目標(biāo)
- 體驗:用戶及時看到商品的最新到手價,提升用戶購物體驗;
- 實時性:由原來的半小時看到商品的最新到手價,提升到3分鐘內(nèi)。
三、技術(shù)方案核心點
3.1 影響因素

影響商品到手價的主要因素:
- 商品,發(fā)布或改價;
- 紅包,新增/刪除或過期;
- 活動/會館,加入或踢出。
3.2 計算公式

如圖所示,商品詳情頁到手價的優(yōu)惠項明細(xì)可用公式總結(jié)如下:
商品的到手價 = 商品原價 - 活動促銷金額 - 紅包最大優(yōu)惠金額
四、落地過程及效果

隨著業(yè)務(wù)需求的變化,系統(tǒng)也需要不斷地增加新功能或者對現(xiàn)有功能進(jìn)行改進(jìn),通過版本演進(jìn),可以逐步引入新的功能模塊或優(yōu)化現(xiàn)有模塊,以滿足業(yè)務(wù)的需求。
商品的到手價設(shè)計也是遵循這樣規(guī)則,從開始的v1.0快速開發(fā)上線,響應(yīng)業(yè)務(wù);到v2.0,v3.0進(jìn)行性能優(yōu)化,升級改造,使用戶體驗更佳,更及時。
4.1 v1.0流程

v1.0流程一共分為兩步:
- 定時任務(wù)拉取拉取特定業(yè)務(wù)線的全量商品,將這批商品全量推送給各個接入方;
- 促銷系統(tǒng)提供回查接口,根據(jù)商品id等參數(shù),查詢商品的到手價;
4.2 v1.0任務(wù)及接口

- v1.0任務(wù)執(zhí)行時間長,偶爾還會出現(xiàn)執(zhí)行失敗的情況;而在正常情況下用戶大概需要半小時左右才能感知到最新的商品到手價;
- 需要提供額外的單商品及批量商品接口查詢到手價,無疑會對系統(tǒng)產(chǎn)生額外的查詢壓力,隨著接入方的增加,接口qps會成比例增加;
4.3 v2.0設(shè)計
針對v1.0版本長達(dá)半個小時更新一次到手價問題,v2.0解決方案如下:
- 實時處理部分
商品上架/商品改價;
商品加入/踢出活動;
商品加入/踢出會館;
這部分?jǐn)?shù)據(jù)的特點是,上述這些操作是能實時拿到商品的infoId,基于這些商品的infoId,可以立即計算這些商品的到手價并更新出去。

商品發(fā)布/改價,加入活動/會館,踢出活動/會館;接收這些情況下觸發(fā)的mq消息,攜帶商品infoId,直接計算到手價。
- 3min任務(wù),計算特定業(yè)務(wù)線的全量商品到手價
紅包: 新增/更新/刪除/過期;
這部分?jǐn)?shù)據(jù)的特點是,一是不能很容易能圈出受到影響的這批商品infoIds,二是有些紅包的領(lǐng)取和使用范圍可能會涉及絕大部分的商品,甚至有些時候大型促銷會配置一些全平臺紅包,影響范圍就是全量商品。
綜上,結(jié)合這兩種情況,以及現(xiàn)有的接口及能力實現(xiàn)v2.0;

推送商品的到手價,消息體格式如下,包括商品id,平臺類型,到手價:
[
{"infoId":"16606xxxxxxx174465",
"ptType":"10","
realPrice":"638000"}
]
首先在Redis維護(hù)全量商品,根據(jù)商品上架/下架消息,新增或刪除隊列中的商品;其次將全量商品保存在10000隊列中,每個隊列只存一部分商品:
queue1=[infoId...]
queue2=[infoId...]
...
queue9999=[infoId...]右圖顯示的是每個隊列存儲的商品數(shù),隊列商品數(shù)使其能保持在同一個量級。

多線程并發(fā)計算,每個線程只計算自己隊列的商品到手價即可;同時增加監(jiān)控及告警,查看每個線程的計算耗時,右圖可以看到大概在120s內(nèi)各線程計算完成。
注意事項:
- 避免無意義的計算: 將每次變化的紅包維護(hù)在一個隊列中,任務(wù)執(zhí)行時判斷是否有紅包更新;
- 并發(fā)問題: 當(dāng)任務(wù)正在執(zhí)行中時,此時恰巧商品有變化(改價,加入活動等),將此次商品放入補償隊列中,延遲執(zhí)行;
綜上,結(jié)合這兩種場景可以做到:
- 某些場景影響商品的到手價(如改價等),攜帶了商品infoId,能做到實時計算并立即推送最新的到手價;
- 拆分多個商品隊列,并發(fā)計算;各司其職,每個線程只計算自己隊列商品的到手價;
- 降低促銷系統(tǒng)壓力,接入方只需要監(jiān)聽到手價消息即可。
4.4 v3.0設(shè)計

可以看到隨著商品數(shù)的增加,計算耗時也成比例增加。

解決辦法:
- 使用分片,v2.0是將一個大任務(wù),由jvm多線程并發(fā)執(zhí)行各自隊列的商品;v3.0則是將這個大任務(wù),由多個分片去執(zhí)行各自隊列中的商品,使其分布式執(zhí)行來提高任務(wù)的執(zhí)行效率和可靠性;
- 擴展性及穩(wěn)定性強,隨著商品的增多,可以適當(dāng)增加分片數(shù),降低計算耗時。
5 總結(jié)
- 系統(tǒng)擴展性 數(shù)據(jù)量日漸增大,系統(tǒng)要能做升級擴展;
- 系統(tǒng)穩(wěn)定性 業(yè)務(wù)迭代,架構(gòu)升級,保持系統(tǒng)穩(wěn)定;
- 完備的監(jiān)控告警 及時的監(jiān)控告警,快速發(fā)現(xiàn)問題,解決問題;
- 演進(jìn)原則 早期不過度設(shè)計,不同時期采用不同架構(gòu),持續(xù)迭代。

































