Nginx 緩存機制詳解

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

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