(完整版)Nginx模块fastcgi_cache的几个注意点_第1页
(完整版)Nginx模块fastcgi_cache的几个注意点_第2页
(完整版)Nginx模块fastcgi_cache的几个注意点_第3页
(完整版)Nginx模块fastcgi_cache的几个注意点_第4页
免费预览已结束,剩余6页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Nginx模块 fastcgi_cache的几个注意点在 web 项目中, 大家都已经非常熟悉其架构流程了。都说Cache 是万金油, 哪里不舒服抹哪里。这些流程中,几乎每个环节都会进行cache 。从浏览器到webserver,到cgi程序,到DB数据库,会进行浏览器cache,数据cache ,SQL查询的cache等等。对于fastcgi这里的 cache ,很少被使用。去年年底,我对nginx 的 fastcgi_cache进行摸索使用。在我的试过程中,发现一些WIKI 以及网络上没被提到的注意点,这里分享一下。测从浏览器到数据库的流程图这里是我的NGinx 配置信息#增加调试信息ad

2、d_header X-Cache-CFC "$upstream_cache_status - $upstream_response_time"fastcgi_temp_path /dev/shm/nginx_tmp;#cache 设置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;配置这些参数时,注意每个参数的作用域,像fastcgi_cache_path参数,只能在http配置项里配置,而fastcgi_cache_min_uses这个参数,可以在http 、 server 、 location三个配置项里配置。 这样更灵活

4、的会每个域名、每个匹配的location进行选择性cache 了。具体的参数作用域,参考FASTCGI模块的官方WIKI。我为了调试方便,添加了一个X-Cache-CFC的 http响应头,$upstream_cache_status变量表示此请求响应来自cache的状态,分别为: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 已过期,响应数据不合法,被污染HIT 命中 cacheFASTCGI_CACHE $upstream_cache_status结果为 miss ,一次也没命中程序代码是Discuz! 论坛,随便开启 测试了几下,发现 /dev/shm/nginx_cache/下没有任何目录建立,也没有文件创建。调试的http header响应头里的X-Cache-CFC 结果一直是 MISS。从 服务器

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 成功,我以为我配置参数有问题,只好阅读WIKI 。发现 fastcgi_ignore_headers参数下解释有这么一段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” .也就是说这个参数的值,将会被忽略掉,同样被忽略掉的响应头比如”X-Accel-Redirect”,“ X-Accel-Expires”,“ Expires” or“Cache-Control”,而nginx配置中并没有fastcgi_ignore_headers参数的设定,那么问题会不会出现在FASTCGI响应结果里包含了类似”X-Accel-Redire

9、ct” ,“ X-Accel-Expires” ,“ Expires”or“Cache-Control ”这几个响应头呢 ?用 strace 抓包,看了下 nginx 与 fpm 进程通讯的数据#为了确保准确抓到处理该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从抓取的数据包里可以看到,fpm 确实返回了包含“Expires”、“Cache-Control”

12、头的http响应头信息。那么疑问来了:nginx的fastcgi_cache没缓存这条http响应,是因为响应头里包含“Expires”、“Cache-Control”的原因吗?程序里并没有输出“Expires ”、“ Cache-Control” http header的代码,这是谁输出的呢 ?既然是 fpm 响应的时候,就已经有了,那么是php 的 core 模块,还是其他拓展模块输出的 ?“Expires: ”时间为何是“ Thu, 19 Nov 1981 08:52:00 GMT ” ?疑问比较多,一个一个查起, 先从 Nginx 的 fastcgi_cache没缓存这条http响应查

13、起。我根据测试环境nginx 版本 1.1.9(ubuntu12.04 默认的 ) ,到 nginx 官方下了对应版本的源码,搜索了 fastcgi 参数使用的地方,在 httpngx_http_upstream.c 流程的读懂 nginx 的代码,但粗略的了解,根据了解的情况加以猜测,得出了结论,确定了 nginx 的 fastcgi_cache 的规则。找到了。虽然不能很再动手测试实验,也/ngx_http_upstream.c/line 3136当 fastcgi响应包含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当响应头包含Expires时,如果过期时间大于当前服务器 时间,则nginx_cache

15、会缓存该响应,否则,则不缓存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当响应头包含Cache-Control时, #如果 #这里有如果啊。/ 【注意】如果则不缓存 . 不缓存Cache-Control .参数值为no-cache、no-store、private中任意一个时,/ 【注意】 如果Cache-Control参数值为max-age时,会被缓存, 且nginx设置的cache的过期时间,就是系统当前时间+ 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响应 http 请求的结果中,响应头包括Expires 、 Cache-Control 、Set-Cookie 三个,都会可能不被cache ,但不只有这些,别忘了nginx 配置中fastcgi_ignore_headers参数设定的部分。以及ngxin 的 X-ACCEL X-Accel-Redirect、X-Accel-Expires 、X-Accel-Charset、X-Accel-Buffering等 nginx 自定义的响应头。由于这几个不常用,我也没深入研究。通过对nginx的 ngx_http_upstream 模块代码模糊理解,加猜测,以及写了

20、脚本测试验证,可以得到结论是正确的。即Nginx fastcgi_cache在缓存后端 fastcgi 响应时,当响应里包含 “ set-cookie”时,不缓存 ; 当响应头包含 Expires 时,如果过期时间大于当前服务器时间,则nginx_cache 会缓存该响应,否则,则不缓存; 当响应头包含 Cache-Control时,如果 Cache-Control 参数值为 no-cache 、no-store 、private中任意一个时,则不缓存,如果Cache-Control参数值为 max-age 时,会被缓存,且nginx设置的 cache 的过期时间,就是系统当前时间+ mag-

21、age的值。nginx fastcgi_cache响应 expirednginx fastcgi_cache hit命中FASTCGI_CACHE $upstream_cache_status结果为 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 响应的时候,就已经有了,那么是php 的core模块,还是其他拓展模块输出的?我精简了代码,只输出一个“hello world”,发现也确实被缓存了。显然,php 脚本程序中并没输出http header的“Expires”、“ Cache-Control”,多次测试,最终定位到session_start函数,翻阅源码找到了这些代码:/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 或者上面几个# 默认是 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. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论