1. 程式人生 > >nginx proxy_cache緩存詳解

nginx proxy_cache緩存詳解

停止 內部 操作 開始 服務 logs 一起 _for 文件中

目錄

  • 1. 關於緩沖區指令
    • 1.1 proxy_buffer_size
    • 1.2 proxy_buffering
    • 1.3 proxy_buffers
    • 1.4 proxy_busy_buffers_size
    • 1.5 proxy_max_temp_file_size
    • 1.6 proxy_temp_file_write_size
    • 1.7 緩沖區配置實例
  • 2. 常用配置項
    • 2.1 proxy_cache_path
    • 2.2 proxy_temp_path
    • 2.3 proxy_cache
    • 2.4 proxy_cache_key
    • 2.5 proxy_cache_valid
    • 2.6 proxy_ignore_headers
    • 2.7 proxy_hide_header
    • 2.8 proxy_pass_header
    • 2.9 proxy_cache_min_uses
    • 2.10 proxy_cache_use_stale
    • 2.11 proxy_cache_lock
    • 2.12 proxy_cache_bypass
    • 2.13 proxy_no_cache
  • 3. 其他一些配置
    • 3.1 proxy_cache_lock_timeout
    • 3.2 proxy_read_timeout
    • 3.3 proxy_connect_timeout
    • 3.4 proxy_send_timeout
    • 3.5 proxy_http_version
    • 3.6 proxy_ignore_client_abort
    • 3.7 proxy_intercept_errors
    • 3.8 proxy_next_upstream
    • 3.9 proxy_cookie_domain
    • 3.10 proxy_cookie_path
    • 3.11 proxy_pass
    • 3.12 proxy_redirect
    • 3.13 proxy_set_header
    • 3.14 proxy_store
  • 4. 其他一些問題
    • 4.1 緩存動態內容
    • 4.2 緩存不生效問題
    • 4.2 緩存過期問題
    • 4.3 緩存清除問題
    • 4.4 緩存命中率
    • 4.5 如何實現動靜分離
  • 參考網址

1. 關於緩沖區指令

1.1 proxy_buffer_size

語法: proxy_buffer_size size;
默認值:    proxy_buffer_size 4k|8k;
上下文:    http, server, location
  1. 該緩沖用於來自上遊服務器響應的開始部分,在該部分通常包含一個小小的響應頭
  2. 該緩沖區大小默認等於proxy_buffers指令設置的一塊緩沖區的大小,沒有必要也跟著設置太大。 proxy_buffer_size最好單獨設置,一般設置個4k就夠了,但它也可以被設置得更小。
  3. 一塊緩沖區的大小通常等於一個內存頁的大小(4K或者8K),獲取Linux 內存頁(基頁)大小的命令:getconf PAGE_SIZE,一般的輸出是4096,即 4KB。

1.2 proxy_buffering

語法: proxy_buffering on | off;
默認值:    proxy_buffering on;
上下文:    http, server, location
  1. 該指令控制緩沖是否啟用。默認情況下,它的值是“on”。如果這個設置為off,那麽proxy_buffers和proxy_busy_buffers_size這兩個指令將會失效。 但是無論proxy_buffering是否開啟,對proxy_buffer_size配置都會起作用。
  2. 當開啟緩沖時,nginx盡可能快地從被代理的服務器接收響應,再將它存入proxy_buffer_size和proxy_buffers指令設置的緩沖區中。如果響應無法整個納入內存,那麽其中一部分將存入磁盤上的臨時文件,某些請求的響應過大,則超過_buffers的部分將被緩沖到硬盤, 當然這將會使讀取響應的速度減慢, 影響用戶體驗。通過proxy_max_temp_file_size和proxy_temp_file_write_size指令可以控制臨時文件的寫入。
  3. 當關閉緩沖時,收到響應後,nginx立即將其同步傳給客戶端。nginx不會嘗試從被代理的服務器讀取整個請求,而是將proxy_buffer_size指令設定的大小作為一次讀取的最大長度(所以無論是否開啟,proxy_buffer_size都起作用)。每次傳輸內容小了,效率肯定會有影響。
  4. 響應頭“X-Accel-Buffering”傳遞“yes”或“no”可以動態地開啟或關閉代理的緩沖功能。 這個能力可以通過proxy_ignore_headers指令關閉。

proxy_buffering啟用時,要提防使用的代理緩沖區太大。這可能會吃掉你的內存,限制代理能夠支持的最大並發連接數。

1.3 proxy_buffers

語法: proxy_buffers number size;
默認值:    proxy_buffers 8 4k|8k;
上下文:    http, server, location
  1. 為每個連接設置緩沖區的數量為number,每塊緩沖區的大小為size。這些緩沖區用於保存從被代理的服務器讀取的響應。
  2. proxy_buffers的緩沖區大小一般會設置的比較大,以應付大網頁。proxy_buffers當中單個緩沖區的大小是由系統的內存頁面大小決定的,Linux系統中一般為4k。 proxy_buffers由緩沖區數量和緩沖區大小組成的。總的大小為number*size。

1.4 proxy_busy_buffers_size

語法: proxy_busy_buffers_size size;
默認值:    proxy_busy_buffers_size 8k|16k;
上下文:    http, server, location
  1. 當開啟緩沖響應的功能以後,在沒有讀到全部響應的情況下,寫緩沖到達一定大小時,nginx一定會向客戶端發送響應,直到緩沖小於此值。這條指令用來設置此值。
  2. 同時,剩余的緩沖區可以用於接收響應,如果需要,一部分內容將緩沖到臨時文件。該大小默認是proxy_buffer_size和proxy_buffers指令設置單塊緩沖大小的兩倍。

1.5 proxy_max_temp_file_size

語法: proxy_max_temp_file_size size;
默認值:    proxy_max_temp_file_size 1024m;
上下文:    http, server, location
  1. 打開響應緩沖以後,如果整個響應不能存放在proxy_buffer_size和proxy_buffers指令設置的緩沖區內,部分響應可以存放在臨時文件中。 這條指令可以設置臨時文件的最大容量。而每次寫入臨時文件的數據量則由proxy_temp_file_write_size指令定義。
  2. 寫入硬盤的臨時文件的大小,如果超過了這個值, Nginx將與Proxy服務器同步的傳遞內容, 而不再緩沖到硬盤. 設置為0時,將禁止響應寫入臨時文件,也就相當於直接關閉硬盤緩沖。

1.6 proxy_temp_file_write_size

語法: proxy_temp_file_write_size size;
默認值:    proxy_temp_file_write_size 8k|16k;
上下文:    http, server, location

在開啟緩沖後端服務器響應到臨時文件的功能後,設置nginx每次寫數據到臨時文件的size(大小)限制。 size的默認值是proxy_buffer_size指令和proxy_buffers指令定義的每塊緩沖區大小的兩倍, 而臨時文件最大容量由proxy_max_temp_file_size指令設置。

1.7 緩沖區配置實例

通用網站的配置

proxy_buffer_size 4k; #設置代理服務器(nginx)保存用戶頭信息的緩沖區大小
proxy_buffers 4 32k; #proxy_buffers緩沖區,網頁平均在32k以下的設置
proxy_busy_buffers_size 64k; #高負荷下緩沖大小(proxy_buffers*2)
proxy_temp_file_write_size 64k;
#設定緩存文件夾大小,大於這個值,將從upstream服務器傳

docker registry的配置 這個每次傳輸至少都是9M以上的內容,緩沖區配置大;

proxy_buffering on;
proxy_buffer_size 4k; 
proxy_buffers 8 1M;
proxy_busy_buffers_size 2M;
proxy_max_temp_file_size 0;

關於緩沖區大小的配置,還是需要實地的分析,一般來說通用配置可以應付了。

2. 常用配置項

2.1 proxy_cache_path

語法: proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] [loader_files=number] [loader_sleep=time] [loader_threshold=time];
默認值:    —
上下文:    http
  • path 指定緩存文件目錄,和 proxy_temp_path 最好設置在同一文件分區下,緩存內容是先寫在 temp_path,臨時文件和緩存可以放在不同的文件系統,將導致文件在這兩個文件系統中進行拷貝,而不是廉價的重命名操作。因此,針對任何路徑,都建議將緩存和proxy_temp_path指令設置的臨時文件目錄放在同一文件系統。
  • level 定義了緩存的層次結構,每層可以用1(最多16中選擇,0-f)或2(最多256種選擇,00-ff)表示,中間用 [冒號] 分隔。“levels=1:2”表示開啟1、2層級(第2層級理論有16*256個目錄)。
proxy_cache_path /data/nginx/cache;  # 所有緩存只有一個目錄
/data/nginx/cache/d7b6e5978e3f042f52e875005925e51b 

proxy_cache_path /data/nginx/cache levels=1:2;  # 第二層級有16*256=4096個目錄
/data/nginx/cache/b/51/d7b6e5978e3f042f52e875005925e51b 

proxy_cache_path /data/nginx/cache levels=1:1:1; #第三層級有16*16*16個目錄
/data/nginx/cache/b/1/5/d7b6e5978e3f042f52e87500592 

proxy_cache_path /data/nginx/cache levels=2; # 第一層級有256個目錄
/data/nginx/cache/1b/d7b6e5978e3f042f52e875005925e51b 
  • keys_zone 指定一個共享內存空間zone,所有活動的鍵和緩存數據相關的信息都被存放在共享內存中,這樣nginx可以快速判斷一個request是否命中或者未命中緩存,1m可以存儲8000個key,10m可以存儲80000個key;
  • inactive inactive=30m 表示 30 分鐘沒有被訪問的文件會被 cache manager 刪除,inactive的默認值是10分鐘。 需要註意的是,inactive和expired配置項的含義是不同的,expired只是緩存過期,但不會被刪除,inactive是刪除指定時間內未被訪問的緩存文件
  • max_size cache存儲的最大尺寸,如果不指定,會用掉所有磁盤空間,當尺寸超過,將會基於LRU算法移除數據,以減少占用大小。nginx啟動時,會創建一個“Cache manager”進程,通過“purge”方式移除數據。
  • loader_files “cache loader”進程遍歷文件時,每次加載的文件個數。默認為100.
  • loader_threshold 每次遍歷消耗時間上限。默認為200毫秒。
  • loader_sleep 一次遍歷之後,停頓的時間間隔,默認為50毫秒。

需要註意的是:

特殊進程“cache manager”監控緩存的條目數量,如果超過max_size參數設置的最大值,使用LRU算法移除緩存數據。nginx新啟動後不就,特殊進程“cache loader”就被啟動。該進程將文件系統上保存的過去緩存的數據的相關信息重新加載到共享內存。加載過程分多次叠代完成,每次叠代,進程只加載不多於loader_files參數指定的文件數量(默認值為100)。此外,每次叠代過程的持續時間不能超過loader_threshold參數的值(默認200毫秒)。每次叠代之間,nginx的暫停時間由loader_sleep參數指定(默認50毫秒)。緩存文件並不是越多越好,所以 cache_key 的設計非常關鍵。代理或 URL 跳轉常常會添加的無用請求參數,這就會出現不同的 cache_key 保存了多份相同的緩存內容,這對緩存效果影響很大。

2.2 proxy_temp_path

語法: proxy_temp_path path [level1 [level2 [level3]]];
默認值:    
proxy_temp_path proxy_temp;
上下文:    http, server, location

定義從後端服務器接收的臨時文件的存放路徑,可以為臨時文件路徑定義至多三層子目錄的目錄樹。 比如,下面配置

proxy_temp_path /spool/nginx/proxy_temp 1 2;

那麽臨時文件的路徑看起來會是這樣:

/spool/nginx/proxy_temp/7/45/00000123457

2.3 proxy_cache

語法: proxy_cache zone | off;
默認值:    proxy_cache off;
上下文:    http, server, location

指定用於頁面緩存的共享內存。同一塊共享內存可以在多個地方使用。off參數可以屏蔽從上層配置繼承的緩存功能。zone名稱由“proxy_cache_path”指令定義。

2.4 proxy_cache_key

語法: proxy_cache_key string;
默認值:    
proxy_cache_key $scheme$proxy_host$request_uri;
上下文:    http, server, location

定義如何生成緩存的鍵,比如

proxy_cache_key "$host$request_uri $cookie_user";

這條指令的默認值類似於下面字符串

proxy_cache_key $scheme$proxy_host$uri$is_args$args;

緩存文件並不是越多越好,所以 cache_key 的設計非常關鍵。代理或 URL 跳轉常常會添加的無用請求參數,這就會出現不同的 cache_key 保存了多份相同的緩存內容,這對緩存效果影響很大。通過 ngx_lua 可以對 URL 參數進行過濾,保證 cache_key 唯一。

2.5 proxy_cache_valid

語法: proxy_cache_valid [code ...] time;
默認值:    —
上下文:    http, server, location

為不同的響應狀態碼設置不同的緩存時間。比如,下面指令

proxy_cache_valid 200 302 10m;
proxy_cache_valid 404      1m;

設置狀態碼為200和302的響應的緩存時間為10分鐘,狀態碼為404的響應的緩存時間為1分鐘。

如果僅僅指定了time,

proxy_cache_valid 5m;

那麽只有狀態碼為200、300和302的響應會被緩存。

如果使用了any參數,那麽就可以緩存任何響應:

proxy_cache_valid 200 302 10m;
proxy_cache_valid 301      1h;
proxy_cache_valid any      1m;

緩存參數也可以直接在響應頭中設定。這種方式的優先級高於使用這條指令設置緩存時間。

“X-Accel-Expires”響應頭可以以秒為單位設置響應的緩存時間,如果值為0,表示禁止緩存響應,如果值以@開始,表示自1970年1月1日以來的秒數,響應一直會被緩存到這個絕對時間點。
如果不含“X-Accel-Expires”響應頭,緩存參數仍可能被“Expires”或者“Cache-Control”響應頭設置。
如果響應頭含有“Set-Cookie”,響應將不能被緩存。 這些頭的處理過程可以使用指令proxy_ignore_headers忽略。

2.6 proxy_ignore_headers

語法: proxy_ignore_headers field ...;
默認值:    —
上下文:    http, server, location

指定來自後端server的響應中的某些header不會被處理,如下幾個fields可以被ignore:“X-Accel-Redirect”、“X-Accel-Expires”、“X-Accel-Limit-Rate”、“X-Accel-Buffering”、“X-Accel-Charset”、“Expires”、“Cache-Control”、“Set-Cookie”、“Vary”。“不被處理”就是nginx不會嘗試解析這些header並應用它們,比如nginx處理來自後端server的“Expires”,將會影響它本地的文件cache的機制

如果不被取消,這些頭部的處理可能產生下面結果:

“X-Accel-Expires”,“Expires”,“Cache-Control”,和“Set-Cookie” 設置響應緩存的參數;
“X-Accel-Redirect”執行到指定URI的內部跳轉;
“X-Accel-Limit-Rate”設置響應到客戶端的傳輸速率限制;
“X-Accel-Buffering”啟動或者關閉響應緩沖;
“X-Accel-Charset”設置響應所需的字符集。

2.7 proxy_hide_header

語法: proxy_hide_header field;
默認值:    —
上下文:    http, server, location

nginx默認不會將“Date”、“Server”、“X-Pad”,和“X-Accel-...”響應頭發送給客戶端。proxy_hide_header指令則可以設置額外的響應頭,這些響應頭也不會發送給客戶端。相反的,如果希望允許傳遞某些響應頭給客戶端,可以使用proxy_pass_header指令。

2.8 proxy_pass_header

語法: proxy_pass_header field;
默認值:    —
上下文:    http, server, location

允許傳送被屏蔽的後端服務器響應頭到客戶端。

2.9 proxy_cache_min_uses

語法: proxy_cache_min_uses number;
默認值:    proxy_cache_min_uses 1;
上下文:    http, server, location

設置響應被緩存的最小請求次數。默認為1,當客戶端發送相同請求達到規定次數後,nginx才對響應數據進行緩存;指定請求至少被發送了多少次以上時才緩存,可以防止低頻請求被緩存

2.10 proxy_cache_use_stale

語法: proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_404 | off ...;
默認值:    proxy_cache_use_stale off;
上下文:    http, server, location

如果後端服務器出現狀況,nginx是可以使用過期的響應緩存的。這條指令就是定義何種條件下允許開啟此機制。這條指令的參數與proxy_next_upstream指令的參數相同。

此外,updating參數允許nginx在正在更新緩存的情況下使用過期的緩存作為響應。這樣做可以使更新緩存數據時,訪問源服務器的次數最少。

在植入新的緩存條目時,如果想使訪問源服務器的次數最少,可以使用proxy_cache_lock指令。

2.11 proxy_cache_lock

語法: proxy_cache_lock on | off;
默認值:    proxy_cache_lock off;
上下文:    http, server, location
這個指令出現在版本 1.1.12.

開啟此功能時,對於相同的請求,同時只允許一個請求發往後端,並根據proxy_cache_key指令的設置在緩存中植入一個新條目。 其他請求相同條目的請求將一直等待,直到緩存中出現相應的內容,或者鎖在proxy_cache_lock_timeout指令設置的超時後被釋放。如果不啟用proxy_cache_lock,則所有在緩存中找不到文件的請求都會直接與服務器通信。

2.12 proxy_cache_bypass

語法: proxy_cache_bypass string ...;
默認值:    —
上下文:    http, server, location

定義nginx不從緩存取響應的條件。如果至少一個字符串條件非空而且非“0”,nginx就不會從緩存中去取響應:

proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
proxy_cache_bypass $http_pragma    $http_authorization;

本指令可和與proxy_no_cache一起使用。

2.13 proxy_no_cache

語法: proxy_no_cache string ...;
默認值:    —
上下文:    http, server, location

定義nginx不將響應寫入緩存的條件。如果至少一個字符串條件非空而且非“0”,nginx就不將響應存入緩存:

proxy_no_cache $cookie_nocache $arg_nocache$arg_comment;
proxy_no_cache $http_pragma    $http_authorization;

這條指令可以和proxy_cache_bypass指令一起使用。

3. 其他一些配置

3.1 proxy_cache_lock_timeout

語法: proxy_cache_lock_timeout time;
默認值:    proxy_cache_lock_timeout 5s;
上下文:    http, server, location

這個指令出現在版本 1.1.12.

為proxy_cache_lock指令設置鎖的超時。

3.2 proxy_read_timeout

語法: proxy_read_timeout time;
默認值:    proxy_read_timeout 60s;
上下文:    http, server, location

定義從後端服務器讀取響應的超時。此超時是指相鄰兩次讀操作之間的最長時間間隔,而不是整個響應傳輸完成的最長時間。如果後端服務器在超時時間段內沒有傳輸任何數據,連接將被關閉。

3.3 proxy_connect_timeout

語法: proxy_connect_timeout time;默認值: 
proxy_connect_timeout 60s;
上下文:    http, server, location

設置與後端服務器建立連接的超時時間。應該註意這個超時一般不可能大於75秒。

3.4 proxy_send_timeout

語法: proxy_send_timeout time;
默認值:    proxy_send_timeout 60s;
上下文:    http, server, location

定義向後端服務器傳輸請求的超時。此超時是指相鄰兩次寫操作之間的最長時間間隔,而不是整個請求傳輸完成的最長時間。如果後端服務器在超時時間段內沒有接收到任何數據,連接將被關閉。

3.5 proxy_http_version

語法: proxy_http_version 1.0 | 1.1;
默認值:    proxy_http_version 1.0;
上下文:    http, server, location

這個指令出現在版本 1.1.4.

設置代理使用的HTTP協議版本。默認使用的版本是1.0,而1.1版本則推薦在使用keepalive連接時一起使用。

3.6 proxy_ignore_client_abort

語法: proxy_ignore_client_abort on | off;
默認值:    proxy_ignore_client_abort off;
上下文:    http, server, location

決定當客戶端在響應傳輸完成前就關閉連接時,nginx是否應關閉後端連接。

3.7 proxy_intercept_errors

語法: proxy_intercept_errors on | off;
默認值:    proxy_intercept_errors off;
上下文:    http, server, location

當後端服務器的響應狀態碼大於等於400時,決定是否直接將響應發送給客戶端,亦或將響應轉發給nginx由error_page指令來處理。

3.8 proxy_next_upstream

語法: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_404 | off ...;
默認值:    proxy_next_upstream error timeout;
上下文:    http, server, location

指定在何種情況下一個失敗的請求應該被發送到下一臺後端服務器:

error
和後端服務器建立連接時,或者向後端服務器發送請求時,或者從後端服務器接收響應頭時,出現錯誤;
timeout
和後端服務器建立連接時,或者向後端服務器發送請求時,或者從後端服務器接收響應頭時,出現超時;
invalid_header
後端服務器返回空響應或者非法響應頭;
http_500
後端服務器返回的響應狀態碼為500;
http_502
後端服務器返回的響應狀態碼為502;
http_503
後端服務器返回的響應狀態碼為503;
http_504
後端服務器返回的響應狀態碼為504;
http_404
後端服務器返回的響應狀態碼為404;
off
停止將請求發送給下一臺後端服務器。

需要理解一點的是,只有在沒有向客戶端發送任何數據以前,將請求轉給下一臺後端服務器才是可行的。也就是說,如果在傳輸響應到客戶端時出現錯誤或者超時,這類錯誤是不可能恢復的。

語法: proxy_cookie_domain off;
proxy_cookie_domain domain replacement;
默認值:    proxy_cookie_domain off;
上下文:    http, server, location

這個指令出現在版本 1.1.15.

設置“Set-Cookie”響應頭中的domain屬性的替換文本。 假設後端服務器返回的“Set-Cookie”響應頭含有屬性“domain=localhost”,那麽指令

proxy_cookie_domain localhost example.org;
將這個屬性改寫為“domain=example.org”。

domain和replacement配置字符串,以及domain屬性中起始的點將被忽略。 匹配過程大小寫不敏感。

domain和replacement配置字符串中可以包含變量:

proxy_cookie_domain www.$host $host;
這條指令同樣可以使用正則表達式。這時,domain應以“~”標誌開始,且可以使用命名匹配組和位置匹配組,而replacement可以引用這些匹配組:

proxy_cookie_domain ~\.(?P<sl_domain>[-0-9a-z]+\.[a-z]+)$ $sl_domain;

可以同時定義多條proxy_cookie_domain指令:

proxy_cookie_domain localhost example.org;
proxy_cookie_domain ~\.([a-z]+\.[a-z]+)$ $1;

off參數可以取消當前配置級別的所有proxy_cookie_domain指令:

proxy_cookie_domain off;
proxy_cookie_domain localhost example.org;
proxy_cookie_domain www.example.org example.org;
語法: proxy_cookie_path off;
proxy_cookie_path path replacement;
默認值:    proxy_cookie_path off;
上下文:    http, server, location

這個指令出現在版本 1.1.15.

設置“Set-Cookie”響應頭中的path屬性的替換文本。 假設後端服務器返回的“Set-Cookie”響應頭含有屬性“path=/two/some/uri/”,那麽指令

proxy_cookie_path /two/ /;

將這個屬性改寫為“path=/some/uri/”。

path和replacement配置字符串可以包含變量:

proxy_cookie_path $uri /some$uri;

這條指令同樣可以使用正則表達式。如果使用大小寫敏感的匹配,path應以“~”標誌開始,如果使用大小寫不敏感的匹配,path應以“~*”標誌開始。path可以使用命名匹配組和位置匹配組,replacement可以引用這些匹配組:

proxy_cookie_path ~*^/user/([^/]+) /u/$1;

可以同時定義多條proxy_cookie_path指令:

proxy_cookie_path /one/ /;
proxy_cookie_path / /two/;

off參數可以取消當前配置級別的所有proxy_cookie_path指令:

proxy_cookie_path off;
proxy_cookie_path /two/ /;
proxy_cookie_path ~*^/user/([^/]+) /u/$1;

3.11 proxy_pass

語法: proxy_pass URL;
默認值:    —
上下文:    location, if in location, limit_except

設置後端服務器的協議和地址,還可以設置可選的URI以定義本地路徑和後端服務器的映射關系。 這條指令可以設置的協議是“http”或者“https”,而地址既可以使用域名或者IP地址加端口(可選)的形式來定義:

proxy_pass http://localhost:8000/uri/;

又可以使用UNIX域套接字路徑來定義。該路徑接在“unix”字符串後面,兩端由冒號所包圍,比如:

proxy_pass http://unix:/tmp/backend.socket:/uri/;

如果解析一個域名得到多個地址,所有的地址都會以輪轉的方式被使用。當然,也可以使用服務器組來定義地址。

請求URI按下面規則傳送給後端服務器:

如果proxy_pass使用了URI,當傳送請求到後端服務器時,規範化以後的請求路徑與配置中的路徑的匹配部分將被替換為指令中定義的URI:

location /name/ {
    proxy_pass http://127.0.0.1/remote/;
}

如果proxy_pass沒有使用URI,傳送到後端服務器的請求URI一般客戶端發起的原始URI,如果nginx改變了請求URI,則傳送的URI是nginx改變以後完整的規範化URI:

location /some/path/ {
    proxy_pass http://127.0.0.1;
}

在1.1.12版以前,如果proxy_pass沒有使用URI,某些情況下,nginx改變URI以後,會錯誤地將原始URI而不是改變以後的URI發送到後端服務器。
某些情況下,無法確定請求URI中應該被替換的部分:

使用正則表達式定義路徑。
這種情況下,指令不應該使用URI。

在需要代理的路徑中,使用rewrite指令改變了URI,但仍使用相同配置處理請求(break):

location /name/ {
    rewrite    /name/([^/]+) /users?name=$1 break;
    proxy_pass http://127.0.0.1;
}

這種情況下,本指令設置的URI會被忽略,改變後的URI將被發送給後端服務器。

後端服務器的地址,端口和URI中都可以使用變量:

proxy_pass http://$host$uri;

甚至像這樣:

proxy_pass $request;

這種情況下,後端服務器的地址將會在定義的服務器組中查找。如果查找不到,nginx使用resolver來查找該地址。

3.12 proxy_redirect

語法: proxy_redirect default;
proxy_redirect off;
proxy_redirect redirect replacement;
默認值:    proxy_redirect default;
上下文:    http, server, location

設置後端服務器“Location”響應頭和“Refresh”響應頭的替換文本。 假設後端服務器返回的響應頭是 “Location: http://localhost:8000/two/some/uri/”,那麽指令

proxy_redirect http://localhost:8000/two/ http://frontend/one/;

將把字符串改寫為 “Location: http://frontend/one/some/uri/”。

replacement字符串可以省略服務器名:

proxy_redirect http://localhost:8000/two/ /;

此時將使用代理服務器的主域名和端口號來替換。如果端口是80,可以不加。

用default參數指定的默認替換使用了location和proxy_pass指令的參數。因此,下面兩例配置等價:

location /one/ {
    proxy_pass     http://upstream:port/two/;
    proxy_redirect default;
location /one/ {
    proxy_pass     http://upstream:port/two/;
    proxy_redirect http://upstream:port/two/ /one/;

而且因為同樣的原因,proxy_pass指令使用變量時,不允許本指令使用default參數。

replacement字符串可以包含變量:

proxy_redirect http://localhost:8000/ http://$host:$server_port/;

而redirect字符串從1.1.11版本開始也可以包含變量:

proxy_redirect http://$proxy_host:8000/ /;

同時,從1.1.11版本開始,指令支持正則表達式。使用正則表達式的話,如果是大小寫敏感的匹配,redirect以“~”作為開始,如果是大小寫不敏感的匹配,redirect以“~*”作為開始。而且redirect的正則表達式中可以包含命名匹配組和位置匹配組,而在replacement中可以引用這些匹配組的值:

proxy_redirect ~^(http://[^:]+):\d+(/.+)$ $1$2;
proxy_redirect ~*/user/([^/]+)/(.+)$      http://$1.example.com/$2;

除此以外,可以同時定義多個proxy_redirect指令:

proxy_redirect default;
proxy_redirect http://localhost:8000/  /;
proxy_redirect http://www.example.com/ /;

另外,off參數可以使所有相同配置級別的proxy_redirect指令無效:

proxy_redirect off;
proxy_redirect default;
proxy_redirect http://localhost:8000/  /;
proxy_redirect http://www.example.com/ /;

最後,使用這條指令也可以為地址為相對地址的重定向添加域名:

proxy_redirect / /;

3.13 proxy_set_header

語法: proxy_set_header field value;
默認值:    
proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
上下文:    http, server, location

允許重新定義或者添加發往後端服務器的請求頭。value可以包含文本、變量或者它們的組合。 當且僅當當前配置級別中沒有定義proxy_set_header指令時,會從上面的級別繼承配置。 默認情況下,只有兩個請求頭會被重新定義:

proxy_set_header Host       $proxy_host;
proxy_set_header Connection close;

如果不想改變請求頭“Host”的值,可以這樣來設置:

proxy_set_header Host       $http_host;

但是,如果客戶端請求頭中沒有攜帶這個頭部,那麽傳遞到後端服務器的請求也不含這個頭部。 這種情況下,更好的方式是使用$host變量——它的值在請求包含“Host”請求頭時為“Host”字段的值,在請求未攜帶“Host”請求頭時為虛擬主機的主域名:

proxy_set_header Host       $host;

此外,服務器名可以和後端服務器的端口一起傳送:

proxy_set_header Host       $host:$proxy_port;

如果某個請求頭的值為空,那麽這個請求頭將不會傳送給後端服務器:

proxy_set_header Accept-Encoding "";
語法: proxy_ssl_session_reuse on | off;
默認值:    proxy_ssl_session_reuse on;
上下文:    http, server, location

決定是否重用與後端服務器的SSL會話。如果日誌中出現“SSL3_GET_FINISHED:digest check failed”錯誤,請嘗試關閉會話重用。

3.14 proxy_store

語法: proxy_store on | off | string;
默認值:    proxy_store off;
上下文:    http, server, location

開啟將文件保存到磁盤上的功能。如果設置為on,nginx將文件保存在alias指令或root指令設置的路徑中。如果設置為off,nginx將關閉文件保存的功能。此外,保存的文件名也可以使用含變量的string參數來指定:

proxy_store /data/www$original_uri;

保存文件的修改時間根據接收到的“Last-Modified”響應頭來設置。響應都是先寫到臨時文件,然後進行重命名來生成的。從0.8.9版本開始,臨時文件和持久化存儲可以放在不同的文件系統,但是需要註意這時文件執行的是在兩個文件系統間拷貝操作,而不是廉價的重命名操作。因此建議保存文件的路徑和proxy_temp_path指令設置的臨時文件的路徑在同一個文件系統中。

這條指令可以用於創建靜態無更改文件的本地拷貝,比如:

location /images/ {
    root                   /data/www;
    open_file_cache_errors off;
    error_page             404 = /fetch$uri;
}

location /fetch/ {
    internal;

    proxy_pass             http://backend/;
    proxy_store            on;
    proxy_store_access     user:rw group:rw all:r;
    proxy_temp_path        /data/temp;

    alias                  /data/www/;
}

或者像這樣:

location /images/ {
    root               /data/www;
    error_page         404 = @fetch;
}

location @fetch {
    internal;

    proxy_pass         http://backend;
    proxy_store        on;
    proxy_store_access user:rw group:rw all:r;
    proxy_temp_path    /data/temp;

    root               /data/www;
}
語法: proxy_store_access users:permissions ...;
默認值:    proxy_store_access user:rw;
上下文:    http, server, location

設置新創建的文件和目錄的訪問權限,比如:

proxy_store_access user:rw group:rw all:r;

如果指定了任何group或者all的訪問權限,那麽可以略去user的訪問權限:

proxy_store_access group:rw all:r;

4. 其他一些問題

4.1 緩存動態內容

NGINX可以緩存動態內容,但是這不應該亂用,有些情況需要考慮

首先,任何用戶相關的數據不應被高速緩存。這可能導致一個用戶的數據被呈現給其他用戶。如果你的網站是完全靜態的,這可能不是一個問題。

如果你的網站有一些動態元素,你將不得不考慮到這一點。你如何處理要看是什麽應用程序或服務器處理的後端處理。對於私人的內容,你應該設置Cache-Control頭為“no-cache”,“no-sotre”,或者“private”依賴於數據的性質:

4.2 緩存不生效問題

nginx是否緩存是由nginx緩存服務器與源服務器共同決定的, 緩存服務器需要嚴格遵守源服務器響應的header來決定是否緩存以及緩存的時長。

默認情況下,NGINX需要考慮從原始服務器得到的Cache-Control標頭。當在響應頭部中Cache-Control被配置為Private,No-Cache,No-Store或者Set-Cookie,NGINX不進行緩存。NGINX僅僅緩存GET和HEAD客戶端請求。

可以嘗試通過更改頭信息改讓反代服務器緩存

1、嘗試修改源服務器代碼,改變程序響應的頭信息

2、nginx反代配置提供了proxy_ignore_headers配置來忽略某些頭信息,我們可以忽略引起反代不緩存的頭信息

proxy_ignore_headers?X-Accel-Expires?Expires?Cache-Control?Set-Cookie; 

4.2 緩存過期問題

引起緩存過期的因素

  • inactive:在proxy_cache_path配置項中進行配置,說明某個緩存在inactive指定的時間內如果不訪問,將會從緩存中刪除。
  • 源服務器php頁面中生成的響應頭中的Expires,生成語句為:
    header("Expires: Fri, 07 Sep 2013 08:05:18 GMT");
  • 源服務器php頁面生成的max-age,生成語句為:
    header("Cache-Control: max-age=60");
  • nginx的配置項 proxy_cache_valid:配置nginx cache中的緩存文件的緩存時間,如果配置項為:proxy_cache_valid 200 304 2m;說明對於狀態為200和304的緩存文件的緩存時間是2分鐘,兩分鐘之後再訪問該緩存文件時,文件會過期,從而去源服務器重新取數據。

優先級

  • 在同時設置了源服務器端Expires、源服務器端max-age和nginx cahe端的proxy_cache_valid的情況下,以源服務器端設置的Expires的值為標準進行緩存的過期處理
  • 若在nginx中配置了相關配置項(proxy_ignore_headers,proxy_hide_header),取消原服務器端Expires對緩存的影響,在同時設置了源服務器端Expires、源服務器端max-age和nginx cahe端的proxy_cache_valid的情況下,以源服務器端max-age的值為標準進行緩存的過期處理
  • 若同時取消源服務器端Expires和源服務器端max-age對緩存的影響,則以proxy_cache_valid設置的值為標準進行緩存的過期處理
  • Inactive的值不受上述三個因素的影響,即第一次請求頁面之後,每經過inactvie指定的時間,都要強制進行相應的緩存清理。因此inactive的優先級最高。

詳細的測試可以參照http://www.ttlsa.com/nginx/nginx-cache-priority/

4.3 緩存清除問題

nginx沒有提供直接緩存清除的方法,但是我們可以使用以下方法清除

1、但是可以通過使用第三方的模塊ngx_cache_purge清除指定的URL
需要加入一個新的location配置

location ~ /purge(/.*) {
    proxy_cache_purge cache_one $host$1$is_args$args;
}

原網址和清除緩存的url對應關系

www.firefoxbug.net/index.html ==>> www.firefoxbug.net/purge/index.html就能清除.

2、直接刪除指定的緩存文件

直接想辦法刪除proxy_cache_path配置的目錄下的所有文件,如果你可以直接操作linux那麽可以直接rm -rf xxx了,如果不方便可以考慮寫個腳本去刪除相應的文件目錄。

4.4 緩存命中率

nginx 提供了變量$upstream-cache-status 來顯示緩存的命中狀態,我們可以再nginx.conf配置中添加一個http響應頭來顯示這一狀態

反代配置中加入

location / {
    proxy_pass http://zhengde.xxx.cn;
    proxy_set_header Host zhengde.xxx.cn;
    add_header X-Cache-Status $upstream_cache_status; 
    ... 其他配置
}

在對客戶端的響應中添加了一個X-Cache-StatusHTTP響應頭,這樣可以在響應信息中查看X-Cache-Status狀態來判定是否命中

如果想要統計命中率,那麽在訪問日誌的格式中加入$upstream_cache_status記錄即可

log_format main   ‘$remote_addr – $remote_user [$time_local] “$request” ‘
                                ‘$status $body_bytes_sent “$http_referer” ‘
                               ’”$http_user_agent” “$http_x_forwarded_for”‘
                               ’”$upstream_cache_status”‘;

然後可以使用awk命令進行統計

命令:awk '{if($NF=="\"HIT\"") hit++}  END  {printf "%.2f%",hit/NR}'   access.log
結果: 32.15%

下面是$upstream_cache_status的可能值:

1.MISS——響應在緩存中找不到,所以需要在服務器中取得。這個響應之後可能會被緩存起來。
2.BYPASS——響應來自原始服務器而不是緩存,因為請求匹配了一個proxy_cache_bypass(見下面我可以在緩存中打個洞嗎?)。這個響應之後可能會被緩存起來。
3.EXPIRED——緩存中的某一項過期了,來自原始服務器的響應包含最新的內容。
4.STALE——內容陳舊是因為原始服務器不能正確響應。需要配置proxy_cache_use_stale。
5.UPDATING——內容過期了,因為相對於之前的請求,響應的入口(entry)已經更新,並且proxy_cache_use_stale的updating已被設置。
6.REVALIDATED——proxy_cache_revalidate命令被啟用,NGINX檢測得知當前的緩存內容依然有效(If-Modified-Since或者If-None-Match)。
7.HIT——響應包含來自緩存的最新有效的內容。

4.5 如何實現動靜分離

server  
{  
    listen       10000;  
    server_name  localhost;  
     
    #靜態處理交給nginx
    location ~ .*\.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|ico|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma|css|js)$ {
        proxy_cache cache_one;
        proxy_cache_valid 200 304 302 2d;
        proxy_cache_valid any 1d;
        proxy_cache_key $host$uri$is_args$args;
        add_header X-Cache '$upstream_cache_status from $host';
        
        proxy_pass http://127.0.0.1:8088;
        expires 30d;
    }
    
    #動態文件不處理
    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}  

參考網址

http://tengine.taobao.org/nginx_docs/cn/docs/http/ngx_http_proxy_module.html#proxy_ignore_headers

https://blog.csdn.net/mary881225/article/details/70173907

http://www.cnblogs.com/bethal/p/5606062.html

http://lmdkfs.blog.163.com/blog/static/74611324201421283237778/

nginx proxy_cache緩存詳解