nginx proxy_cache緩存詳解

目錄

  • 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

?
  1. 語法: proxy_buffer_size size;

  2. 默認值: proxy_buffer_size 4k|8k;

  3. 上下文: http, server, location

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

1.2 proxy_buffering

?
  1. 語法: proxy_buffering on | off;

  2. 默認值: proxy_buffering on;

  3. 上下文: 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

?
  1. 語法: proxy_buffers number size;

  2. 默認值: proxy_buffers 8 4k|8k;

  3. 上下文: http, server, location

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

1.4 proxy_busy_buffers_size

?
  1. 語法: proxy_busy_buffers_size size;

  2. 默認值: proxy_busy_buffers_size 8k|16k;

  3. 上下文: http, server, location

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

1.5 proxy_max_temp_file_size

?
  1. 語法: proxy_max_temp_file_size size;

  2. 默認值: proxy_max_temp_file_size 1024m;

  3. 上下文: 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

?
  1. 語法: proxy_temp_file_write_size size;

  2. 默認值: proxy_temp_file_write_size 8k|16k;

  3. 上下文: http, server, location

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

1.7 緩沖區配置實例

通用網站的配置

?
  1. proxy_buffer_size 4k; #設置代理服務器(nginx)保存用戶頭信息的緩沖區大小

  2. proxy_buffers 4 32k; #proxy_buffers緩沖區,網頁平均在32k以下的設置

  3. proxy_busy_buffers_size 64k; #高負荷下緩沖大小(proxy_buffers*2)

  4. proxy_temp_file_write_size 64k;

  5. #設定緩存文件夾大小,大于這個值,將從upstream服務器傳

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

?
  1. proxy_buffering on;

  2. proxy_buffer_size 4k;

  3. proxy_buffers 8 1M;

  4. proxy_busy_buffers_size 2M;

  5. proxy_max_temp_file_size 0;

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

2. 常用配置項

2.1 proxy_cache_path

?
  1. 語法: proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] [loader_files=number] [loader_sleep=time] [loader_threshold=time];

  2. 默認值: —

  3. 上下文: 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個目錄)。
?
  1. proxy_cache_path /data/nginx/cache; # 所有緩存只有一個目錄

  2. /data/nginx/cache/d7b6e5978e3f042f52e875005925e51b

  3. ?
  4. proxy_cache_path /data/nginx/cache levels=1:2; # 第二層級有16*256=4096個目錄

  5. /data/nginx/cache/b/51/d7b6e5978e3f042f52e875005925e51b

  6. ?
  7. proxy_cache_path /data/nginx/cache levels=1:1:1; #第三層級有16*16*16個目錄

  8. /data/nginx/cache/b/1/5/d7b6e5978e3f042f52e87500592

  9. ?
  10. proxy_cache_path /data/nginx/cache levels=2; # 第一層級有256個目錄

  11. /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

?
  1. 語法: proxy_temp_path path [level1 [level2 [level3]]];

  2. 默認值:

  3. proxy_temp_path proxy_temp;

  4. 上下文: http, server, location

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

proxy_temp_path /spool/nginx/proxy_temp 1 2;

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

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

2.3 proxy_cache

?
  1. 語法: proxy_cache zone | off;

  2. 默認值: proxy_cache off;

  3. 上下文: http, server, location

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

2.4 proxy_cache_key

?
  1. 語法: proxy_cache_key string;

  2. 默認值:

  3. proxy_cache_key $scheme$proxy_host$request_uri;

  4. 上下文: 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

?
  1. 語法: proxy_cache_valid [code ...] time;

  2. 默認值: —

  3. 上下文: http, server, location

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

?
  1. proxy_cache_valid 200 302 10m;

  2. proxy_cache_valid 404 1m;

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

如果僅僅指定了time,

proxy_cache_valid 5m;

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

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

?
  1. proxy_cache_valid 200 302 10m;

  2. proxy_cache_valid 301 1h;

  3. proxy_cache_valid any 1m;

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

?
  1. “X-Accel-Expires”響應頭可以以秒為單位設置響應的緩存時間,如果值為0,表示禁止緩存響應,如果值以@開始,表示自1970年1月1日以來的秒數,響應一直會被緩存到這個絕對時間點。

  2. 如果不含“X-Accel-Expires”響應頭,緩存參數仍可能被“Expires”或者“Cache-Control”響應頭設置。

  3. 如果響應頭含有“Set-Cookie”,響應將不能被緩存。 這些頭的處理過程可以使用指令proxy_ignore_headers忽略。

2.6 proxy_ignore_headers

?
  1. 語法: proxy_ignore_headers field ...;

  2. 默認值: —

  3. 上下文: 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的機制

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

?
  1. “X-Accel-Expires”,“Expires”,“Cache-Control”,和“Set-Cookie” 設置響應緩存的參數;

  2. “X-Accel-Redirect”執行到指定URI的內部跳轉;

  3. “X-Accel-Limit-Rate”設置響應到客戶端的傳輸速率限制;

  4. “X-Accel-Buffering”啟動或者關閉響應緩沖;

  5. “X-Accel-Charset”設置響應所需的字符集。

2.7 proxy_hide_header

?
  1. 語法: proxy_hide_header field;

  2. 默認值: —

  3. 上下文: http, server, location

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

2.8 proxy_pass_header

?
  1. 語法: proxy_pass_header field;

  2. 默認值: —

  3. 上下文: http, server, location

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

2.9 proxy_cache_min_uses

?
  1. 語法: proxy_cache_min_uses number;

  2. 默認值: proxy_cache_min_uses 1;

  3. 上下文: http, server, location

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

2.10 proxy_cache_use_stale

?
  1. 語法: proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_404 | off ...;

  2. 默認值: proxy_cache_use_stale off;

  3. 上下文: http, server, location

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

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

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

2.11 proxy_cache_lock

?
  1. 語法: proxy_cache_lock on | off;

  2. 默認值: proxy_cache_lock off;

  3. 上下文: http, server, location

  4. 這個指令出現在版本 1.1.12.

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

2.12 proxy_cache_bypass

?
  1. 語法: proxy_cache_bypass string ...;

  2. 默認值: —

  3. 上下文: http, server, location

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

?
  1. proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;

  2. proxy_cache_bypass $http_pragma $http_authorization;

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

2.13 proxy_no_cache

?
  1. 語法: proxy_no_cache string ...;

  2. 默認值: —

  3. 上下文: http, server, location

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

?
  1. proxy_no_cache $cookie_nocache $arg_nocache$arg_comment;

  2. proxy_no_cache $http_pragma $http_authorization;

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

3. 其他一些配置

3.1 proxy_cache_lock_timeout

?
  1. 語法: proxy_cache_lock_timeout time;

  2. 默認值: proxy_cache_lock_timeout 5s;

  3. 上下文: http, server, location

這個指令出現在版本 1.1.12.

為proxy_cache_lock指令設置鎖的超時。

3.2 proxy_read_timeout

?
  1. 語法: proxy_read_timeout time;

  2. 默認值: proxy_read_timeout 60s;

  3. 上下文: http, server, location

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

3.3 proxy_connect_timeout

?
  1. 語法: proxy_connect_timeout time;默認值:

  2. proxy_connect_timeout 60s;

  3. 上下文: http, server, location

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

3.4 proxy_send_timeout

?
  1. 語法: proxy_send_timeout time;

  2. 默認值: proxy_send_timeout 60s;

  3. 上下文: http, server, location

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

3.5 proxy_http_version

?
  1. 語法: proxy_http_version 1.0 | 1.1;

  2. 默認值: proxy_http_version 1.0;

  3. 上下文: http, server, location

這個指令出現在版本 1.1.4.

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

3.6 proxy_ignore_client_abort

?
  1. 語法: proxy_ignore_client_abort on | off;

  2. 默認值: proxy_ignore_client_abort off;

  3. 上下文: http, server, location

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

3.7 proxy_intercept_errors

?
  1. 語法: proxy_intercept_errors on | off;

  2. 默認值: proxy_intercept_errors off;

  3. 上下文: http, server, location

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

3.8 proxy_next_upstream

?
  1. 語法: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_404 | off ...;

  2. 默認值: proxy_next_upstream error timeout;

  3. 上下文: http, server, location

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

?
  1. error

  2. 和后端服務器建立連接時,或者向后端服務器發送請求時,或者從后端服務器接收響應頭時,出現錯誤;

  3. timeout

  4. 和后端服務器建立連接時,或者向后端服務器發送請求時,或者從后端服務器接收響應頭時,出現超時;

  5. invalid_header

  6. 后端服務器返回空響應或者非法響應頭;

  7. http_500

  8. 后端服務器返回的響應狀態碼為500;

  9. http_502

  10. 后端服務器返回的響應狀態碼為502;

  11. http_503

  12. 后端服務器返回的響應狀態碼為503;

  13. http_504

  14. 后端服務器返回的響應狀態碼為504;

  15. http_404

  16. 后端服務器返回的響應狀態碼為404;

  17. off

  18. 停止將請求發送給下一臺后端服務器。

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

?
  1. 語法: proxy_cookie_domain off;

  2. proxy_cookie_domain domain replacement;

  3. 默認值: proxy_cookie_domain off;

  4. 上下文: 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指令:

?
  1. proxy_cookie_domain localhost example.org;

  2. proxy_cookie_domain ~\.([a-z]+\.[a-z]+)$ $1;

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

?
  1. proxy_cookie_domain off;

  2. proxy_cookie_domain localhost example.org;

  3. proxy_cookie_domain www.example.org example.org;

?
  1. 語法: proxy_cookie_path off;

  2. proxy_cookie_path path replacement;

  3. 默認值: proxy_cookie_path off;

  4. 上下文: 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指令:

?
  1. proxy_cookie_path /one/ /;

  2. proxy_cookie_path / /two/;

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

?
  1. proxy_cookie_path off;

  2. proxy_cookie_path /two/ /;

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

3.11 proxy_pass

?
  1. 語法: proxy_pass URL;

  2. 默認值: —

  3. 上下文: 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:

?
  1. location /name/ {

  2. proxy_pass http://127.0.0.1/remote/;

  3. }

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

?
  1. location /some/path/ {

  2. proxy_pass http://127.0.0.1;

  3. }

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

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

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

?
  1. location /name/ {

  2. rewrite /name/([^/]+) /users?name=$1 break;

  3. proxy_pass http://127.0.0.1;

  4. }

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

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

proxy_pass http://$host$uri;

甚至像這樣:

proxy_pass $request;

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

3.12 proxy_redirect

?
  1. 語法: proxy_redirect default;

  2. proxy_redirect off;

  3. proxy_redirect redirect replacement;

  4. 默認值: proxy_redirect default;

  5. 上下文: 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指令的參數。因此,下面兩例配置等價:

?
  1. location /one/ {

  2. proxy_pass http://upstream:port/two/;

  3. proxy_redirect default;

  4. location /one/ {

  5. proxy_pass http://upstream:port/two/;

  6. 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中可以引用這些匹配組的值:

?
  1. proxy_redirect ~^(http://[^:]+):\d+(/.+)$ $1$2;

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

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

?
  1. proxy_redirect default;

  2. proxy_redirect http://localhost:8000/ /;

  3. proxy_redirect http://www.example.com/ /;

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

?
  1. proxy_redirect off;

  2. proxy_redirect default;

  3. proxy_redirect http://localhost:8000/ /;

  4. proxy_redirect http://www.example.com/ /;

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

proxy_redirect / /;

3.13 proxy_set_header

?
  1. 語法: proxy_set_header field value;

  2. 默認值:

  3. proxy_set_header Host $proxy_host;

  4. proxy_set_header Connection close;

  5. 上下文: http, server, location

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

?
  1. proxy_set_header Host $proxy_host;

  2. 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;

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

?
  1. proxy_set_header Accept-Encoding "";

  2. 語法: proxy_ssl_session_reuse on | off;

  3. 默認值: proxy_ssl_session_reuse on;

  4. 上下文: http, server, location

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

3.14 proxy_store

?
  1. 語法: proxy_store on | off | string;

  2. 默認值: proxy_store off;

  3. 上下文: http, server, location

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

proxy_store /data/www$original_uri;

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

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

?
  1. location /images/ {

  2. root /data/www;

  3. open_file_cache_errors off;

  4. error_page 404 = /fetch$uri;

  5. }

  6. ?
  7. location /fetch/ {

  8. internal;

  9. ?
  10. proxy_pass http://backend/;

  11. proxy_store on;

  12. proxy_store_access user:rw group:rw all:r;

  13. proxy_temp_path /data/temp;

  14. ?
  15. alias /data/www/;

  16. }

或者像這樣:

?
  1. location /images/ {

  2. root /data/www;

  3. error_page 404 = @fetch;

  4. }

  5. ?
  6. location @fetch {

  7. internal;

  8. ?
  9. proxy_pass http://backend;

  10. proxy_store on;

  11. proxy_store_access user:rw group:rw all:r;

  12. proxy_temp_path /data/temp;

  13. ?
  14. root /data/www;

  15. }

?
  1. 語法: proxy_store_access users:permissions ...;

  2. 默認值: proxy_store_access user:rw;

  3. 上下文: 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配置

?
  1. location ~ /purge(/.*) {

  2. proxy_cache_purge cache_one $host$1$is_args$args;

  3. }

原網址和清除緩存的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響應頭來顯示這一狀態

反代配置中加入

?
  1. location / {

  2. proxy_pass http://zhengde.xxx.cn;

  3. proxy_set_header Host zhengde.xxx.cn;

  4. add_header X-Cache-Status $upstream_cache_status;

  5. ... 其他配置

  6. }

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

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

?
  1. log_format main ‘$remote_addr – $remote_user [$time_local] “$request” ‘

  2. ‘$status $body_bytes_sent “$http_referer” ‘

  3. ’”$http_user_agent” “$http_x_forwarded_for”‘

  4. ’”$upstream_cache_status”‘;

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

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

  2. 結果: 32.15%

下面是$upstream_cache_status的可能值:

?
  1. 1.MISS——響應在緩存中找不到,所以需要在服務器中取得。這個響應之后可能會被緩存起來。

  2. 2.BYPASS——響應來自原始服務器而不是緩存,因為請求匹配了一個proxy_cache_bypass(見下面我可以在緩存中打個洞嗎?)。這個響應之后可能會被緩存起來。

  3. 3.EXPIRED——緩存中的某一項過期了,來自原始服務器的響應包含最新的內容。

  4. 4.STALE——內容陳舊是因為原始服務器不能正確響應。需要配置proxy_cache_use_stale。

  5. 5.UPDATING——內容過期了,因為相對于之前的請求,響應的入口(entry)已經更新,并且proxy_cache_use_stale的updating已被設置。

  6. 6.REVALIDATED——proxy_cache_revalidate命令被啟用,NGINX檢測得知當前的緩存內容依然有效(If-Modified-Since或者If-None-Match)。

  7. 7.HIT——響應包含來自緩存的最新有效的內容。

4.5 如何實現動靜分離

?
  1. server

  2. {

  3. listen 10000;

  4. server_name localhost;

  5. ?
  6. #靜態處理交給nginx

  7. location ~ .*\.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|ico|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma|css|js)$ {

  8. proxy_cache cache_one;

  9. proxy_cache_valid 200 304 302 2d;

  10. proxy_cache_valid any 1d;

  11. proxy_cache_key $host$uri$is_args$args;

  12. add_header X-Cache '$upstream_cache_status from $host';

  13. ?
  14. proxy_pass http://127.0.0.1:8088;

  15. expires 30d;

  16. }

  17. ?
  18. #動態文件不處理

  19. location / {

  20. proxy_pass http://127.0.0.1:8080;

  21. }

  22. ?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/535369.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/535369.shtml
英文地址,請注明出處:http://en.pswp.cn/news/535369.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mysql主從延遲

在實際的生產環境中&#xff0c;由單臺MySQL作為獨立的數據庫是完全不能滿足實際需求的&#xff0c;無論是在安全性&#xff0c;高可用性以及高并發等各個方面 因此&#xff0c;一般來說都是通過集群主從復制&#xff08;Master-Slave&#xff09;的方式來同步數據&#xff0c…

16張圖帶你吃透高性能 Redis 集群

現如今 Redis 變得越來越流行&#xff0c;幾乎在很多項目中都要被用到&#xff0c;不知道你在使用 Redis 時&#xff0c;有沒有思考過&#xff0c;Redis 到底是如何穩定、高性能地提供服務的&#xff1f; 你也可以嘗試回答一下以下這些問題&#xff1a; 我使用 Redis 的場景很…

Redis與MySQL雙寫一致性如何保證

談談一致性 一致性就是數據保持一致&#xff0c;在分布式系統中&#xff0c;可以理解為多個節點中數據的值是一致的。 強一致性&#xff1a;這種一致性級別是最符合用戶直覺的&#xff0c;它要求系統寫入什么&#xff0c;讀出來的也會是什么&#xff0c;用戶體驗好&#xff0c;…

weblogic忘記console密碼

進入 cd /sotware/oracle_ldap/Middleware/user_projects/domains/base_domain/security/ 目錄 執行 java -classpath /sotware/oracle_ldap/Middleware/wlserver_10.3/server/lib/weblogic.jar weblogic.security.utils.AdminAccount weblogic(賬號) weblogic123(密碼) . …

Mysql高性能優化技能總結

數據庫命令規范 所有數據庫對象名稱必須使用小寫字母并用下劃線分割 所有數據庫對象名稱禁止使用mysql保留關鍵字&#xff08;如果表名中包含關鍵字查詢時&#xff0c;需要將其用單引號括起來&#xff09; 數據庫對象的命名要能做到見名識意&#xff0c;并且最后不要超過32個…

Redis的AOF日志

如果 Redis 每執行一條寫操作命令&#xff0c;就把該命令以追加的方式寫入到一個文件里&#xff0c;然后重啟 Redis 的時候&#xff0c;先去讀取這個文件里的命令&#xff0c;并且執行它&#xff0c;這不就相當于恢復了緩存數據了嗎&#xff1f; 這種保存寫操作命令到日志的持久…

Redis 核心技術與實戰

目錄 開篇詞 | 這樣學 Redis&#xff0c;才能技高一籌 01 | 基本架構&#xff1a;一個鍵值數據庫包含什么&#xff1f; 02 | 數據結構&#xff1a;快速的Redis有哪些慢操作&#xff1f; 鍵和值用什么結構組織&#xff1f; 為什么哈希表操作變慢了&#xff1f; 有哪些底層數…

redis核心技術與實戰(二)緩存應用篇

1.《旁路緩存&#xff1a;redis 在緩存中工作原理》 1.緩存的兩個特征 1.什么是緩存&#xff0c;有什么特征&#xff1f; 磁盤->內存->cpu 之間讀寫速度差異巨大&#xff0c;為了平衡他們之間的差異&#xff0c;操作系統默認使用了兩種緩存&#xff1b; CPU 里面的末級…

redis核心技術與實戰(三) 性能篇

影響redis性能主要有以下部分&#xff1a; Redis 內部的阻塞式操作&#xff1b; CPU核和NUMA架構 Redis關鍵系統配置 Redis內存碎片 Redis緩沖區 下面一個個來介紹這些地方 1.《redis 有哪些阻塞點&#xff1f;》 redis實例主要交互的對象有以下幾點&#xff0c;我們依據下面這…

redis核心與實戰(一)數據結構篇

1.《redis數據結構概覽》 1.數據結構概覽 數據模型&#xff1a;一共5種&#xff0c;String&#xff08;字符串&#xff09;、List&#xff08;列表&#xff09;、Hash&#xff08;哈希&#xff09;、Set&#xff08;集合&#xff09;和 Sorted Set&#xff08;有序集合&#xf…

redis核心技術與實戰(四)高可用高擴展篇

1.《redis架構組成》 1.redis學習維度 2.一個基本的鍵值型數據庫包括什么&#xff1f; 1.訪問框架 redis通過網絡框架進行訪問&#xff0c;使得 Redis 可以作為一個基礎性的網絡服務進行訪問&#xff0c;擴大了redis應用范圍&#xff1b; 過程&#xff1a;如果客戶端發送“pu…

tomcat監控腳本

#!/bin/sh# func:自動監控tomcat腳本并且執行重啟操作# 獲取tomcat進程ID&#xff08;其中[grep -w .....]中的.....需要替換為實際部署的tomcat文件夾名&#xff0c;如下&#xff09; TomcatID$(ps -ef |grep tomcat |grep -w /usr/local/tomcat/apache-tomcat-8.5.31|grep -v…

weblogic命令行操作

啟動和停止子節點&#xff1a; [rootoud bin]# cd /sotware/oracle_ldap/Middleware/user_projects/domains/base_domain/bin/ [rootoud bin]# ./startManagedWebLogic.sh Server-0 http://192.168.63.129:7001 -Dweblogic.management.usernameweblogic -Dweblogic.management…

Ansible系列--Copy模塊

copy模塊 copy模塊在ansible里的角色就是把ansible執行機器上的文件拷貝到遠程節點上。 與fetch模塊相反的操作 常用參數 參數名是否必須默認值選項說明srcno 用于定位ansible執行的機器上的文件&#xff0c;需要絕對路徑。如果拷貝的是文件夾&#xff0c;那么文件夾會整體…

ANSIBLE--handlers的概念

handlers可以理解成另一種tasks&#xff0c;handlers是另一種’任務列表’&#xff0c;handlers中的任務會被tasks中的任務進行”調用”&#xff0c;但是&#xff0c;被”調用”并不意味著一定會執行&#xff0c;只有當tasks中的任務”真正執行”以后&#xff08;真正的進行實際…

ansible--- tags

tags可以幫助我們對任務進行’打標簽’的操作&#xff0c;當任務存在標簽以后&#xff0c;我們就可以在執行playbook時&#xff0c;借助標簽&#xff0c;指定執行哪些任務&#xff0c;或者指定不執行哪些任務。在實際的使用中&#xff0c;我們應該讓tags的值能夠見名知義。 當…

ANSIBLE---變量

注冊變量 ansible的模塊在運行之后&#xff0c;其實都會返回一些”返回值”&#xff0c;只是默認情況下&#xff0c;這些”返回值”并不會顯示而已&#xff0c;我們可以把這些返回值寫入到某個變量中&#xff0c;這樣我們就能夠通過引用對應的變量從而獲取到這些返回值了&…

inux中限制用戶進程CPU和內存占用率

#!/bin/sh PIDStop -bn 1 | grep "^ *[1-9]" | awk { if($9 > 50 || $10 > 25 && id -u $2 > 500) print $1} echo $PIDS for PID in $PIDS dorenice 10 $PIDecho "renice 10 $PID" done

按月拆分數據庫表--oracle

生產有一張日志表&#xff0c;數據量很大&#xff0c;需要按月進行存儲&#xff0c;存儲過程如下&#xff1a; CREATE OR REPLACE PROCEDURE NEWLOG4_SUB_TABLE IStable_name1 VARCHAR2(50);create_table_sql VARCHAR2(4000);insert_data_sql VARC…

plsql定時器

Oralce中的任務有2種&#xff1a;Job和Dbms_job&#xff0c;兩者的區別有&#xff1a; 1&#xff0e; jobs是oracle數據庫的對象&#xff0c; dbms_jobs只是jobs對象的一個實例&#xff0c; 就像對于tables&#xff0c; emp和dept都是表的實例。 2&#xff0e; 創建方式也有…