使用靜態緩存提升網站性能的五種方法!

一、瀏覽器緩存

瀏覽器緩存,也稱爲客戶端緩存,是靜態緩存中最常見最直接的表現形式,很多時候都往往被人忽略掉。

案例1:

我們經常在nginx的配置文件中看到以下緩存配置:

6d000037ed9f276fc6c

案例2:

在經常寫 jsp 的時候,html 標籤中關於 http 頭信息也可以注意到“ expires ”的字樣:

6d100037e15c8ded90d

對於案例1和案例2中(nginx設置的expires優先級大於代碼中設置的expires優先級),expires是給一個資源設定一個過期時間,也就是說無需去服務端驗證,直接通過瀏覽器自身確認是否過期即可,所以不會產生額外的流量。此種方法非常適合不經常變動的資源。如果文件變動較頻繁,就不要使用 expires 來緩存。

比如對於常見類web網站來說,css 樣式和 js 腳本基本已經定型,所以最適合的方法是 expires 來緩存一些內容到訪問者瀏覽器。

案例3:

通過 chrome 訪問服務器端的一張圖片,用F12鍵打開開發者前端調試工具:

6d000037eda08b47417

第一次訪問,響應200狀態,當第二次及後續訪問的時候,變成304狀態,客戶端已經開始獲取瀏覽器緩存內容,而不需要去服務器端獲取對應的請求內容,即 nginx 中 expires 參數設置已經生效。等待客戶端緩存時間過期後,會再次請求服務器端內容來更新本地緩存。

6d000037edbc442d9b9

介紹到這裏,突然想起一個有意思的需求。比如,訪問一張靜態文件,不想客戶端緩存,需要每次都去服務器端取數據。我們可以用“ last-modified ”參數來實現,即“ last-modified ”是根據文件更新時間來確定是否再次發送加載。

Nginx核心配置如下:

6d000037ed8acbc1f97

我們更改掉服務器傳回客戶端的“ last-modified ”文件修改時間參數的值,這樣導致客戶端本地保存的文件時間每次跟服務器端傳回來的時間不一致,所以每次客戶端“ 誤認爲 ”服務器端有靜態文件更新,每次都會去服務器端取“ 所謂的最新數據 ”。這樣我們可以看到,不管在瀏覽器訪問多少次,返回的 http 狀態都是200,再也找不到304狀態了。

誤區:在 nginx 中設置 expires,並不是指把靜態內容緩存在 nginx 中,而是設置客戶端瀏覽器緩存的時間,這是很多人的誤區所在。

二、磁盤緩存

除了存儲在客戶端的靜態緩存(瀏覽器靜態)技術外,在服務器端的靜態緩存技術主要分爲磁盤緩存和內存緩存兩大類。單純圍繞 nginx 的 squid、varnish 等一類中間件,處理靜態數據的性能十分優秀。核心是 nginx 基於 epoll 網絡模型,而相比 apache 基於 select 網絡模型。所以 apache 的優勢在於密計算型,穩定性好。而 nginx 偏向靜態處理,反向代理,高併發。比如 apache+php 的穩定性比 nginx+php 要好,而性能是明顯 nginx 要優秀許多。

以上僅單純是對磁盤中靜態數據處理的能力,所謂磁盤緩存,指另外的一種緩存靜態文件的技術。以 nginx 配置爲例:

6d100037e19d4127df6

可以看出 nginx 主要通過 proxy_cache 來實現 web cache,熟悉 nginx 的同學,不難看出,以上配置在 location 這裏,不僅可以實現靜態文件的緩存,還可以實現動態文件的緩存(這裏放在下章節詳細介紹)。我們編寫個 test.html測試文件,然後並訪問。test.html 源碼如下:

6d000037edc9ba52346

我們發現服務器的 cache 目錄裏面,多了兩個緩存文件:

6d100037e1746809432

有意思的,這兩個文件裏面的內容分別爲(通過 less 命令查看):

6d100037e1ae69f0753

(b0ad5d3e7f099bfff9e4fc6a159d868c)

6d100037e1e193e6dbb

(53edc39ed253e14415a29412cfc01faf)

所以不難看出,nginx 把 html 內容和圖片二進制全部緩存到本地磁盤上了。下次用戶再次來訪問 test.html 的時候,nginx 直接將緩存在本地磁盤的文件返回給用戶。特別是後端如若是部署的 tomcat、iis 等,nginx 強大的靜態緩存能力,有效減少了服務器壓力。

三、內存緩存

緊接上面描述的磁盤緩存,內存緩存顧名思義,就是把靜態文件緩存在服務器端的內存中。所以這種緩存,如若命中緩存的話,取內存中的緩存數據返回比取磁盤中的緩存數據返回,性能要高很多。以 varnish 爲例,varnish 核心配置如下:

啓動命令:

6d100037e18e22f534b

參數簡介:

6d000037ee413494231

default.vcl核心配置如下:

6d000037ee6dd062ae8

Varnish對.gif、.jpg、.jpeg、.png等結尾的 URL 緩存時間設置1小時。varnish設置完畢後,我們用命令行方式,通過查看網頁頭來查看命中情況:

6d000037ee881153360

6d100037e203342923b

最後,我們可以通過 varnishadm 命令來清理緩存,也可以通過 varnishstat 命令來查看 varnish 系統緩存狀態。

四、Nginx 的內存緩存

以上主要以 Varnish 爲例,介紹了內存緩存靜態資源的方法。其實 nginx 也有內存緩存,相比 squid、varnish 而言,nginx 的內存緩存需要通過編碼實現。如下配置:

6d000037ee7f70a3812

memcached_pass 指定服務器地址,使用變量 $memcache_key 爲 key 查詢值,去 memcache 查詢對應 value 值。

如我們訪問:http://***.***.***.***/image/test.jpg ,則 nginx 去 memcache 中查詢key 爲“ test.jpg ”的 value 值並返回。如果沒有相應的值,則返回 error_page 404。介紹到這裏,關鍵在於存儲在 memcache 中的靜態文件,需要通過代碼寫入 memcache 中。怎麼樣通過 php/java 等代碼把靜態資源的數據寫入 memcache 中,關於這塊的示例就不再過多介紹了。

Nginx的內存緩存因爲需要通過編碼實現,所以靈活性特別高。這塊可以結合自身業務系統的特點,讓靜態緩存的靈活性和效率都能得到保障。可能唯一的缺陷就是,通過編碼實現的方式,給我們維護管理帶來了負擔。在之前我曾參與的一個電商系統,就是把客戶的訂單照片通過 php 代碼寫入 memcache,客戶訪問取圖的時候,從 memcache 中獲取,速度效率特別高。Nginx 作爲一款在七層無所不能且輕量級高性能的中間件,能夠直接去 memcache 中取數據,來實現靜態緩存的效果,這塊相應的功能是其他軟件無法相媲美的。

五、CDN

說起 CDN,大家都不陌生,它是靜態緩存加速最典型的代表。CDN技術並不是一門新的技術,它是基於傳統 nginx、squid、varnish 等 web 緩存技術,結合 DNS 智能解析的靜態緩存加速技術。值得注意的是,他對動態鏈接訪問並沒有加速效果。架構原理圖如下:

6d100037e2349afb0db

所以CDN的靜態緩存技術核心主要在於兩點:

節點緩存:對需要加速的網站應用,相應的靜態資源通過內存緩存+磁盤緩存的方式緩存在服務器端。

精準調度:對訪問的用戶 ip 進行智能解析調度,實現就近緩存節點訪問。比如以上圖例中,北京用戶訪問 www.a.com。通過 dns 解析的時候,分析用戶 ip,發現是北京用戶。則 dns 返回對應北京緩存節點的 ip 地址給到用戶,則用戶 www.a.com 默認訪問北京服務器上面的緩存數據,實現就近訪問的策略,大大提升了訪問速度。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章