反向代理的一個(gè)問(wèn)題是代理大量用戶時(shí)會(huì)增加服務(wù)器進(jìn)程的性能沖擊影響。在大多數(shù)情況下,可以很大程度上能通過(guò)利用Nginx的緩沖和緩存功能減輕。
當(dāng)代理到另一臺(tái)服務(wù)器,兩個(gè)不同的連接速度會(huì)影響客戶的體驗(yàn):
從客戶機(jī)到Nginx代理的連接。
從Nginx代理到后端服務(wù)器的連接。
Nginx具有優(yōu)化這些連接調(diào)整其行為的能力。
如果沒(méi)有緩沖,數(shù)據(jù)從代理的服務(wù)器發(fā)送并立即開(kāi)始被發(fā)送到客戶。如果假定客戶端很快,緩沖可以關(guān)閉而盡快使數(shù)據(jù)到客戶端,有了緩沖,Nginx 代理將暫時(shí)存儲(chǔ)后端的響應(yīng),然后按需供給數(shù)據(jù)給客戶端。如果客戶端是緩慢的,允許Nginx服務(wù)器關(guān)閉到后端的連接。然后,它可以處理數(shù)據(jù)分配到客戶端, 以任何可能的速度。
Nginx默認(rèn)有緩沖設(shè)計(jì),因?yàn)榭蛻舳送泻艽蟮牟煌倪B接速度。我們可以用以下指令調(diào)節(jié)緩沖行為??梢栽贖TTP,server或 location位置來(lái)設(shè)置。重要的是要記住,大小size指令是針對(duì)每個(gè)請(qǐng)求配置的,所以增加超出你需求會(huì)影響你的性能,如果這時(shí)有許多客戶端請(qǐng)求:
proxy_buffering:該指令控制緩沖是否啟用。默認(rèn)情況下,它的值是“on”。
proxy_buffers:該指令控制代理響應(yīng)緩沖區(qū)的數(shù)量(第一個(gè)參數(shù))和大小(第二個(gè)參數(shù))。默認(rèn)配置是8個(gè)緩沖區(qū)大小等于一個(gè)內(nèi)存頁(yè)(4K或者8K)。增加緩沖區(qū)的數(shù)目可以讓你緩沖更多信息。
proxy_buffer_size:從后端服務(wù)器的響應(yīng)頭緩沖區(qū)大小,它包含headers,和其他部分響應(yīng)是分開(kāi)的。該指令設(shè)置響應(yīng)部分的緩沖區(qū)大小。默認(rèn)情況下,它和proxy_buffers是相同的尺寸,但因?yàn)檫@是用于頭信息,這通??梢栽O(shè)置為一個(gè)較低的值。
proxy_busy_buffers_size:此指令設(shè)置標(biāo)注“client-ready”緩沖區(qū)的最大尺寸。而客戶端可以一次讀取來(lái)自一個(gè)緩沖區(qū)的數(shù)據(jù),緩沖被放置在隊(duì)列中,批量發(fā)送到客戶端。此指令控制允許是在這種狀態(tài)下的緩沖空間的大小。
proxy_max_temp_file_size:這是每個(gè)請(qǐng)求能用磁盤(pán)上臨時(shí)文件最大大小。這些當(dāng)上游響應(yīng)太大不能裝配到緩沖區(qū)時(shí)被創(chuàng)建。
proxy_temp_file_write_size:這是當(dāng)被代理服務(wù)器的響應(yīng)過(guò)大時(shí)Nginx一次性寫(xiě)入臨時(shí)文件的數(shù)據(jù)量。
proxy_temp_path:當(dāng)上游服務(wù)器的響應(yīng)過(guò)大不能存儲(chǔ)到配置的緩沖區(qū)域時(shí),Nginx存儲(chǔ)臨時(shí)文件硬盤(pán)路徑。
正如你所看到的,Nginx提供了相當(dāng)多的不同的指令來(lái)調(diào)整緩沖行為。大多數(shù)時(shí)候,你不必?fù)?dān)心太多,但它對(duì)于調(diào)整一些值可能是有用的??赡茏钣杏玫恼{(diào)整是proxy_buffers和proxy_buffer_size指令。
一個(gè)例子:、
proxy_busy_buffers_size 8k;
proxy_max_temp_file_size 2048m;
proxy_temp_file_write_size 32k;
proxy_pass http://example.com;
盡管緩沖可以幫助釋放后端服務(wù)器以處理更多的請(qǐng)求,Nginx還提供了一種方法來(lái)緩存從后端服務(wù)器的內(nèi)容,對(duì)于許多請(qǐng)求無(wú)需連接到上游。
配置代理緩存
要設(shè)置緩存用于代理內(nèi)容,我們可以使用proxy_cache_path指令。這將創(chuàng)建區(qū)域保存來(lái)自被代理服務(wù)器返回的數(shù)據(jù)。該proxy_cache_path指令必須在HTTP上下文部分進(jìn)行設(shè)置。
在下面的例子中,我們將配置一些相關(guān)的指令來(lái)建立我們的緩存系統(tǒng)。
# http context
proxy_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=backcache:8m max_size=50m;
proxy_cache_key '$scheme$request_method$host$request_uri$is_args$args';
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
用proxy_cache_path指令,我們首先應(yīng)該已經(jīng)定義在文件系統(tǒng)中希望存儲(chǔ)緩存的目錄。在這個(gè)例子中,我們選擇在/var/lib/nginx/cache目錄。如果該目錄不存在,你可以用正確的權(quán)限和所有權(quán)創(chuàng)建它:
sudo mkdir -p /var/lib/nginx/cache
sudo chown www-data /var/lib/nginx/cache
sudo chmod 700 /var/lib/nginx/cache
levels=參數(shù)指定緩存將如何組織。 Nginx將通過(guò)散列鍵(下方配置)的值來(lái)創(chuàng)建一個(gè)緩存鍵。我們選擇了上述的levels決定了單個(gè)字符目錄(這是散列值的最后一個(gè)字符)配有兩個(gè)字符的 子目錄(下兩個(gè)字符取自散列值的末尾)將被創(chuàng)建。你通常不必對(duì)這個(gè)細(xì)節(jié)關(guān)注,但它可以幫助Nginx快速找到相關(guān)的值。
keys_zone=參數(shù)定義緩存區(qū)域的名字,我們稱之為backcache。這也是我們定義多少元數(shù)據(jù)存儲(chǔ)的地方。在這個(gè)例子里,我們是存儲(chǔ)8 MB的key。對(duì)于每兆字節(jié),Nginx可存儲(chǔ)8000左右的條目。MAX_SIZE參數(shù)設(shè)置實(shí)際緩存數(shù)據(jù)的最大尺寸。
我們使用上面的另一個(gè)指令是proxy_cache_key。這個(gè)設(shè)置將設(shè)置用于存儲(chǔ)緩存值的鍵。此鍵用于檢查是否一個(gè)請(qǐng)求可以從高速緩存提供服務(wù)。我們將它設(shè)置成方案(http或https),HTTP請(qǐng)求方法,以及被請(qǐng)求的主機(jī)和URI的組合。
proxy_cache_valid指令可以被指定多次。它依賴于狀態(tài)代碼值使我們能夠配置多長(zhǎng)時(shí)間存儲(chǔ)。在我們的例子中,我們對(duì)于后端返回200和302存儲(chǔ)10分鐘,404響應(yīng)的一分鐘過(guò)期。
現(xiàn)在,我們已經(jīng)配置了緩存區(qū),但我們?nèi)匀恍枰嬖VNginx什么時(shí)候使用緩存。
在我們代理到后端的location位置,我們可以配置使用這個(gè)緩存:
# server context
location /proxy-me {
proxy_cache backcache;
proxy_cache_bypass $http_cache_control;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_pass http://backend;
}
使用proxy_cache指令,就可以指定該backcache緩存區(qū)被用于這個(gè)位置。 Nginx會(huì)在這里檢查傳遞給后端有效的條目。
上述proxy_cache_bypass指令被設(shè)置為$ http_cache_control變量。這將包含一個(gè)指示器,用以指示該客戶端是否被明確地請(qǐng)求一個(gè)最新的,非緩存版本。設(shè)置此指令允許Nginx正確處理這些類型的客戶端請(qǐng)求。無(wú)需進(jìn)行進(jìn)一步的配置。
我們還增加了被稱為X-Proxy-Cache的額外頭。我們?cè)O(shè)置這個(gè)頭部為$ upstream_cache_status變量的值。這個(gè)設(shè)置頭,使我們能夠看到,如果請(qǐng)求導(dǎo)致高速緩存命中,高速緩存未命中,或者高速緩存被明確旁 路。這是對(duì)于調(diào)試特別有價(jià)值,也對(duì)客戶端是有用的信息。
高速緩存能夠極大地提高代理服務(wù)器的性能。不過(guò),也需要明確的考慮配置緩存時(shí)候,要記住。
首先,任何用戶相關(guān)的數(shù)據(jù)不應(yīng)被高速緩存。這可能導(dǎo)致一個(gè)用戶的數(shù)據(jù)被呈現(xiàn)給其他用戶。如果你的網(wǎng)站是完全靜態(tài)的,這可能不是一個(gè)問(wèn)題。
如果你的網(wǎng)站有一些動(dòng)態(tài)元素,你將不得不考慮到這一點(diǎn)。你如何處理要看是什么應(yīng)用程序或服務(wù)器處理的后端處理。對(duì)于私人的內(nèi)容,你應(yīng)該設(shè)置Cache-Control頭為“no-cache”,“no-sotre”,或者“private”依賴于數(shù)據(jù)的性質(zhì):
no-cache:
請(qǐng)求: 告知緩存者,必須原原本本的轉(zhuǎn)發(fā)原始請(qǐng)求,并告知任何緩存者,需要去轉(zhuǎn)發(fā)請(qǐng)求,并驗(yàn)證緩存(如果有的話).對(duì)應(yīng)名詞:端對(duì)端重載.
響應(yīng): 允許緩存者緩存副本.那么其實(shí)際價(jià)值是,總是強(qiáng)制緩存者,校驗(yàn)緩存的新鮮度.一旦確認(rèn)新鮮,則可以使用緩存副本作為響應(yīng). no-cache,還可以指定某個(gè)包含字段,比如一個(gè)典型應(yīng)用,no-cache=Set-Cookie. 這樣做的結(jié)果,就是告知緩存者,對(duì)于Set-Cookie字段,你不要使用緩存內(nèi)容.而是使用新滴.其他內(nèi)容則可以使用緩存
no-store:表示在任何時(shí)候收到的數(shù)據(jù)不被緩存。這對(duì)于私人數(shù)據(jù)是最安全,因?yàn)樗馕吨?,該?shù)據(jù)必須從服務(wù)器每次進(jìn)行檢索。
private:這表明共享的緩存空間不能緩存此數(shù)據(jù)。這可以用于指示用戶的瀏覽器高速緩存數(shù)據(jù),但代理服務(wù)器不應(yīng)當(dāng)考慮隨后的請(qǐng)求數(shù)據(jù)有效。
public:這表明該響應(yīng)是可在連接的任何點(diǎn)被高速緩存的公共數(shù)據(jù)。
一個(gè)相關(guān)的可以控制此行為報(bào)頭是max-age頭,其指示,任何資源應(yīng)該緩存的秒數(shù)。
根據(jù)內(nèi)容的敏感性,正確設(shè)置這些頭,會(huì)幫助你利用緩存優(yōu)勢(shì),同時(shí)保持你的私人數(shù)據(jù)安全,并使您的動(dòng)態(tài)數(shù)據(jù)最新。
如果你的后端也使用Nginx,你可以設(shè)置使用過(guò)期指令,設(shè)置max-age來(lái)實(shí)現(xiàn)Cache-Control:
location / {
expires 60m;
}
location /check-me {
expires -1;
}
在上面的例子中,第一個(gè)塊允許緩存一個(gè)小時(shí)的內(nèi)容。第二塊設(shè)置Cache-Control頭為“無(wú)緩存”。要設(shè)置其他值,可以使用add_header指令,就像這樣:
location /private {
expires -1;
add_header Cache-Control 'no-store';
}
聯(lián)系客服