五、詳情頁架構(gòu)設(shè)計原則

2018-02-24 15:49 更新

詳情頁架構(gòu)設(shè)計原則

數(shù)據(jù)閉環(huán)


?數(shù)據(jù)閉環(huán)即數(shù)據(jù)的自我管理,或者說是數(shù)據(jù)都在自己系統(tǒng)里維護,不依賴于任何其他系統(tǒng),去依賴化;這樣得到的好處就是別人抖動跟我沒關(guān)系。

數(shù)據(jù)異構(gòu),是數(shù)據(jù)閉環(huán)的第一步,將各個依賴系統(tǒng)的數(shù)據(jù)拿過來,按照自己的要求存儲起來;

數(shù)據(jù)原子化,數(shù)據(jù)異構(gòu)的數(shù)據(jù)是原子化數(shù)據(jù),這樣未來我們可以對這些數(shù)據(jù)再加工再處理而響應(yīng)變化的需求;

數(shù)據(jù)聚合,將多個原子數(shù)據(jù)聚合為一個大JSON數(shù)據(jù),這樣前端展示只需要一次get,當然要考慮系統(tǒng)架構(gòu),比如我們使用的Redis改造,Redis又是單線程系統(tǒng),我們需要部署更多的Redis來支持更高的并發(fā),另外存儲的值要盡可能的??;

數(shù)據(jù)存儲,我們使用JIMDB,Redis加持久化存儲引擎,可以存儲超過內(nèi)存N倍的數(shù)據(jù)量,我們目前一些系統(tǒng)是Redis+LMDB引擎的存儲,目前是配合SSD進行存儲;另外我們使用Hash Tag機制把相關(guān)的數(shù)據(jù)哈希到同一個分片,這樣mget時不需要跨分片合并。

我們目前的異構(gòu)數(shù)據(jù)時鍵值結(jié)構(gòu)的,用于按照商品維度查詢,還有一套異構(gòu)時關(guān)系結(jié)構(gòu)的用于關(guān)系查詢使用。

詳情頁架構(gòu)設(shè)計原則?/?數(shù)據(jù)維度化

對于數(shù)據(jù)應(yīng)該按照維度和作用進行維度化,這樣可以分離存儲,進行更有效的存儲和使用。我們數(shù)據(jù)的維度比較簡單:

1、商品基本信息,標題、擴展屬性、特殊屬性、圖片、顏色尺碼、規(guī)格參數(shù)等;

2、商品介紹信息,商品維度商家模板、商品介紹等;

3、非商品維度其他信息,分類信息、商家信息、店鋪信息、店鋪頭、品牌信息等;

4、商品維度其他信息(異步加載),價格、促銷、配送至、廣告詞、推薦配件、最佳組合等。?

拆分系統(tǒng)


?將系統(tǒng)拆分為多個子系統(tǒng)雖然增加了復(fù)雜性,但是可以得到更多的好處,比如數(shù)據(jù)異構(gòu)系統(tǒng)存儲的數(shù)據(jù)是原子化數(shù)據(jù),這樣可以按照一些維度對外提供服務(wù);而數(shù)據(jù)同步系統(tǒng)存儲的是聚合數(shù)據(jù),可以為前端展示提供高性能的讀取。而前端展示系統(tǒng)分離為商品詳情頁和商品介紹,可以減少相互影響;目前商品介紹系統(tǒng)還提供其他的一些服務(wù),比如全站異步頁腳服務(wù)。

Worker無狀態(tài)化+任務(wù)化?

1、數(shù)據(jù)異構(gòu)和數(shù)據(jù)同步Worker無狀態(tài)化設(shè)計,這樣可以水平擴展;

2、應(yīng)用雖然是無狀態(tài)化的,但是配置文件還是有狀態(tài)的,每個機房一套配置,這樣每個機房只讀取當前機房數(shù)據(jù);

3、任務(wù)多隊列化,等待隊列、排重隊列、本地執(zhí)行隊列、失敗隊列;

4、隊列優(yōu)先級化,分為:普通隊列、刷數(shù)據(jù)隊列、高優(yōu)先級隊列;例如一些秒殺商品會走高優(yōu)先級隊列保證快速執(zhí)行;

5、副本隊列,當上線后業(yè)務(wù)出現(xiàn)問題時,修正邏輯可以回放,從而修復(fù)數(shù)據(jù);可以按照比如固定大小隊列或者小時隊列設(shè)計;

6、在設(shè)計消息時,按照維度更新,比如商品信息變更和商品上下架分離,減少每次變更接口的調(diào)用量,通過聚合Worker去做聚合。

異步化+并發(fā)化

?我們系統(tǒng)大量使用異步化,通過異步化機制提升并發(fā)能力。首先我們使用了消息異步化?進行系統(tǒng)解耦合,通過消息通知我變更,然后我再調(diào)用相應(yīng)接口獲取相關(guān)數(shù)據(jù);之前老系統(tǒng)使用同步推送機制,這種方式系統(tǒng)是緊耦合的,出問題需要聯(lián)系各個負責人重新推送還要考慮失敗重試機制。數(shù)據(jù)更新異步化 ,更新緩存時,同步調(diào)用服務(wù),然后異步更新緩存??刹⑿腥蝿?wù)并發(fā)化, 商品數(shù)據(jù)系統(tǒng)來源有多處,但是可以并發(fā)調(diào)用聚合,這樣本來串行需要1s的經(jīng)過這種方式我們提升到300ms之內(nèi)。異步請求合并,異步請求做合并,然后一次請求調(diào)用就能拿到所有數(shù)據(jù)。前端服務(wù)異步化/聚合,實時價格、實時庫存異步化, 使用如線程或協(xié)程機制將多個可并發(fā)的服務(wù)聚合。異步化還一個好處就是可以對異步請求做合并,原來N次調(diào)用可以合并為一次,還可以做請求的排重。

多級緩存化

瀏覽器緩存,當頁面之間來回跳轉(zhuǎn)時走local cache,或者打開頁面時拿著Last-Modified去CDN驗證是否過期,減少來回傳輸?shù)臄?shù)據(jù)量;

CDN緩存,用戶去離自己最近的CDN節(jié)點拿數(shù)據(jù),而不是都回源到北京機房獲取數(shù)據(jù),提升訪問性能;

服務(wù)端應(yīng)用本地緩存,我們使用Nginx+Lua架構(gòu),使用HttpLuaModule模塊的shared dict做本地緩存(?reload不丟失)或內(nèi)存級Proxy Cache,從而減少帶寬;

另外我們還使用使用一致性哈希(如商品編號/分類)做負載均衡內(nèi)部對URL重寫提升命中率;

我們對mget做了優(yōu)化,如去商品其他維度數(shù)據(jù),分類、面包屑、商家等差不多8個維度數(shù)據(jù),如果每次mget獲取性能差而且數(shù)據(jù)量很大,30KB以上;而這些數(shù)據(jù)緩存半小時也是沒有問題的,因此我們設(shè)計為先讀local cache,然后把不命中的再回源到remote cache獲取,這個優(yōu)化減少了一半以上的remote cache流量;

服務(wù)端分布式緩存,我們使用內(nèi)存+SSD+JIMDB持久化存儲。

動態(tài)化

數(shù)據(jù)獲取動態(tài)化,商品詳情頁:按維度獲取數(shù)據(jù),商品基本數(shù)據(jù)、其他數(shù)據(jù)(分類、商家信息等);而且可以根據(jù)數(shù)據(jù)屬性,按需做邏輯,比如虛擬商品需要自己定制的詳情頁,那么我們就可以跳轉(zhuǎn)走,比如全球購的需要走jd.hk域名,那么也是沒有問題的;

模板渲染實時化,支持隨時變更模板需求;

重啟應(yīng)用秒級化,使用Nginx+Lua架構(gòu),重啟速度快,重啟不丟共享字典緩存數(shù)據(jù);

需求上線速度化,因為我們使用了Nginx+Lua架構(gòu),可以快速上線和重啟應(yīng)用,不會產(chǎn)生抖動;另外Lua本身是一種腳本語言,我們也在嘗試把代碼如何版本化存儲,直接內(nèi)部驅(qū)動Lua代碼更新上線而不需要重啟Nginx。

彈性化

我們所有應(yīng)用業(yè)務(wù)都接入了Docker容器,存儲還是物理機;我們會制作一些基礎(chǔ)鏡像,把需要的軟件打成鏡像,這樣不用每次去運維那安裝部署軟件了;未來可以支持自動擴容,比如按照CPU或帶寬自動擴容機器,目前京東一些業(yè)務(wù)支持一分鐘自動擴容。

降級開關(guān)

推送服務(wù)器推送降級開關(guān),開關(guān)集中化維護,然后通過推送機制推送到各個服務(wù)器;

可降級的多級讀服務(wù),前端數(shù)據(jù)集群--->數(shù)據(jù)異構(gòu)集群--->動態(tài)服務(wù)(調(diào)用依賴系統(tǒng));這樣可以保證服務(wù)質(zhì)量,假設(shè)前端數(shù)據(jù)集群壞了一個?磁盤,還可以回源到數(shù)據(jù)異構(gòu)集群獲取數(shù)據(jù);

開關(guān)前置化,如Nginx--àTomcat,在Nginx上做開關(guān),請求就到不了后端,減少后端壓力;

可降級的業(yè)務(wù)線程池隔離,從Servlet3開始支持異步模型,Tomcat7/Jetty8開始支持,相同的概念是Jetty6的Continuations。我們可以把處理過程分解為一個個的事件。通過這種將請求劃分為事件方式我們可以進行更多的控制。如,我們可以為不同的業(yè)務(wù)再建立不同的線程池進行控制:即我們只依賴tomcat線程池進行請求的解析,對于請求的處理我們交給我們自己的線程池去完成;這樣tomcat線程池就不是我們的瓶頸,造成現(xiàn)在無法優(yōu)化的狀況。通過使用這種異步化事件模型,我們可以提高整體的吞吐量,不讓慢速的A業(yè)務(wù)處理影響到其他業(yè)務(wù)處理。慢的還是慢,但是不影響其他的業(yè)務(wù)。我們通過這種機制還可以把tomcat線程池的監(jiān)控拿出來,出問題時可以直接清空業(yè)務(wù)線程池,另外還可以自定義任務(wù)隊列來支持一些特殊的業(yè)務(wù)。

多機房多活

應(yīng)用無狀態(tài),通過在配置文件中配置各自機房的數(shù)據(jù)集群來完成數(shù)據(jù)讀取。

數(shù)據(jù)集群采用一主三從結(jié)構(gòu),防止當一個機房掛了,另一個機房壓力大產(chǎn)生抖動。

多種壓測方案

線下壓測,Apache ab,Apache Jmeter,這種方式是固定url壓測,一般通過訪問日志收集一些url進行壓測,可以簡單壓測單機峰值吞吐量,但是不能作為最終的壓測結(jié)果,因為這種壓測會存在熱點問題;

線上壓測,可以使用Tcpcopy直接把線上流量導(dǎo)入到壓測服務(wù)器,這種方式可以壓測出機器的性能,而且可以把流量放大,也可以使用Nginx+Lua協(xié)程機制把流量分發(fā)到多臺壓測服務(wù)器,或者直接在頁面埋點,讓用戶壓測,此種壓測方式可以不給用戶返回內(nèi)容。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號