今天拋開編譯(opcode緩衝)緩衝、CDN緩衝、web伺服器(如nginx)緩衝不說,只談程式能控制實現的緩衝方式:
一、本機快取: 先問個問題,我要發貨到遼寧,最牛逼的物流是什麼。大貨車。高鐵。飛機。時光隧道。機器貓。我暈,你還讓不讓我寫下去了。
做過物流的應該知道,最厲害的物流不是物聯調度系統響應有多快(伺服器處理能力),運輸工具有多快(傳輸速度),也不是你同時能發多少趟車(頻寬),那你說是啥。對了,在當地建倉庫,倉庫建到他家去。
緩衝也是這個道理,最牛B的緩衝就是把最後要呈現於瀏覽器的資訊內容存到瀏覽器本地。
使用者在向伺服器擷取內容時因為頭部帶有If-Modified-Since,伺服器判斷本地的資訊是否到期,沒有到期就返回304讓瀏覽器到本地拿貨;到期了就重建內容,並構造緩衝的頭部資訊,其中包含很重要的max-ag,Expires,Last-modified資訊(能讓要求標頭帶上If-Modified-Since)。
public function set_cache_header($last_modified, $expiration){ $max_age = $expiration - $_SERVER['REQUEST_TIME']; if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $last_modified <= strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { $this->set_status_header(304); exit; } else { header('Pragma: public'); header('Cache-Control: max-age='.$max_age.', public'); header('Expires: '.gmdate('D, d M Y H:i:s', $expiration).' GMT'); header('Last-modified: '.gmdate('D, d M Y H:i:s', $last_modified).' GMT'); }}
怎麼讓瀏覽器不緩衝靜態資源。
設定頭資訊Cache-Control: no-cache header,這樣就不會緩衝靜態資源了,每次都去伺服器上重新擷取。
對firefox的瀏覽器要在header中加一個Cache-Control: no-cache, no-store
二、服務端/應用程式層緩衝
這個層級的緩衝,重點是在緩衝介質的使用上。介質可以是File,Nosql 。主要是減少Cpu運算,磁碟這種慢的I/O讀寫和內在佔用。
CI架構的做法是根據使用者請求的URL作為唯一的KEY值進行緩衝,那麼value就是該地址向瀏覽器輸出的內容。當然我們也可以有別的用法,不去緩衝整個頁面,而是緩衝片段,比如省、市、區三級聯動資料,比如欄目類別資料。不過對於需要身分識別驗證和判斷的頁面,或者適時性很強的頁面,就不適合作緩衝了,反而需要強制不緩衝。
如果請求的URL命中緩衝,那就直接輸出內容,不需要資料庫訪問,運算,三個字,好快省。
怎麼設定到期呢。CI架構是這樣做的,將到期時間$expire放在緩衝的內容前面,並用一個特殊字元串"ENDCI--->"隔開。
在讀取緩衝時,先取出前端的到期時間$expire,與當前請求時間$_SERVER['REQUEST_TIME']比對,如果小的話就說明到期了,然後無情刪除,如果大的話,就說明還是有效緩衝。
當某個終端使用者第一次請求該url,會在伺服器上產生一個緩衝,同時按照“本機快取”中的實現方法
三、資料庫緩衝
資料庫緩衝重點同樣是在緩衝介質的使用上。CI的實現方式是將查詢類的語句的結果對像序列化並儲存到文本中,對於緩衝的key實現方法,各種架構都有不同,有的把查詢語句md5產生唯一key。CI的做法是,根據調用的控制器名和方法名產生一個目錄,然後將方法中的查詢快取檔案儲存到子目錄中。