電商技術(shù)解密:如何讓用戶快速地打開商品詳情頁(yè)?
如何盡量減少用戶的流量,減少客戶端與后臺(tái)的交互,讓用戶在APP上有比較好的體驗(yàn),這些都是在設(shè)計(jì)商詳系統(tǒng)時(shí)候需要面臨的挑戰(zhàn)。
今天來(lái)跟大家聊聊商詳,商詳是展示商品詳情信息的一個(gè)頁(yè)面,整個(gè)購(gòu)物流程比較重要的一個(gè)部分,承載著網(wǎng)站的絕大部分流量。為了提高轉(zhuǎn)化率構(gòu)成商詳?shù)脑胤浅XS富,有大量的圖片、部分商品還有視頻介紹、有相對(duì)靜態(tài)的商詳模板,有實(shí)時(shí)變化的價(jià)格、促銷、庫(kù)存。
下面我們先來(lái)看下商詳上一共有哪些元素組成?
可以看到商詳上的元素非常多,總結(jié)下來(lái)分為這么幾個(gè)維度:商品維度(標(biāo)題、主圖、規(guī)格參數(shù)、商品文描)、分類維度、商家維度、店鋪維度。另外還有一些實(shí)時(shí)性比較高的:價(jià)格、實(shí)時(shí)促銷、配送地址、庫(kù)存、廣告等。
主要面臨的挑戰(zhàn)有:
- 高性能,商詳頁(yè)聚合服務(wù)比較多,要保證商詳頁(yè)在1-2秒內(nèi)可以打開。
- 靈活性較好,可以快速響應(yīng)頁(yè)面變更需求。
- 具有較好的擴(kuò)展性,當(dāng)訪問(wèn)量增加的時(shí)候可以隨時(shí)進(jìn)行水平擴(kuò)展。
- 要能夠做到柔性降級(jí),自帶開關(guān)。某些底層服務(wù)出問(wèn)題時(shí)可以通過(guò)開關(guān)進(jìn)行相應(yīng)降級(jí)處理。
針對(duì)商詳可以有幾種不同的實(shí)現(xiàn)方式,用戶看到的是同一個(gè)商詳頁(yè),但背后實(shí)現(xiàn)的方式卻多種多樣,下面給大家介紹幾種常見(jiàn)的實(shí)現(xiàn)。
第一種實(shí)現(xiàn)方式:?jiǎn)螜C(jī)版
整個(gè)網(wǎng)站放在一臺(tái)機(jī)器上,通過(guò)幾條SQL分別拿到商詳需要展示的各種信息,聚合成一個(gè)大的接口吐出給前端展示。
優(yōu)點(diǎn):邏輯簡(jiǎn)單。靈活性較好,可以快速響應(yīng)頁(yè)面變更需求。
缺點(diǎn):性能比較差,沒(méi)有擴(kuò)展性。
第二種實(shí)現(xiàn)方式:緩存銀彈
在第一版的基礎(chǔ)上增加各種維度的緩存??梢詫⒅鲌D、商詳?shù)腍TML模板放到CDN上,每個(gè)商品的聚合信息可以放到cache中,不需要每次請(qǐng)求都通過(guò)DB獲取商品數(shù)據(jù)。
優(yōu)點(diǎn):可以一定程度上提高性能。
缺點(diǎn):需要解決緩存與DB的數(shù)據(jù)一致性問(wèn)題,單純?cè)黾泳彺婷媾R數(shù)據(jù)實(shí)時(shí)性不高,底層數(shù)據(jù)已經(jīng)修改,緩存中還不是最新數(shù)據(jù)。若任何底層數(shù)據(jù)變更實(shí)時(shí)更新緩存則修改工作量較大。另外仍然沒(méi)有解決擴(kuò)展性問(wèn)題。當(dāng)請(qǐng)求量過(guò)大,或者商品數(shù)據(jù)過(guò)多將導(dǎo)致性能變差。
第三種實(shí)現(xiàn)方式:分布式服務(wù)化
按照領(lǐng)域進(jìn)行切分,不同業(yè)務(wù)領(lǐng)域獨(dú)立實(shí)現(xiàn)分別部署,將商詳依賴的底層業(yè)務(wù)領(lǐng)域分別拆分出來(lái)。例如,商品、庫(kù)存、促銷、地址等分別進(jìn)行服務(wù)化。每個(gè)子領(lǐng)域的服務(wù)自己保證各自的性能。
優(yōu)點(diǎn):具有很好的靈活性。當(dāng)有業(yè)務(wù)需求變化的時(shí)候,每個(gè)子領(lǐng)域內(nèi)部自行修改,對(duì)外部提供的接口協(xié)議不變,對(duì)外部無(wú)感知。并且具有良好的擴(kuò)展性,當(dāng)請(qǐng)求量或者數(shù)據(jù)量比較大的時(shí)候,每個(gè)子領(lǐng)域都可以分別進(jìn)行橫向擴(kuò)展。
缺點(diǎn):開發(fā)難度變大,由于按照領(lǐng)域進(jìn)行服務(wù)劃分,往往原來(lái)一行SQL可以搞定的事情。現(xiàn)在要涉及到多個(gè)領(lǐng)域一起配合來(lái)修改,需要協(xié)商接口協(xié)議,各個(gè)領(lǐng)域內(nèi)部仍有不少開發(fā)量。
下面我們來(lái)說(shuō)幾個(gè)基本的概念,上面提到的服務(wù)到底是什么?
服務(wù):自己自足的、無(wú)狀態(tài)的業(yè)務(wù)功能,通過(guò)定義良好的標(biāo)準(zhǔn)接口,它接受一個(gè)或多個(gè)請(qǐng)求,返回一個(gè)或多個(gè)應(yīng)答。
- 服務(wù)不應(yīng)依賴于其他功能或過(guò)程;
- 用于提供服務(wù)的技術(shù),編程語(yǔ)言,不構(gòu)成定義的一部分;
- 服務(wù)體現(xiàn)了業(yè)務(wù)功能,聚焦于流程,服務(wù)的主要目標(biāo)是體現(xiàn)業(yè)務(wù)功能的“自然”步驟。就服務(wù)起作用的業(yè)務(wù)而言,服務(wù)應(yīng)該代表了一項(xiàng)自足的功能,對(duì)應(yīng)著一項(xiàng)真實(shí)世界的業(yè)務(wù)活動(dòng),業(yè)務(wù)人員應(yīng)該理解服務(wù)干了什么。
接口和契約(技術(shù)層面)
- 一項(xiàng)服務(wù)是一個(gè)處理(多個(gè))消息的接口,返回信息,以及/或者改變實(shí)體(后端系統(tǒng))的狀態(tài)
- 前置條件、后置條件(安全意識(shí),不信任原則)
- 粗粒度:有助于分離服務(wù)提供者的內(nèi)部數(shù)據(jù)結(jié)構(gòu)和外部接口
- 接口的版本、向后兼容
上面介紹了分布式服務(wù)化的方式來(lái)實(shí)現(xiàn)商詳?shù)募夹g(shù)架構(gòu),那么這樣是不是就完美了?在實(shí)際情況下即使這種架構(gòu)還是有很多不可控的因素會(huì)影響整個(gè)商詳?shù)男阅堋W钪匾囊粋€(gè)就是對(duì)外部服務(wù)的依賴。如果外部服務(wù)出現(xiàn)抖動(dòng)那么整個(gè)商詳頁(yè)也會(huì)隨之出現(xiàn)不穩(wěn)定。尤其商詳是個(gè)比較大的聚合服務(wù),底層依賴的服務(wù)比較多,任何一個(gè)出問(wèn)題都會(huì)受到影響,那么商詳出錯(cuò)的概率就會(huì)比較大。如何解決這個(gè)問(wèn)題呢?
一種方案是要求所有底層服務(wù)各自保證自己的穩(wěn)定性,這需要有比較完善的監(jiān)控體系,能夠快速找到出問(wèn)題的點(diǎn),然后進(jìn)行修正。這種方案屬于比較理想狀態(tài),對(duì)外部有強(qiáng)依賴。這需要有一個(gè)比較靠譜的團(tuán)隊(duì),團(tuán)隊(duì)中每個(gè)人負(fù)責(zé)的領(lǐng)域穩(wěn)定性、健壯性都比較高,那么這種方式是比較好的,領(lǐng)域的劃分比較清晰,各自的職責(zé)也比較清晰。大家各自把自己的領(lǐng)域做好,那么整個(gè)網(wǎng)站的效率都比較高。
這對(duì)整個(gè)團(tuán)隊(duì)要求比較高,這種團(tuán)隊(duì)是存在的,但是當(dāng)公司業(yè)務(wù)發(fā)展比較快,團(tuán)隊(duì)人數(shù)增長(zhǎng)也比較快的時(shí)候,這時(shí)候團(tuán)隊(duì)的質(zhì)量就比較難保證了,就會(huì)出現(xiàn)某一個(gè)領(lǐng)域或者某幾個(gè)領(lǐng)域質(zhì)量不是很高,就會(huì)導(dǎo)致整個(gè)服務(wù)調(diào)用鏈都不穩(wěn)定,對(duì)整體網(wǎng)站影響較大。那么出現(xiàn)這種問(wèn)題時(shí)如何解決呢?
互不信任原則
對(duì)外部不信任的原則是服務(wù)自我保護(hù)最重要的方式,盡量降低外部服務(wù)出問(wèn)題時(shí)對(duì)本服務(wù)的影響。對(duì)于一個(gè)寫服務(wù)來(lái)說(shuō),一定要校驗(yàn)外部服務(wù)調(diào)用的所有參數(shù)是否合法,對(duì)每一個(gè)調(diào)用方分配場(chǎng)景ID記錄調(diào)用來(lái)源,并且自己要做冪等去重處理。設(shè)計(jì)系統(tǒng)時(shí)首先想到對(duì)于這個(gè)外部調(diào)用一旦失敗該如何處理?是否有相應(yīng)的降級(jí)策略?對(duì)于不同調(diào)用失敗的場(chǎng)景一定要清晰記錄錯(cuò)誤信息方便后面調(diào)試跟蹤解決問(wèn)題。
數(shù)據(jù)閉環(huán)
數(shù)據(jù)閉環(huán)即數(shù)據(jù)的自我管理,或者說(shuō)是數(shù)據(jù)都在自己系統(tǒng)里維護(hù),不依賴于任何其他系統(tǒng),去依賴化;這樣得到的好處就是別人抖動(dòng)跟我沒(méi)關(guān)系。
- 數(shù)據(jù)異構(gòu):是數(shù)據(jù)閉環(huán)的第一步,將各個(gè)依賴系統(tǒng)的數(shù)據(jù)拿過(guò)來(lái),按照自己的要求存儲(chǔ)起來(lái);
- 數(shù)據(jù)原子化:數(shù)據(jù)異構(gòu)的數(shù)據(jù)是原子化數(shù)據(jù),這樣未來(lái)我們可以對(duì)這些數(shù)據(jù)再加工再處理而響應(yīng)變化的需求;
- 數(shù)據(jù)聚合:將多個(gè)原子數(shù)據(jù)聚合為一個(gè)大JSON數(shù)據(jù),這樣前端展示只需要一次get,當(dāng)然要考慮系統(tǒng)架構(gòu),比如使用Redis,Redis又是單線程系統(tǒng),我們需要部署更多的Redis來(lái)支持更高的并發(fā),另外存儲(chǔ)的值要盡可能的??;
- 數(shù)據(jù)維度化:對(duì)于數(shù)據(jù)應(yīng)該按照維度和作用進(jìn)行維度化,這樣可以分離存儲(chǔ),進(jìn)行更有效的存儲(chǔ)和使用。
下面是一種相對(duì)比較簡(jiǎn)單的維度的劃分:
- 商品基本信息,標(biāo)題、擴(kuò)展屬性、特殊屬性、圖片、顏色尺碼、規(guī)格參數(shù)等;
- 商品介紹信息,商品維度商家模板、商品介紹等;
- 非商品維度其他信息,分類信息、商家信息、店鋪信息、店鋪頭、品牌信息等;
- 商品維度其他信息(異步加載),價(jià)格、促銷、配送至、廣告詞、推薦配件、最佳組合等。
降級(jí)開關(guān)
當(dāng)?shù)讓酉到y(tǒng)出現(xiàn)問(wèn)題時(shí)候要能夠做到通過(guò)開關(guān)的配置屏蔽底層系統(tǒng)的波動(dòng)對(duì)商詳?shù)挠绊?,例如?dāng)?shù)讓拥膸?kù)存系統(tǒng)出現(xiàn)問(wèn)題時(shí)可以通過(guò)開關(guān)進(jìn)行配置商詳屏蔽調(diào)用庫(kù)存接口,默認(rèn)所有商品有庫(kù)存,這樣庫(kù)存數(shù)量可能不是最準(zhǔn)確的,但至少可以保證用戶正常瀏覽商詳頁(yè)不至于由于底層系統(tǒng)的波動(dòng)導(dǎo)致整個(gè)商詳頁(yè)面打不開。在系統(tǒng)設(shè)計(jì)時(shí)候要盡可能的多預(yù)留降級(jí)開關(guān),能降級(jí)的地方都要做好降級(jí)的準(zhǔn)備,只有這樣才能保證商詳?shù)母呖捎谩?/p>
異步并發(fā)
假設(shè)一個(gè)讀服務(wù)是需要如下數(shù)據(jù):
- 數(shù)據(jù)A ?10ms
- 數(shù)據(jù)B ?15ms
- 數(shù)據(jù)C ? 20ms
- 數(shù)據(jù)D ? 5ms
- 數(shù)據(jù)E ? 10ms
那么如果串行獲取那么需要:60ms;
而如果數(shù)據(jù)C依賴數(shù)據(jù)A和數(shù)據(jù)B、數(shù)據(jù)D誰(shuí)也不依賴、數(shù)據(jù)E依賴數(shù)據(jù)C;那么我們可以這樣子來(lái)獲取數(shù)據(jù):
那么如果并發(fā)化獲取那么需要:30ms;能提升一倍的性能。
假設(shè)數(shù)據(jù)E還依賴數(shù)據(jù)F(5ms),而數(shù)據(jù)F是在數(shù)據(jù)E服務(wù)中獲取的,此時(shí)就可以考慮在此服務(wù)中在取數(shù)據(jù)A/B/D時(shí)預(yù)取數(shù)據(jù)F,那么整體性能就變?yōu)榱耍?5ms。
上面我們聊了聊關(guān)于商詳?shù)牟糠旨夹g(shù)實(shí)現(xiàn)方案,下期將跟大家聊聊電商的搶購(gòu)系統(tǒng)的哪些事兒,敬請(qǐng)期待!
本文由 @Nicole 原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理。未經(jīng)許可,禁止轉(zhuǎn)載。
不明覺(jué)厲
筆者的架構(gòu)思維和對(duì)系統(tǒng)的風(fēng)險(xiǎn)意識(shí)很好
真的是好文章。還看了作者其他的寫庫(kù)存的什么之類的,特別好。
首先聲明下,我是個(gè)菜雞。然后我有個(gè)問(wèn)題,大神你舉的并發(fā)例子,我得出的怎是45s … 還有E依賴F的話,預(yù)加載可以,但是怎么會(huì)減少響應(yīng)時(shí)間,我怎么理解成時(shí)間不會(huì)變~ (先在這問(wèn)問(wèn),我去找個(gè)技術(shù)同學(xué)問(wèn)問(wèn))
好文,這才是干貨。哪天把一些底層的服務(wù)也講講唄,比如價(jià)格,比如庫(kù)存
會(huì)講的
轉(zhuǎn)給我們技術(shù)同事看了。