Nginx 緩存作爲性能優化的一個重要手段,可以極大減輕後端服務器的負載。下面我們將介紹 Nginx 緩存配置的相關指令以及 http 緩存機制,以及 Nginx 緩存實踐案例分析。
Nginx 緩存示例
實例演示,緩存是怎麼出現的,怎麼查看!
當我們代開某個網站,如 baidu.com,我們可以看到 size 這一列有一些 js 標識爲 disk cache,這裏就是應用到了緩存。
HTTP 緩存機制
HTTP 的緩存流程如下圖所示
緩存,可以分爲強制緩存和對比緩存。
Nginx 強制緩存
介紹強制緩存是什麼?以及可能造成這個原因的配置參數!
瀏覽器不會向服務器發送任何請求,直接從本地緩存中讀取緩存數據並返回 200 狀態碼,如下圖所示。如果緩存過期再找服務器,其過程如下:
可以造成強制緩存的字段,有如下幾個:
Expires
位置: HTTP Response Header
說明: Expires 是服務端返回的到期時間。如果下一次請求如果小於服務端返回的過期時間,則直接使用緩存數據。Expires 是 HTTP1.0 的東西,現在瀏覽器默認都是使用 HTTP1.1。而且由於該值是有服務端生成,而客戶端的時間和服務端的時間有可能不一致,導致存在一定誤差。所以 HTTP1.1 使用 Cache-Control 替代。
# 示例
Expires: Mon, 22 Jul 2019 11:08:59 GMT
Cache-Control
位置: HTTP Response Header
說明: 緩存策略定義
- max-age: 標識資源能夠被緩存的最大時間
- public: 表示該響應任何中間人,包括客戶端和代理服務器都可以緩存
- private: 表示該響應只能用於瀏覽器私有緩存中,中間人(代理服務器)不能緩存此響應
- no-cache: 需要使用對比緩存(Last-Modified/If-Modified-Since/Etag/If-None-Match)來驗證緩存數據
- no-store: 所有內容都不會緩存,強制緩存和對比緩存都不會觸發
Nginx 對比緩存
介紹使用緩存和不使用緩存的區別和對比!
瀏覽器在第一次請求數據時,服務器會將緩存的標識與數據一起返回給瀏覽器,瀏覽器將這兩個緩存到本地緩存數據庫中。
再次請求數據時,就會在請求 header 中帶上緩存的標識發送給服務器,服務器根據緩存標識對比,如果發生變化,則返回 200 狀態碼,返回完整的響應數據給瀏覽器,如果未發生更新,則返回 304 狀態碼告訴瀏覽器繼續使用緩存數據。
如下圖比較所示,在第一次請求時,沒有使用緩存。而在第二次使用緩存時,可以明顯看到兩者請求的時間不一樣,後者時間少很多。這是因爲服務端如果進行緩存比較後發現未更新,只返回 header 部分,並返回 304 狀態碼通知客戶端使用本地緩存,沒有將報文的 body 部分返回給瀏覽器,所以請求時間和報文大小才明顯優化。別小看這幾十毫秒,當訪問量很大時,這裏就優化了很多時間、減少了很多服務器壓力。
第一次訪問,未使用緩存:
第二次訪問,使用緩存:
HTTP 請求和響應報文結構如下圖所示:
會造成對比緩存的字段如下:
-
Last-Modified
- 位置: HTTP Response Header
- 說明: 第一次請求時,服務器會在響應頭裏設置該參數,告訴瀏覽器該資源的最後修改時間。
# 示例
Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT
-
If-Modified-Since
- 位置: HTTP Request Header
- 說明: 再次(注意不是第一次)請求服務器時,客戶端瀏覽器通過此字段通知服務器上次請求時,服務器返回的資源最後修改時間。服務器收到請求後,發現 header 中有 If-Modified-Since 字段,則與被請求資源的最後修改時間進行對比。若資源的最後修改時間大於 If-Modified-Since,則說明資源被修改過,則響應返回完整的內容,返回狀態碼 200。 若資源的最後修改時間小於或等於 If-Modified-Since,則說明資源未修改,則返回 304 狀態碼,告訴瀏覽器繼續使用所保存的緩存數據。
Etag
-
位置: HTTP Response Header
- 說明: 服務器響應請求時,告訴瀏覽器當前資源在服務器的唯一標識(由服務端生成)。
- 優先級: 高於 Last-Modified 與 If-Modified-Since
-
If-None-Match
- 位置: HTTP Request Header
- 說明: 再次請求服務器時,通過此字段通知服務器客戶端緩存的資源的唯一標識。服務器收到請求 header 周發現有 If-None-Match 字段,則與被請求資源的唯一標識進行對比。 如果不一樣,說明資源被修改過,則返回完整的響應,狀態碼 200。 如果一樣,說明資源未被修改過,則返回 304 狀態碼,告訴瀏覽器繼續使用緩存的數據。
Nginx 緩存實踐
實際配置和演示一下,使用緩存的效果!
配置文件的內容,如下所示:
nginx
user nginx;
pid /run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 100000;
events {
worker_connections 2048;
multi_accept on;
}
http {
sendfile on;
access_log off;
error_log /data/log/nginx-1.0/error.log error;
proxy_cache_path /data/nginx-1.0/cache levels=1:2 keys_zone=cache_zone:10m inactive=60m;
server {
listen 80;
server_name localhost;
root /usr/local/services/nginx-1.0/html/;
location / {
}
location ~.*\.(gif|jpg|png|css|js)(.*) {
proxy_cache cache_zone;
proxy_cache_valid 200 302 24h;
expires 1d;
add_header X-Proxy-Cache $upstream_cache_status;
}
}
}
實際的測試情況,如下所示:
[root@VM_16_4_centos conf]# curl -I http://localhost/test.js
HTTP/1.1 200 OK
Server: nginx/1.14.0
Date: Sun, 21 Jul 2019 12:35:06 GMT
Content-Type: text/plain
Content-Length: 12
Last-Modified: Sun, 21 Jul 2019 12:33:32 GMT
Connection: keep-alive
ETag: "5d345b9c-c"
Expires: Mon, 22 Jul 2019 12:35:06 GMT
Cache-Control: max-age=86400
Accept-Ranges: bytes
我們再以圖片爲例,當我們第一次請求 http://localhost/google_logo.jpg,服務端返回了該資源的唯一標識 Etag 給我們。
我們第二次請求時,可以發現 http 報文的體積和響應實踐大大縮減,說明我們的緩存發回了作用。
作者: Escape
鏈接: escapelife.site/posts/b167e14a.html