淘寶前台系統的優化歷程
2009年,系統拆分,靜態文件合並,前端頁面異步化和JSON化。
2010年,去DB依賴,引入緩存,提升單機QPS,關注用戶體驗。
2011年,優化進入深水區Velocity,BigPipe。
2012年,靜態化改造。
2013年,統一Cache,CDN化,網絡協議。
高訪問系統的靜態改造
什么是靜態化系統?
幾個特征:
- 一個頁面對應URL通常固定。
- 在頁面中不能包含與瀏覽者相關的因素,這里所說的“不能包含”不包括JS動態生成的部分,也就是在頁面中HTML代碼不能明顯地含有與瀏覽器相關的DOM。
- 在頁面中不包含時間因素。頁面同樣不能含有與時間(而是服務端輸出的時間)相關的因素,頁面中的DOM不隨時間變化而變化。
- 頁面中不包含地域信息。
- 不能包含Cookie等私有數據。
為什么要進行靜態化架構設計?
系統經過多次優化升級,包括系統架構的升級,系統本身的模塊優化,代碼優化和增加各種緩存等這些優化,我們的優化層次都是在java系統中做改進的。在這種情況下壓測我們的java系統,性能依舊不能滿足我們的期望,我們的目標是再上一個數量級。java本身遇到了瓶頸,自然就想到了靜態化這種架構,讓請求盡量不進過java。
那么系統靜態化為何能做java系統做不到的高性能呢?靜態化有如下優點:
- 改變了緩存方式。直接緩存http連接而不是僅僅緩存數據,web代理服務器根據請求url直接取出對應的http相應頭和響應體直接返回,這個響應連http協議都不用重新組裝,同樣http請求頭也不一定需要解析,所以做到了獲取數據最快。
- 改變了緩存的地方。不是在java層面做緩存而是直接在web服務器層上做,所以屏蔽了java層面的一些弱點,而web服務器(如nignx,apache,varnish)都擅長處理大並發的靜態文件請求。
如何改造動態系統?
- URL唯一化
- 分離與瀏覽者相關的因素。
- 分離時間因素。
- 異地化地域因素。
- 去掉Cookie。
- 動態內容結構化。(ESI和CSI)
ps:
ESI(Edge Side Includes)-即在web代理服務器做動態內容請求,並將請求插入到靜態頁面中,當用戶拿到頁面時已經是一個完整的頁面了。這種方式對服務端性能有些影響(同步集中請求),對對用戶體驗較好。
CSI(Client Side Include)-這種方式就是發起一個異步js請求單獨向服務端獲取動態內容。對服務端性能影響小,但是用戶端頁面有些延時。
如何選擇靜態化方案的設計?
nignx+cache(靜態文件)+java 結構虛擬機單機部署
nignx+cache(靜態文件)+java 結構實體機(增大cache內存,增大緩存命中率-采用一致性hash分組)單機部署
統一cache層+java(把nignx和cache層統一管理和運維)
緩存失效問題?
被動失效:采用設置cache時間長度自動失效,也可以開發一個cache管理界面手工失效某些cache。
主動失效:
- cache失效中心監控數據庫表變化發送purge失效請求
- 裝修時間戳比較失效裝修內容
- java系統發布清空cache
- vm模板發布清空cache
其中失效中心承擔了主要的失效功能,失效中心的邏輯圖如下: