(完整版)Nginx模塊fastcgi_cache的幾個注意點_第1頁
(完整版)Nginx模塊fastcgi_cache的幾個注意點_第2頁
(完整版)Nginx模塊fastcgi_cache的幾個注意點_第3頁
(完整版)Nginx模塊fastcgi_cache的幾個注意點_第4頁
免費預(yù)覽已結(jié)束,剩余6頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、Nginx模塊 fastcgi_cache的幾個注意點在 web 項目中, 大家都已經(jīng)非常熟悉其架構(gòu)流程了。都說Cache 是萬金油, 哪里不舒服抹哪里。這些流程中,幾乎每個環(huán)節(jié)都會進行cache 。從瀏覽器到webserver,到cgi程序,到DB數(shù)據(jù)庫,會進行瀏覽器cache,數(shù)據(jù)cache ,SQL查詢的cache等等。對于fastcgi這里的 cache ,很少被使用。去年年底,我對nginx 的 fastcgi_cache進行摸索使用。在我的試過程中,發(fā)現(xiàn)一些WIKI 以及網(wǎng)絡(luò)上沒被提到的注意點,這里分享一下。測從瀏覽器到數(shù)據(jù)庫的流程圖這里是我的NGinx 配置信息#增加調(diào)試信息ad

2、d_header X-Cache-CFC "$upstream_cache_status - $upstream_response_time"fastcgi_temp_path /dev/shm/nginx_tmp;#cache 設(shè)置fastcgi_cache_path /dev/shm/nginx_cache levels=1:2 keys_zone=cfcache:10m inactive=50m;fastcgi_cache_key "$request_method:/$host$request_uri"fastcgi_cache_methods G

3、ET HEAD;fastcgi_cache cfcache;fastcgi_cache_valid any 1d;fastcgi_cache_min_uses 1;fastcgi_cache_use_stale error timeout invalid_header http_500;fastcgi_ignore_client_abort on;配置這些參數(shù)時,注意每個參數(shù)的作用域,像fastcgi_cache_path參數(shù),只能在http配置項里配置,而fastcgi_cache_min_uses這個參數(shù),可以在http 、 server 、 location三個配置項里配置。 這樣更靈活

4、的會每個域名、每個匹配的location進行選擇性cache 了。具體的參數(shù)作用域,參考FASTCGI模塊的官方WIKI。我為了調(diào)試方便,添加了一個X-Cache-CFC的 http響應(yīng)頭,$upstream_cache_status變量表示此請求響應(yīng)來自cache的狀態(tài),分別為:MISS 未命中EXPIRED expired, request was passed to backend Cache已過期UPDATING expired, stale response was used due toproxy/fastcgi_cache_use_stale updating Cache已過期,

5、 ( 被其他 nginx 子進程 ) 更新中STALE expired, stale response was used due to proxy/fastcgi_cache_use_stale Cache 已過期,響應(yīng)數(shù)據(jù)不合法,被污染HIT 命中 cacheFASTCGI_CACHE $upstream_cache_status結(jié)果為 miss ,一次也沒命中程序代碼是Discuz! 論壇,隨便開啟 測試了幾下,發(fā)現(xiàn) /dev/shm/nginx_cache/下沒有任何目錄建立,也沒有文件創(chuàng)建。調(diào)試的http header響應(yīng)頭里的X-Cache-CFC 結(jié)果一直是 MISS。從 服務(wù)器

6、進程上來看,Nginx cache manager process跟 Nginx cache loaderprocess進程也正常運行:root 3100 1 0 14:52 ? 00:00:00 nginx: master process /usr/sbin/nginxwww-data 3101 3100 0 14:52 ? 00:00:00 nginx: worker processwww-data 3102 3100 0 14:52 ? 00:00:00 nginx: cache manager processwww-data 3103 3100 0 14:52 ? 00:00:00 n

7、ginx: cache loader process不知道為何會這樣,為何沒有cache 成功,我以為我配置參數(shù)有問題,只好閱讀WIKI 。發(fā)現(xiàn) fastcgi_ignore_headers參數(shù)下解釋有這么一段fastcgi_ignore_headersSyntax: fastcgi_ignore_headers fieldDefault:Context: httpserverlocationReference: fastcgi_ignore_headersThis directiveforbidsprocessingreply. It is possible to specify heade

8、rs like“X-Accel-Expires” ,“ Expires ” orof the named headersfrom the FastCGI-server“ X-Accel-Redirect”,“ Cache-Control” .也就是說這個參數(shù)的值,將會被忽略掉,同樣被忽略掉的響應(yīng)頭比如”X-Accel-Redirect”,“ X-Accel-Expires”,“ Expires” or“Cache-Control”,而nginx配置中并沒有fastcgi_ignore_headers參數(shù)的設(shè)定,那么問題會不會出現(xiàn)在FASTCGI響應(yīng)結(jié)果里包含了類似”X-Accel-Redire

9、ct” ,“ X-Accel-Expires” ,“ Expires”or“Cache-Control ”這幾個響應(yīng)頭呢 ?用 strace 抓包,看了下 nginx 與 fpm 進程通訊的數(shù)據(jù)#為了確保準(zhǔn)確抓到處理該http請求的進程,我把nginx、 fpm 都只開啟了一個進程處理。/strace -ff -tt -s 1000 -o xxx.log -p PHPFPM-PID14:52:07.837334 write(3, "1601034350X-Powered-By:PHP/5.3.10-1ubuntu3.5rnExpires:Thu, 19 Nov 1981 08:52:

10、00GMTrnCache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0rnPragma:no-cachernContent-type: text/htmlrnrnHellocfc4n13620343270000013010100000000000", 256) = 256/strace -ff -tt -s 1000 -o xxx.log -p Nginx-PID15:05:13.265663 recvfrom(12, "1601034350X-Powered-By:PHP/5.

11、3.10-1ubuntu3.5rnExpires:Thu, 19 Nov 1981 08:52:00GMTrnCache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0rnPragma:no-cachernContent-type: text/htmlrnrnHellocfc4n13620351130000013010100000000000",4023, 0, NULL, NULL)= 256從抓取的數(shù)據(jù)包里可以看到,fpm 確實返回了包含“Expires”、“Cache-Control”

12、頭的http響應(yīng)頭信息。那么疑問來了:nginx的fastcgi_cache沒緩存這條http響應(yīng),是因為響應(yīng)頭里包含“Expires”、“Cache-Control”的原因嗎?程序里并沒有輸出“Expires ”、“ Cache-Control” http header的代碼,這是誰輸出的呢 ?既然是 fpm 響應(yīng)的時候,就已經(jīng)有了,那么是php 的 core 模塊,還是其他拓展模塊輸出的 ?“Expires: ”時間為何是“ Thu, 19 Nov 1981 08:52:00 GMT ” ?疑問比較多,一個一個查起, 先從 Nginx 的 fastcgi_cache沒緩存這條http響應(yīng)查

13、起。我根據(jù)測試環(huán)境nginx 版本 1.1.9(ubuntu12.04 默認(rèn)的 ) ,到 nginx 官方下了對應(yīng)版本的源碼,搜索了 fastcgi 參數(shù)使用的地方,在 httpngx_http_upstream.c 流程的讀懂 nginx 的代碼,但粗略的了解,根據(jù)了解的情況加以猜測,得出了結(jié)論,確定了 nginx 的 fastcgi_cache 的規(guī)則。找到了。雖然不能很再動手測試實驗,也/ngx_http_upstream.c/line 3136當(dāng) fastcgi響應(yīng)包含set-cookie時,不緩存static ngx_int_tngx_http_upstream_process_se

14、t_cookie(ngx_http_request_t *r, ngx_table_elt_t*h,ngx_uint_t offset)#if (NGX_HTTP_CACHE)ngx_http_upstream_t *u;u = r->upstream;if (!(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_SET_COOKIE) u->cacheable = 0;#endifreturn NGX_OK;/line 3242當(dāng)響應(yīng)頭包含Expires時,如果過期時間大于當(dāng)前服務(wù)器 時間,則nginx_cache

15、會緩存該響應(yīng),否則,則不緩存static ngx_int_tngx_http_upstream_process_expires(ngx_http_request_t*r,ngx_table_elt_t*h,ngx_uint_t offset)ngx_http_upstream_t *u;u = r->upstream;u->headers_in.expires = h;#if (NGX_HTTP_CACHE)time_t expires;if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_EXPIRES) re

16、turn NGX_OK;if (r->cache = NULL) return NGX_OK;if (r->cache->valid_sec != 0) return NGX_OK;expires = ngx_http_parse_time(h->value.data, h->value.len);if (expires = NGX_ERROR | expires < ngx_time() u->cacheable = 0;return NGX_OK;r->cache->valid_sec = expires;#endifreturn NG

17、X_OK;/line 3199當(dāng)響應(yīng)頭包含Cache-Control時, #如果 #這里有如果啊。/ 【注意】如果則不緩存 . 不緩存Cache-Control .參數(shù)值為no-cache、no-store、private中任意一個時,/ 【注意】 如果Cache-Control參數(shù)值為max-age時,會被緩存, 且nginx設(shè)置的cache的過期時間,就是系統(tǒng)當(dāng)前時間+ mag-age的值if (ngx_strlcasestrn(p, last, (u_char *) "no-cache", 8 - 1) != NULL| ngx_strlcasestrn(p, las

18、t, (u_char *) "no-store", 8 - 1) != NULL| ngx_strlcasestrn(p, last, (u_char *) "private", 7 - 1) != NULL)u->cacheable = 0; return NGX_OK;p = ngx_strlcasestrn(p, last, (u_char *) "max-age=", 8 - 1); if (p = NULL) return NGX_OK;.r->cache->valid_sec = ngx_time() +

19、 n;也就是說, fastcgi響應(yīng) http 請求的結(jié)果中,響應(yīng)頭包括Expires 、 Cache-Control 、Set-Cookie 三個,都會可能不被cache ,但不只有這些,別忘了nginx 配置中fastcgi_ignore_headers參數(shù)設(shè)定的部分。以及ngxin 的 X-ACCEL X-Accel-Redirect、X-Accel-Expires 、X-Accel-Charset、X-Accel-Buffering等 nginx 自定義的響應(yīng)頭。由于這幾個不常用,我也沒深入研究。通過對nginx的 ngx_http_upstream 模塊代碼模糊理解,加猜測,以及寫了

20、腳本測試驗證,可以得到結(jié)論是正確的。即Nginx fastcgi_cache在緩存后端 fastcgi 響應(yīng)時,當(dāng)響應(yīng)里包含 “ set-cookie”時,不緩存 ; 當(dāng)響應(yīng)頭包含 Expires 時,如果過期時間大于當(dāng)前服務(wù)器時間,則nginx_cache 會緩存該響應(yīng),否則,則不緩存; 當(dāng)響應(yīng)頭包含 Cache-Control時,如果 Cache-Control 參數(shù)值為 no-cache 、no-store 、private中任意一個時,則不緩存,如果Cache-Control參數(shù)值為 max-age 時,會被緩存,且nginx設(shè)置的 cache 的過期時間,就是系統(tǒng)當(dāng)前時間+ mag-

21、age的值。nginx fastcgi_cache響應(yīng) expirednginx fastcgi_cache hit命中FASTCGI_CACHE $upstream_cache_status結(jié)果為 miss ,一次也沒命中。/ 逐個測試,測試時,注釋其他的header("Expires: ".gmdate("D, d M Y H:i:s", time()+10000).' GMT');header("Expires: ".gmdate("D, d M Y H:i:s", time()-99999)

22、.' GMT');header("X-Accel-Expires:30");header("Cache-Control: no-cache");header("Cache-Control: no-store");header("Cache-Control: private");header("Cache-Control: max-age=10");setcookie('cfc4n',"testaaaa");echo 'Hello cfc

23、4n',time();到了這里,疑問1 解決了。那么疑問2、 3 呢 ?程序里并沒有輸出“Expires”、“Cache-Control”http header的代碼,這是誰輸出的呢?既然是fpm 響應(yīng)的時候,就已經(jīng)有了,那么是php 的core模塊,還是其他拓展模塊輸出的?我精簡了代碼,只輸出一個“hello world”,發(fā)現(xiàn)也確實被緩存了。顯然,php 腳本程序中并沒輸出http header的“Expires”、“ Cache-Control”,多次測試,最終定位到session_start函數(shù),翻閱源碼找到了這些代碼:/ext/session/session.c line:1

24、190/ .CACHE_LIMITER_FUNC(private) /* */左右ADD_HEADER("Expires: Thu, 19 Nov 1981 08:52:00 GMT");CACHE_LIMITER(private_no_expire)(TSRMLS_C);/* */ 再到這里3 或者上面幾個# 默認(rèn)是 nocacheCACHE_LIMITER_FUNC(nocache) /* */ADD_HEADER("Expires: Thu, 19 Nov 1981 08:52:00 GMT");/* For HTTP/1.1 conforming

25、 clients and the rest (MSIE 5) */ADD_HEADER("Cache-Control: no-store,no-cache,must-revalidate,post-check=0,pre-check=0");/* For HTTP/1.0 conforming clients */ADD_HEADER("Pragma: no-cache");/* */這里2static php_session_cache_limiter_t php_session_cache_limiters = CACHE_LIMITER_ENTRY

26、(public)CACHE_LIMITER_ENTRY(private)CACHE_LIMITER_ENTRY(private_no_expire)CACHE_LIMITER_ENTRY(nocache)0;static int php_session_cache_limiter(TSRMLS_D) /* */php_session_cache_limiter_t *lim;if (PS(cache_limiter)0 = '0') return 0;if (SG(headers_sent) constchar *output_start_filename= php_outpu

27、t_get_start_filename(TSRMLS_C);int output_start_lineno = php_output_get_start_lineno(TSRMLS_C);if (output_start_filename) php_error_docref(NULLTSRMLS_CC,E_WARNING,"Cannot send sessioncache limiter- headers already sent (output started at %s:%d)", output_start_filename, output_start_lineno); else php_error_docref(NULLTSRMLS_CC,E_WARNING,"Cannot send sessioncache limiter- headers already sent");return -2;for (lim = php_session_cache_limiters; lim->name; lim+) if (!strcasecmp(lim-&g

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論