nginx服務器開啟緩存、反向代理


一、反向代理配置

1、反向代理服務器配置如下

   

  反向代理就是需要這一行proxy_pass來完成。當我們要訪問后端web服務器的時候,我們只需要訪問代理服務器就可以了,此時代理服務器就充當后端web服務器的角色。proxy_pass依賴的模塊是:

      

  至於后兩行是什么意思呢?

    “proxy_set_header Host”表示后端web服務器的域名要與當前配置文件中的域名保持一致。

  后端web服務器我們配置一下:

    

    

    

  代理服務器和web服務器都重載一下nginx。我們在windows上瀏覽一下(注意修改hosts文件,對代理服務器ip添加映射)

         看看這個

    瀏覽成功了。反向代理成功。訪問不同的域名有不同的路徑關系。

2、proxy_pass后面的域名加上一個“/”是什么作用呢?

  比如:后面有沒有加上這個“/”,差別是很大的。

  比如:我們再次配置代理服務器:

    

     注意在web服務器上也要創建admin目錄。然后我們訪問一下:

    

    再看看這個目錄:

        

 

     總結:這就是加不加根號“/”的區別。不加根號表示域名的后面跟上location中的uri。而加上根號則表示域名后面的根替換了location后的uri。此時訪問的是根下的index.html。所以說當你的location后面只有一個根“/”,域名結尾加不加“/”都一個樣子,但是location后面有uri時,域名后面加不加根差別很大。還有一個:

    

    當location中包含正則表達式的時候,proxy_pass的域名后面絕對不能帶上根號,否則報錯:

      

 

總結:

 

 

2、proxy_set_header field value;
  設定發往后端主機的請求報文的請求首部的值;Context: http, server, location

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

一般是來說我們更多使用X-Forwarded-For這個參數,參數的用法我在之前的博客也說過。https://www.cnblogs.com/FengGeBlog/p/10529821.html

 

   添加響應報文守護主要是將添加的內容發送給客戶端的,比如上面那個add_header參數,“add_header X-Vis  $server_addr”表示將服務器地址發送給客戶端。

      

 3、緩存話題:

 

 

一個web緩存坐落於客戶端和“原始服務器(origin server)”中間,它保留了所有可見內容的拷貝。如果一個客戶端請求的內容在緩存中存儲,則可以直接在緩存中獲得該內容而不需要與服務器通信。這樣一來,由於web緩存距離客戶端“更近”,就可以提高響應性能,並更有效率的使用應用服務器,因為服務器不用每次請求都進行頁面生成工作。

在瀏覽器和應用服務器之間,存在多種“潛在”緩存,如:客戶端瀏覽器緩存、中間緩存、內容分發網絡(CDN)和服務器上的負載平衡和反向代理。緩存,僅在反向代理和負載均衡的層面,就對性能提高有很大的幫助。

舉個例子說明,去年,我接手了一項任務,這項任務的內容是對一個加載緩慢的網站進行性能優化。首先引起我注意的事情是,這個網站差不多花費了超過1秒鍾才生成了主頁。經過一系列調試,我發現加載緩慢的原因在於頁面被標記為不可緩存,即為了響應每一個請求,頁面都是動態生成的。由於頁面本身並不需要經常性的變更,並且不涉及個性化,那么這樣做其實並沒有必要。為了驗證一下我的結論,我將頁面標記為每5秒緩存一次,僅僅做了這一個調整,就能明顯的感受到性能的提升。第一個字節到達的時間降低到幾毫秒,同時頁面的加載明顯要更快。

並不是只有大規模的內容分發網絡(CDN)可以在使用緩存中受益——緩存還可以提高負載平衡器、反向代理和應用服務器前端web服務的性能。通過上面的例子,我們看到,緩存內容結果,可以更高效的使用應用服務器,因為不需要每次都去做重復的頁面生成工作。此外,Web緩存還可以用來提高網站可靠性。當服務器宕機或者繁忙時,比起返回錯誤信息給用戶,不如通過配置NGINX將已經緩存下來的內容發送給用戶。這意味着,網站在應用服務器或者數據庫故障的情況下,可以保持部分甚至全部的功能運轉。
1)如何安裝配置基礎緩存。
我們只需要兩個命令就可以啟用基礎緩存: proxy_cache_path[1]和proxy_cache[2]。proxy_cache_path用來設置緩存的路徑和配置,proxy_cache用來啟用緩存。
我們建議將proxy_cache_path放在nginx的主配置文件http段中,表示對所有的server生效。
http{
proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off; server { ... location / { proxy_cache my_cache; proxy_pass http://my_upstream; } }
}
 
         

proxy_cache_path命令中的參數及對應配置說明如下:

1.用於緩存的本地磁盤目錄是/path/to/cache/

2.levels在/path/to/cache/設置了一個兩級層次結構的目錄。將大量的文件放置在單個目錄中會導致文件訪問緩慢,所以針對大多數部署,我們推薦使用兩級目錄層次結構。如果levels參數沒有配置,則NGINX會將所有的文件放到同一個目錄中。

3.keys_zone設置一個共享內存區,該內存區用於存儲緩存鍵和元數據,有些類似計時器的用途。將鍵的拷貝放入內存可以使NGINX在不檢索磁盤的情況下快速決定一個請求是`HIT`還是`MISS`,這樣大大提高了檢索速度。一個1MB的內存空間可以存儲大約8000個key,那么上面配置的10MB內存空間可以存儲差不多80000個key。

4.max_size設置了緩存的上限(在上面的例子中是10G)。這是一個可選項;如果不指定具體值,那就是允許緩存不斷增長,占用所有可用的磁盤空間。當緩存達到這個上線,處理器便調用cache manager來移除最近最少被使用的文件,這樣把緩存的空間降低至這個限制之下。

5.inactive指定了項目在不被訪問的情況下能夠在內存中保持的時間。在上面的例子中,如果一個文件在60分鍾之內沒有被請求,則緩存管理將會自動將其在內存中刪除,不管該文件是否過期。該參數默認值為10分鍾(10m)。注意,非活動內容有別於過期內容。NGINX不會自動刪除由緩存控制頭部指定的過期內容(本例中Cache-Control:max-age=120)。過期內容只有在inactive指定時間內沒有被訪問的情況下才會被刪除。如果過期內容被訪問了,那么NGINX就會將其從原服務器上刷新,並更新對應的inactive計時器。

6.NGINX最初會將注定寫入緩存的文件先放入一個臨時存儲區域, use_temp_path=off命令指示NGINX將在緩存這些文件時將它們寫入同一個目錄下。我們強烈建議你將參數設置為off來避免在文件系統中不必要的數據拷貝。use_temp_path在NGINX1.7版本和NGINX Plus R6[3]中有所介紹。

最終, proxy_cache命令啟動緩存那些URL與location部分匹配的內容(本例中,為`/`)。你同樣可以將proxy_cache命令添加到server部分,這將會將緩存應用到所有的那些location中未指定自己的proxy_cache命令的服務中。

NGINX內容緩存[4]的一個非常強大的特性是:當無法從原始服務器獲取最新的內容時,NGINX可以分發緩存中的陳舊(stale,編者注:即過期內容)內容。這種情況一般發生在關聯緩存內容的原始服務器宕機或者繁忙時。比起對客戶端傳達錯誤信息,NGINX可發送在其內存中的陳舊的文件。NGINX的這種代理方式,為服務器提供額外級別的容錯能力,並確保了在服務器故障或流量峰值的情況下的正常運行。為了開啟該功能,只需要添加proxy_cache_use_stale[5]命令即可:

 

location / {
    ...
    proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
}

 

按照上面例子中的配置,當NGINX收到服務器返回的error,timeout或者其他指定的5xx錯誤,並且在其緩存中有請求文件的陳舊版本,則會將這些陳舊版本的文件而不是錯誤信息發送給客戶端。

2)緩存微調

NGINX提供了豐富的可選項配置用於緩存性能的微調。

proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m
                 use_temp_path=off;

server {
    ...
    location / {
        proxy_cache my_cache;
        proxy_cache_revalidate on;
        proxy_cache_min_uses 3;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
        proxy_cache_lock on;

        proxy_pass http://my_upstream;
    }
}

這些命令配置了下列的行為:

1.proxy_cache_revalidate[6]指示NGINX在刷新來自服務器的內容時使用GET請求。如果客戶端的請求項已經被緩存過了,但是在緩存控制頭部中定義為過期,那么NGINX就會在GET請求中包含If-Modified-Since字段,發送至服務器端。這項配置可以節約帶寬,因為對於NGINX已經緩存過的文件,服務器只會在該文件請求頭中Last-Modified記錄的時間內被修改時才將全部文件一起發送。

2.proxy_cache_min_uses[7]設置了在NGINX緩存前,客戶端請求一個條目的最短時間。當緩存不斷被填滿時,這項設置便十分有用,因為這確保了只有那些被經常訪問的內容才會被添加到緩存中。該項默認值為1。

3.proxy_cache_use_stale[8]中的updating參數告知NGINX在客戶端請求的項目的更新正在原服務器中下載時發送舊內容,而不是向服務器轉發重復的請求。第一個請求陳舊文件的用戶不得不等待文件在原服務器中更新完畢。陳舊的文件會返回給隨后的請求直到更新后的文件被全部下載。

4.當proxy_cache_lock[9]被啟用時,當多個客戶端請求一個緩存中不存在的文件(或稱之為一個MISS),只有這些請求中的第一個被允許發送至服務器。其他請求在第一個請求得到滿意結果之后在緩存中得到文件。如果不啟用proxy_cache_lock,則所有在緩存中找不到文件的請求都會直接與服務器通信。

3)跨多硬盤分隔緩存

使用NGINX,不需要建立一個RAID(磁盤陣列)。如果有多個硬盤,NGINX可以用來在多個硬盤之間分割緩存。下面是一個基於請求URI跨越兩個硬盤之間均分緩存的例子:

proxy_cache_path /path/to/hdd1 levels=1:2 keys_zone=my_cache_hdd1:10m max_size=10g 
                 inactive=60m use_temp_path=off;
proxy_cache_path /path/to/hdd2 levels=1:2 keys_zone=my_cache_hdd2:10m max_size=10g 
                 inactive=60m use_temp_path=off;

split_clients $request_uri $my_cache {
              50%          “my_cache_hdd1”;
              50%          “my_cache_hdd2”;
}

server {
    ...
    location / {
        proxy_cache $my_cache;
        proxy_pass http://my_upstream;
    }
}

上例中的兩個proxy_cache_path定義了兩個緩存(my_cache_hdd1和my_cache_hd22)分屬兩個不同的硬盤。split_clients[10]配置部分指定了請求結果的一半在my_cache_hdd1中緩存,另一半在my_cache_hdd2中緩存。基於$request_uri(請求URI)變量的哈希值決定了每一個請求使用哪一個緩存,對於指定URI的請求結果通常會被緩存在同一個緩存中。

4)常見問題解答

4.1)可以檢測NGINX緩存狀態嗎?

可以,使用add_header[11]指令:

add_header X-Cache-Status $upstream_cache_status;

上面的例子中,在對客戶端的響應中添加了一個`X-Cache-Status`HTTP響應頭,下面是$upstream_cache_status[12]的可能值:

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

4.2)nginx如何決定緩存

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

Cache-Control頭部可否被忽略?

可以,使用proxy_ignore_headers命令。如下列配置:

location /images/ {
    proxy_cache my_cache;
    proxy_ignore_headers Cache-Control;
    proxy_cache_valid any 30m;
    ...
}

NGINX會忽略所有/images/下的Cache-Control頭。proxy_cache_valid[15]命令強制規定緩存數據的過期時間,如果忽略Cache-Control頭,則該命令是十分必要的。NGINX不會緩存沒有過期時間的文件。

4.3)NGINX 可以緩存動態內容嗎?

可以,提供的Cache-Control頭部可以做到。緩存動態內容,甚至短時間內的內容可以減少在原始數據庫和服務器中加載,可以提高第一個字節的到達時間,因為頁面不需要對每個請求都生成一次。

4.4)nginx使用了哪些緩存鍵?

NGINX生成的鍵的默認格式是類似於下面的NGINX變量[17]的MD5哈希值: $scheme$proxy_host$request_uri,實際的算法有些復雜。

proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m
                 use_temp_path=off;

server {
    ...
    location / {
        proxy_cache $my_cache;
        proxy_pass http://my_upstream;
    }
}

按照上面的配置, http://www.example.org/my_image.jpg的緩存鍵被計算為md5(“http://my_upstream:80/my_image.jpg”)。

注意,$proxy_host[18]變量用於哈希之后的值而不是實際的主機名(www.example.com)。$proxy_host被定義為proxy_pass[19]中指定的代理服務器的主機名和端口號。

為了改變變量(或其他項)作為基礎鍵,可以使用proxy_cache_key[20]命令(下面的問題會講到)。

4.5)可以使用Cookie作為緩存鍵的一部分嗎?

可以,緩存鍵可以配置為任意值,如:

proxy_cache_key $proxy_host$request_uri$cookie_jessionid;

 

 

案例演示:

    

    其他的參數使用默認值就可以了。

補充點知識:

2、proxy_set_header field value;
                設定發往后端主機的請求報文的請求首部的值;Context:    http, server, location
                
                proxy_set_header X-Real-IP  $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                
            3、proxy_cache_path
                定義可用於proxy功能的緩存;Context:    http            
                
                proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
                
            4、proxy_cache zone | off;
                指明要調用的緩存,或關閉緩存機制;Context:    http, server, location
                
            5、    proxy_cache_key string;
                緩存中用於“鍵”的內容;
                
                默認值:proxy_cache_key $scheme$proxy_host$request_uri;
                
            6、proxy_cache_valid [code ...] time;
                定義對特定響應碼的響應內容的緩存時長;
                
                定義在http{...}中;
                proxy_cache_path /var/cache/nginx/proxy_cache levels=1:1:1 keys_zone=pxycache:20m max_size=1g;
                
                定義在需要調用緩存功能的配置段,例如server{...};
                proxy_cache pxycache;
                proxy_cache_key $request_uri;
                proxy_cache_valid 200 302 301 1h;
                proxy_cache_valid any 1m;
                
            7、proxy_cache_use_stale
                
                proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ...;
                
                Determines in which cases a stale cached response can be used when an error occurs during communication with the proxied server.
                
            8、proxy_cache_methods GET | HEAD | POST ...;
                If the client request method is listed in this directive then the response will be cached. “GET” and “HEAD” methods are always added to the list, though it is recommended to specify them explicitly. 
                
            9、proxy_hide_header field;
                By default, nginx does not pass the header fields “Date”, “Server”, “X-Pad”, and “X-Accel-...” from the response of a proxied server to a client. The proxy_hide_header directive sets additional fields that will not be passed.
                
            10、proxy_connect_timeout time;
                Defines a timeout for establishing a connection with a proxied server. It should be noted that this timeout cannot usually exceed 75 seconds.
                
                客戶端面向服務端的超時連接是多長時間。默認為60s;最長為75s;
                
            11、proxy_read_timeout time; 
                Defines a timeout for reading a response from the proxied server. The timeout is set only between two successive read operations, not for the transmission of the whole response.
                
            12、proxy_send_timeout time;
                Sets a timeout for transmitting a request to the proxied server. he timeout is set only between two successive write operations, not for the transmission of the whole request. If the proxied server does not receive anything within this time, the connection is closed.
                    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM