一個(gè)大型的B2B或者B2C網(wǎng)站,必然要考慮訪問(wèn)用戶量和站點(diǎn)自身的內(nèi)容量問(wèn)題,如果解決高訪問(wèn)量和海量?jī)?nèi)容帶來(lái)的性能問(wèn)題呢。當(dāng)然對(duì)于非常成熟的企業(yè)來(lái)說(shuō)可以采用分布式數(shù)據(jù)庫(kù)和服務(wù)器,通過(guò)負(fù)載均衡同樣能解決問(wèn)題。而我們采用的是最簡(jiǎn)單、最容易、成本最低的實(shí)現(xiàn)方式,那就是使用靜態(tài)鏡像站點(diǎn)。
服務(wù)器一:阿里云服務(wù)器(原站點(diǎn))
服務(wù)器二:阿里云OSS存儲(chǔ)服務(wù)(鏡像站點(diǎn))
配置鏡像站點(diǎn)映射到云服務(wù)器,云服務(wù)器的每個(gè)頁(yè)面的訪問(wèn)會(huì)生成靜態(tài)頁(yè)面,當(dāng)靜態(tài)頁(yè)面存在時(shí),則直接讀取靜態(tài)頁(yè)面,若靜態(tài)頁(yè)面不存在則動(dòng)態(tài)生成。
那么問(wèn)題來(lái)了,當(dāng)網(wǎng)站內(nèi)容有更新時(shí),但頁(yè)面靜態(tài)文件已經(jīng)存在的時(shí)候,用戶訪問(wèn)時(shí)get到的永遠(yuǎn)是已經(jīng)生成的那個(gè)靜態(tài)文件,而無(wú)法讀取到最新的頁(yè)面內(nèi)容。
也許你會(huì)說(shuō)這個(gè)很簡(jiǎn)單,定時(shí)將舊的靜態(tài)文件刪除了不就好了嘛。沒(méi)錯(cuò),一開始本君也是這樣做的,但很快就發(fā)現(xiàn)有問(wèn)題,這樣做行不通了。
問(wèn)題一:定時(shí)清除所有靜態(tài)文件,那么新的靜態(tài)文件生成的期間,用戶訪問(wèn)量若大,則性能問(wèn)題一樣會(huì)出現(xiàn)
問(wèn)題二:網(wǎng)站海量的內(nèi)容,生成靜態(tài)文件不是一時(shí)半刻就能完成的,單個(gè)服務(wù)器能承受的并發(fā)很底,幾十萬(wàn)個(gè)靜態(tài)頁(yè)面都要好幾天才能生成完
問(wèn)題三:最頭痛的是阿里OSS存儲(chǔ)服務(wù)器讀取原站點(diǎn)的頁(yè)面只有3s的響應(yīng)時(shí)間,如果頁(yè)面響應(yīng)時(shí)間久了一點(diǎn),則會(huì)出現(xiàn)文件找不到的錯(cuò)誤。
接下來(lái)本君要說(shuō)重點(diǎn)了,我們可以采用主動(dòng)推送方式,具體如下:
1. 定義一張路由表,記錄網(wǎng)站各頁(yè)面的路由地址配置
2. 定義一張路由參數(shù)表,記錄參數(shù)名稱以及參數(shù)值讀取的sql,sql支持指定時(shí)間點(diǎn)查詢
3. 定義一張靜態(tài)頁(yè)面生成歷史記錄表。記錄每個(gè)具體的頁(yè)面url、路由名稱、存儲(chǔ)oss站點(diǎn)、頁(yè)面生成狀態(tài)、頁(yè)面生成內(nèi)容、生成時(shí)間
實(shí)現(xiàn)一個(gè)服務(wù),每5分鐘執(zhí)行一次,讀取路由參數(shù)表,并執(zhí)行相應(yīng)的sql,同樣sql參數(shù)指定時(shí)間點(diǎn)為5分鐘內(nèi)。將sql執(zhí)行讀取到的參數(shù)與路由的url組合成一組具體的url,比較參數(shù)更新時(shí)間和歷史記錄生成的時(shí)間,若參數(shù)更新時(shí)間晚于html生成時(shí)間,則將記錄插入到歷史記錄表標(biāo)記狀態(tài)為未請(qǐng)求。
同時(shí)每次任務(wù)執(zhí)行讀取指定條數(shù)未請(qǐng)求的記錄,開始構(gòu)造H