一個大型的B2B或者B2C網站,必然要考慮訪問用戶量和站點自身的內容量問題,如果解決高訪問量和海量內容帶來的性能問題呢。當然對於非常成熟的企業來說可以采用分布式數據庫和服務器,通過負載均衡同樣能解決問題。而我們采用的是最簡單、最容易、成本最低的實現方式,那就是使用靜態鏡像站點。
服務器一:阿里雲服務器(原站點)
服務器二:阿里雲OSS存儲服務(鏡像站點)
配置鏡像站點映射到雲服務器,雲服務器的每個頁面的訪問會生成靜態頁面,當靜態頁面存在時,則直接讀取靜態頁面,若靜態頁面不存在則動態生成。
那么問題來了,當網站內容有更新時,但頁面靜態文件已經存在的時候,用戶訪問時get到的永遠是已經生成的那個靜態文件,而無法讀取到最新的頁面內容。
也許你會說這個很簡單,定時將舊的靜態文件刪除了不就好了嘛。沒錯,一開始本君也是這樣做的,但很快就發現有問題,這樣做行不通了。
問題一:定時清除所有靜態文件,那么新的靜態文件生成的期間,用戶訪問量若大,則性能問題一樣會出現
問題二:網站海量的內容,生成靜態文件不是一時半刻就能完成的,單個服務器能承受的並發很底,幾十萬個靜態頁面都要好幾天才能生成完
問題三:最頭痛的是阿里OSS存儲服務器讀取原站點的頁面只有3s的響應時間,如果頁面響應時間久了一點,則會出現文件找不到的錯誤。
接下來本君要說重點了,我們可以采用主動推送方式,具體如下:
1. 定義一張路由表,記錄網站各頁面的路由地址配置
2. 定義一張路由參數表,記錄參數名稱以及參數值讀取的sql,sql支持指定時間點查詢
3. 定義一張靜態頁面生成歷史記錄表。記錄每個具體的頁面url、路由名稱、存儲oss站點、頁面生成狀態、頁面生成內容、生成時間
實現一個服務,每5分鍾執行一次,讀取路由參數表,並執行相應的sql,同樣sql參數指定時間點為5分鍾內。將sql執行讀取到的參數與路由的url組合成一組具體的url,比較參數更新時間和歷史記錄生成的時間,若參數更新時間晚於html生成時間,則將記錄插入到歷史記錄表標記狀態為未請求。
同時每次任務執行讀取指定條數未請求的記錄,開始構造HttpWebRequest請求原站點,讀取到最新的html內容。
並更新到歷史記錄表,同時判斷當響應狀態為200時(狀態判斷是為了避免因數據問題頁面出錯,而到賬oss站點頁面出錯),則同步html內容到oss站點。
有時候,如果我們對於頁面的布局做了修改,可能需要整站更新,這就需要一定時間斷之后才能更新完成。但是如果運維人員有更新產品數據,那么我們應該優先更新5分鍾內有更新的這些數據。所以修改了5分鍾內讀取到數據生成的url記錄會直接執行。
同時,我們會發現這樣做還帶來另一個好處,那就是自動化測試。當網站大量生成靜態頁面時,每個靜態頁面的生成狀態,以及生成內容都會保存到數據表中。我們就可以定期分析這些訪問記錄,檢查生成異常的這些數據,就可以輕易的檢查到項目代碼中存在的bug,進而去修正它。