前文裡我講到了網站靜態化的關鍵點是動靜分離,動靜分離是讓動態網站裡的動態網頁根據一定規則把不變的資源和經常變的資源區分開來,動靜資源做好了拆分以後,我們就可以根據靜態資源的特點將其做快取操作,這就是網站靜態化處理的核心思路。由此可見,網站靜態化處理的核心就是動靜分離和快取兩大方面,上篇我簡單講述了動靜整合的基礎知識,本篇將會講述兩大核心之一的動靜分離策略,只有把動靜分離策略做好了,快取才能發揮出它應有的效果。
下麵我們要討論下動靜分離的策略了,一個頁面什麼內容是動態的,什麼內容是靜態的,這個我們到底該如何來區分了?這個問題學問非常大,我們的標準不同,最後拆分出來的動靜資源就會存在很大的不同。在本系列開篇裡,我提到了什麼樣的頁面是靜態頁面,什麼樣的頁面是動態頁面,我是以一個url的角度定義的,每個獨立的頁面都會有一個url,這個url就好比這個頁面的門牌號,我們每次訪問這個url時候如果得到的響應頁面都是一樣的那麼我們就認為該頁面是靜態頁面,如果訪問某個url,我們訪問的時間不同,最後展示的頁面也不一樣那麼這個頁面就是動態頁面,動態頁面就是我們要進行動靜分離的載體了,我們可以看到我的定義其實是和時間相關的,也就是說訪問時間不同,得到的結果會不一致,所以我們可以根據時間這個維度分析頁面裡那些內容是靜態的,那些是動態,但是這個劃分在實際情況裡就會變得非常複雜,下麵我就講講這個複雜度。
場景一:假如我們是一個商戶,我們查詢自己網店的交易資料,一般這個交易資料我們會放置在頁面的右下部分,這個部分我們很自然把它當做動態資源,就算我們的網店交易量很小,我們也不敢把這個部分當做靜態資源處理。
場景二:我們網站為了給使用者一個友好的體驗,會在使用者登入網站後在頁面某個地方顯示歡迎語,例如:上午好,夏天的森林,歡迎使用我們的網站!,到了下午,這個歡迎語可能就變成了下午好,夏天的森林,歡迎使用我們的網站!,那麼這塊內容我們應該是當做靜態內容還是動態內容呢?這個就需要思考了。
場景三:網站頁面裡會有很多圖片,有些圖片的確是很久很久都不會發生變化,例如網站的圖示,但是有的圖片卻不同了,例如有一個星期我們要為某個商戶做營銷活動,那麼營銷圖片這塊更新後就會有一個星期的有效期,複雜點的話,我們可能會在營銷活動期間在頁面的某一塊專設給這個商戶營銷活動的內容區,這個內容區使用一個html片段,但是當營銷活動結束了,這個營銷的圖片可能就要發生變化,營銷的內容區可能會被去掉,那麼這些東西我們是當做靜態內容還是動態內容處理了?
由上面的場景我們可以知道,這個動靜分離是要講究策略的,如果策略設計的不好,可能我們把網站靜態化處理後,效果並沒有達到我們的預期。其實,我認為動靜分離除了以時間維度考慮外,還應該有個維度,就是被拆分的資源是否需要服務端應用加以配合,例如像交易查詢這樣的動態內容,我們其實需要服務端程式按照一定的業務邏輯處理請求後從儲存層獲取資料,那麼這種動態資源是沒法做靜態化處理的,還有一部分資源例如場景三里的圖片以及營銷的html片段,這些資源寫好後在有效時間內是不會發生變化的,那麼這塊內容雖然時效性可能會有差異,但是它卻是可以在這段時間做靜態化處理的,還有種情形就是場景二了,這個場景雖然使用資料需要服務端參入計算,但是計算結果在一定時間範圍內是不變的,也就是說結果是可以被快取的,那麼這塊的資源也是可以當做靜態化資源進行處理的,為什麼說拆分策略要考慮服務端應用的因素了?因為上面這些場景都是由服務端應用參入的形式所決定,在有效時間裡服務端應用不需要參入,或者參入一次後,可以長期儲存結果,那麼我們可以把這些資源當做靜態資源處理。
除此之外,服務端應用和結果的密切度也是要當做考慮的因素的。在web開發裡,除了需要瀏覽器處理的,其他技術都可以當做服務端來理解,如果我們網站使用到了CDN,使用到了靜態web伺服器例如apache,以及服務端的web容器例如jboss,那麼按請求的行進路徑,我們結果處理越早那麼網站響應效率也就越高,所以當請求在CDN傳回了,那麼肯定比在apache傳回效率高,在apache就傳回了肯定比jboss傳回的效率高,再則服務端的web容器本身因為服務端程式執行要消耗部分系統資源,所以它在處理請求的效率會比CDN和apache差很多,所以當我們按照動靜分離策略拆分出了靜態資源後,這個資源能不放在最底層的服務端的web容器處理就不要放在服務端的web容器裡處理。
由上所述,我們再回過頭來看看靜態web伺服器的SSI技術,這個技術使用起來和我們在服務端使用include類似,但是在SSI使用include一定會比在服務端效率高,因為服務端在整合動靜資源時候還會摻雜很多服務端程式處理,因此動靜資源的效率就會大打折扣。我們再看看SSI的include的用法,如下所示:
這個寫法是使用頁面的註釋標簽,當靜態web容器處理請求時候,它會掃描裡面的SSI標簽,接著就會處理這個標簽的內容,如果找到了資源那麼web容器會將資源插入到頁面裡,如果web沒有處理這個SSI標簽,那麼等結果到了瀏覽器,這個也就是一個註釋而已,不會影響頁面的展示,而且SSI標簽處理的資源也是非常豐富的,不管這個資源是靜態的,還是動態的,只要獲取時候是個完整的資源都能被正常加入到頁面裡,所以像前面的場景二這種動態的內容也是可以正常處理的。因此場景二,場景三這樣的情況都可以使用SSI來解決。SSI的作用當然不僅僅只是可以做include操作,它的標簽也可以做一些邏輯上的操作,講述如何使用SSI不是本文的重點,有興趣的朋友可以去研究下。
不過SSI也有自己的侷限性,它的第一個侷限就是SSI解析是靜態web容器來完成,因此它會消耗web容器的效能,如果SSI使用時候還有一定的邏輯,那麼這種效能消耗就會更大,其實我覺得更加重要的是如果靜態web容器過渡使用SSI,那麼就會把自己變成了一個服務端的web容器,除了會影響到請求處理的效率,它還會降低自身的併發處理能力,所以我們希望資源整合策略交給外部服務處理效果會更好些,如是有些大型網際網路公司使用ESI技術,ESI技術和快取關係密切,這個內容我就放到下篇討論了。
本篇最後我要再講講CDN的問題,上篇我講到靜態web容器整合動靜資源的好處,由此我說如果CDN可以做動靜整合,那麼就能做到就近處理,這樣效果會更高,今天我對這個做法做了一些考證,覺得該說法有點不妥,至少我現在的公司沒有使用到這樣的技術,CDN技術應該由三個步驟組成,首先是解析DNS,找到離使用者最近的CDN伺服器,接下來CDN要做一下負載均衡,根據負載均衡策略將請求落地到最合適的一個伺服器上,如果CDN伺服器上就有使用者所需要的靜態資源,那麼這個資源就會直接傳回給瀏覽器,如果沒有CDN伺服器會請求遠端的伺服器,拉取資源再把資源傳回給瀏覽器,如此同時拉取的資源也被快取在CDN伺服器上,下次訪問就不需要在請求遠端的伺服器了,CDN儲存資源的方式使用的是快取,這個快取的載體是和apache,nginx類似的伺服器,我們一般稱之為http加速器,之所以成為http加速器是為了和傳統靜態web伺服器區別開來,傳統的靜態資源伺服器一般都是從持久化裝置上讀取檔案,而http加速器則是從記憶體裡讀取,不過具體儲存的計算模型會根據硬體特點做最佳化使得資源讀取的效率更高,常見的http加速器有varnish,squid。Ngnix加上快取模組也是可以當做http加速器使用的,不管使用什麼技術CDN的伺服器基本都是做一個就近的快取操作,這也就是說CDN是否可以完成SSI操作是值得商榷的,所以前文的說法還是有點問題的。
好了,今天就寫到這裡,祝大家生活愉快。
來自:夏天的森林
連結:http://www.cnblogs.com/sharpxiajun/p/4287011.html