[code.nginx] Nginx服務(wù)器的緩存機(jī)制

404錯(cuò)誤驅(qū)動(dòng)Web緩存

Nginx服務(wù)器的這一種實(shí)現(xiàn)Web緩存的原理其實(shí)很簡(jiǎn)單,主要還是依靠自身的Proxy Store功能對(duì)404錯(cuò)誤進(jìn)行重定向來(lái)實(shí)現(xiàn)。當(dāng)Nginx服務(wù)器在處理客戶端請(qǐng)求時(shí),發(fā)現(xiàn)請(qǐng)求的資源數(shù)據(jù)不存在,會(huì)產(chǎn)生404錯(cuò)誤,然后服務(wù)器通過(guò)捕獲該錯(cuò)誤,進(jìn)一步轉(zhuǎn)向后端服務(wù)器請(qǐng)求數(shù)據(jù),最后將后端服務(wù)器的響應(yīng)數(shù)據(jù)傳回客戶端,同時(shí)在本地進(jìn)行緩存。從實(shí)現(xiàn)-原理上來(lái)看,Nginx服務(wù)器向后端服務(wù)器發(fā)起數(shù)據(jù)請(qǐng)求并完成Web緩存,主要是由產(chǎn)生的404錯(cuò)誤驅(qū)動(dòng)的。
請(qǐng)大家看一個(gè)簡(jiǎn)單的實(shí)現(xiàn)404錯(cuò)誤驅(qū)動(dòng)Web緩存的配置方案片段:

          ...
          location / {
                   ...
                  root /myweb/server/;
                  error_page 404 =200  /errpage 
         }
         location /errpage/ {
                  ...
                  internal;
                  alias /home/html;
                  proxy_pass http://backend;

                  proxy_set_header  Accept-Encoding  "'';  #后端不返回要鎖(gzip/deflate)數(shù)據(jù)
                  proxy_store on;  #指定Nginx將代理返回的文件保存
                  proxy_store_access user:rw group:rw all:r;  #配置緩存數(shù)據(jù)的訪問(wèn)權(quán)限
                  proxy_temp_path  /myweb/server/tmp;  #配置臨時(shí)目錄,該目錄要和/myweb/server/在同一個(gè)硬盤(pán)分區(qū)內(nèi)
        }

配置將404錯(cuò)誤響應(yīng)進(jìn)行重定向,然后使用location塊捕獲重定向請(qǐng)求,向后端服務(wù)器發(fā)起請(qǐng)求獲取響應(yīng)數(shù)據(jù),然后將數(shù)據(jù)轉(zhuǎn)發(fā)給客戶端的同時(shí)緩存到本地。

資源不存在驅(qū)動(dòng)Web緩存

該方法同“404錯(cuò)誤驅(qū)動(dòng)Web緩存”的方法的原理上大同小異,不同之處是,該方法是通過(guò)location塊的location if條件判斷直接驅(qū)動(dòng)Nginx服務(wù)器與后端服務(wù)器的通信和Web緩存,而后者是對(duì)資源不存在引發(fā)的404錯(cuò)誤進(jìn)行捕獲,進(jìn)而驅(qū)動(dòng)Nginx服務(wù)器與后端服務(wù)器的通信和Web緩存。
再看一個(gè)簡(jiǎn)單的通過(guò)判斷資源不存在的驅(qū)動(dòng)Web緩存的配置方案片段:
···nginx
...#其他配置
location / {
...#其他配置
root /home/html/;
internal;; #配置該為目錄不能通過(guò)外部鏈接直接訪問(wèn)
alias /myweb/server/;
proxy_set_header Accept-Encoding "''; #配置后端不反悔要鎖(gzip或deflate)數(shù)據(jù)
proxy_store on; #指定nginx將代理返回的文件保存
proxy_store_access user:w group:rw all:r; #配置緩存數(shù)據(jù)的訪問(wèn)權(quán)限
proxy_temp_path /myweb/server/tmp; #配置臨時(shí)目錄,該目錄要和/myweb/server/在同一個(gè)硬盤(pán)分區(qū)內(nèi)
if(!-f $request_filename) #判斷請(qǐng)求資源是否存在
{
proxy_pass http://backend/; #配置后端upstream地址或者源地址
}
}

在配置實(shí)例中使用location if條件判斷支持的“!-f”判斷請(qǐng)求的資源在Nginx服務(wù)器上是否存在,如果不存在就通過(guò)后端服務(wù)器獲取數(shù)據(jù),然后回傳給客戶端,同時(shí)使用Proxy Store進(jìn)行緩存。
以上兩種緩存機(jī)制在原理上是相近的,在實(shí)際的應(yīng)用中,我們通??梢詫roxy Store的緩存目錄配置到/dev/shm中提高緩存數(shù)據(jù)的處理速度。如果不是在內(nèi)存中保存緩存數(shù)據(jù),這兩種緩存機(jī)制不支持緩存數(shù)據(jù)的清理機(jī)制,緩存文件會(huì)一直保存在本地占用硬盤(pán)空間。
這兩種緩存機(jī)制還有需要注意的地方是它們只能緩存200狀態(tài)嗎下的響應(yīng)數(shù)據(jù),這就是為什么我們?cè)诮榻B“404錯(cuò)誤驅(qū)動(dòng)Web緩存”機(jī)制時(shí)配置實(shí)例中將404錯(cuò)誤重新改寫(xiě)為200狀態(tài)的原因。

兩種緩存機(jī)制也不支持動(dòng)態(tài)鏈接的請(qǐng)求。比如getsource?id=1和getsource?id=2這兩個(gè)請(qǐng)求,這兩種緩存機(jī)制會(huì)忽略id=1參數(shù),從而造成返回的資源不正確等問(wèn)題。這是兩種緩存機(jī)制的缺點(diǎn),但在實(shí)際應(yīng)用中也有一定的使用價(jià)值。
 
## 基于memcached的緩存機(jī)制
memcached是一套高性能的基于分布式的緩存系統(tǒng),用于動(dòng)態(tài)Web應(yīng)用以減輕后臺(tái)服務(wù)器的負(fù)載。memcached可以處理并發(fā)的網(wǎng)絡(luò)連接。它在內(nèi)存中開(kāi)辟一塊空間,然后建立一個(gè)hash表,將緩存數(shù)據(jù)通過(guò)鍵/值存儲(chǔ)在Hash表中進(jìn)行管理。memcached由服務(wù)端和客戶端兩個(gè)核心組件組成,服務(wù)端先通過(guò)計(jì)算“鍵”的hash值來(lái)確定鍵/值對(duì)所在的服務(wù)器所處的位置。當(dāng)確定鍵/值對(duì)的位置后,客戶端就會(huì)發(fā)送一個(gè)查詢請(qǐng)求給對(duì)應(yīng)的服務(wù)端,讓它來(lái)查找并返回確切的數(shù)據(jù)。
在Nginx服務(wù)器的標(biāo)準(zhǔn)HTTP模塊中有一個(gè)ngx_http_memcached_module模塊,專門(mén)用于處理和memcached相關(guān)的配置和功能實(shí)現(xiàn),雖然在目前的版本中還沒(méi)有支持完整的功能,但是其性能很好,對(duì)于一般的應(yīng)用場(chǎng)景是比較好的選擇方案。

## Proxy Cache緩存機(jī)制
Proxy Cache機(jī)制是Nginx服務(wù)器自己實(shí)現(xiàn)的類似于Squid的緩存機(jī)制,它使用md5算法將請(qǐng)求鏈接hash后生成文件系統(tǒng)目錄保存響應(yīng)數(shù)據(jù)。
Nginx服務(wù)器在啟動(dòng)后,會(huì)生成專門(mén)的進(jìn)程對(duì)磁盤(pán)上的緩存文件進(jìn)行掃描,在內(nèi)存中建立緩存索引,提高訪問(wèn)效率,而且還會(huì)生成專門(mén)的管理進(jìn)程對(duì)磁盤(pán)上的緩存文件進(jìn)行過(guò)期判斷,更新等方面的管理。Proxy Cache緩存機(jī)制支持對(duì)任意鏈接響應(yīng)數(shù)據(jù)的緩存,不僅限于200狀態(tài)時(shí)的數(shù)據(jù)。
Proxy Cache緩存機(jī)制的一個(gè)缺陷是,他沒(méi)有實(shí)現(xiàn)自動(dòng)清理磁盤(pán)上緩存數(shù)據(jù)的功能,因此在長(zhǎng)時(shí)間使用過(guò)程中對(duì)服務(wù)器存儲(chǔ)造成一定的壓力。
在下面的配置中,實(shí)現(xiàn)了Nginx服務(wù)器Proxy Cache緩存機(jī)制的一般配置:
```nginx
      ...#其他配置
      http {
            ...#其他配置
            proxy_cache_path  /myweb/server/proxycache  levels=1:2  max_size=2m  inactive=5m
            loader_sleep=1m;  keys_zone=MYPROXYCACHE:10m  #配置了緩存數(shù)據(jù)存放路徑和Proxy Cache使用
            proxy_temp_path  /myweb/server/tmp;  #配置響應(yīng)數(shù)據(jù)的臨時(shí)存放目錄
            server {
                    ...... #其他配置
                    proxy_pass http://www.myweb.name/;  #配置使用MYPROXYCACHE這個(gè)keys_zone
                    proxy_cache  MYPROXYCACHE;  # 配置200狀態(tài)和302狀態(tài)的響應(yīng)緩存1小時(shí)
                    proxy_cache_valid  200 302 1h;  #配置200和302狀態(tài)的響應(yīng)緩存1小時(shí)
                    proxy_cache_valid  301  1d;  #配置301狀態(tài)的響應(yīng)緩存1天
                    proxy_cache_valid  any 1m;  #配置其他狀態(tài)的響應(yīng)數(shù)據(jù)緩存1分鐘

            }
      }

在該實(shí)例中,我們首先在http塊中配置了緩存數(shù)據(jù)存放路徑和Proxy Cache使用的內(nèi)存Cache空間。緩存數(shù)據(jù)存放在磁盤(pán)上/myweb/server/proxycache目錄下,它包含兩級(jí)hash目錄,緩存數(shù)據(jù)的總量不能超過(guò)20MB、如果緩存在5分鐘內(nèi)沒(méi)有被訪問(wèn),則強(qiáng)制更新。內(nèi)存Cache空間的名字為MYPROXYCACHE,大小不能超過(guò)10MB,每隔1分鐘遍歷一次磁盤(pán)緩存源數(shù)據(jù),更新內(nèi)存Cache中的緩存索引。
之后,我們?cè)趕erver塊中,配置使用上面設(shè)置好的MYPROXYCACHE內(nèi)存空間進(jìn)行Proxy Cache工作,對(duì)不同響應(yīng)狀態(tài)的數(shù)據(jù)緩存時(shí)間進(jìn)行了配置。
Proxy Cache機(jī)制是Nginx服務(wù)器自身實(shí)現(xiàn)的一個(gè)功能比較完整、性能也不錯(cuò)的緩存機(jī)制,在實(shí)際應(yīng)用過(guò)程后者能夠使用比較廣泛。

Nginx與Squid組合

Squid Cache(簡(jiǎn)稱Squid)是目前在大訪問(wèn)量的網(wǎng)站建設(shè)中應(yīng)用非常廣泛的Web緩存服務(wù)器。它可以作為網(wǎng)頁(yè)服務(wù)器的前置緩存服務(wù)器來(lái)緩存相關(guān)的請(qǐng)求數(shù)據(jù),也可以緩存公網(wǎng)資源為局域網(wǎng)內(nèi)用戶提供共享資源。但是,Squid服務(wù)本身不支持在單臺(tái)服務(wù)器同一端口(例如要反向道理Web必須制定80端口)下運(yùn)行多個(gè)進(jìn)程,這樣的話就需要給每一個(gè)Squid服務(wù)分配一臺(tái)服務(wù)器設(shè)備,這樣非常浪費(fèi)資源。
Nginx具有反向代理服務(wù)功能,支持服務(wù)器組的配置和對(duì)組間服務(wù)器的輪詢,我們可以運(yùn)用Nginx的這一功能,實(shí)現(xiàn)在同一臺(tái)服務(wù)器中運(yùn)行多個(gè)Squid服務(wù)的目的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容