关于nginx.conf里的fastcgi_cache配置及如何删除fastcgi缓存 及 nginx开启fastcgi缓存时请求php出现页面内容为空问题的原因

一、关于nginx.conf里的fastcgi_cache配置及如何删除fastcgi缓存

    从0.7.48版本开始,Nginx支持类似Squid的缓存功能。这个缓存是把URL及相关组合当做Key(可在nginx配置文件中配置),用Md5算法对Key进行哈希,最后将内容以文本格式得到硬盘上对应的哈希目录路径,从而将缓存内容保存在该目录内。这对一些采用静态页面缓存的新闻网站非常适合,不需要任何代码开发,直接生成缓存。

    nginx启用fastcgi缓存最关键的配置1,在http项里加上下面的配置:

fastcgi_cache_path /var/fastcgi_cache_dir levels=1:2 keys_zone=cache_fastcgi:128m inactive=1d max_size=1g;

     语法格式:fastcgi_cache_path path [levels=m:n] keys_zone=name:size [inactive=time] [max_size=size]

     上述命令指定了fastcgi的配置荐:levels缓存层次,keys_zone 缓存空间名和共享内存大小(热点内容放在内存),inactive  失效时间, 1d = 1天,max_size最大缓存空间(硬盘占用)。这是http模块中必加配置,然后在server模块中结合php的配置里需要添加:

location ~ [^/].php(/|$)
{
    try_files $uri =404;
    fastcgi_pass  unix:/tmp/php-cgi.sock;
    fastcgi_index index.php;
    include fastcgi.conf;
    
    #fastcgi的缓存配置
    expires                     20m;                    #缓存时间20分钟
    fastcgi_cache               cache_fastcgi;          #cache的命令空间,要在nginx配置的keys_zone里   
    fastcgi_cache_valid         200 301 302 25m;        #这些状态码缓存,404之类的不缓存
    fastcgi_cache_key           $request_method$host$uri$is_args$args;   #缓存的key
    fastcgi_cache_use_stale     error timeout http_500;
    add_header                  X-Cache-Source $upstream_cache_status;    #命中缓存时增响应
    fastcgi_hide_header         X-Powered-By;

    fastcgi_connect_timeout     30s;
    fastcgi_read_timeout        40s;
    fastcgi_send_timeout        30s;
}

     加完配置后重启nginx,访问一些URL,就会看到在缓存目录下新生成文件,这些文件格式是:DBase 3 data file。截图如下:

    如果要删除缓存直接来这个目录下清空缓存即可,目前虽然知道fastcgi是通过md5加密key来生成的目录名和文件名,但不清楚体的名称和目录名怎么来的。前台访问时可查看头部信息里是否有这项

X-Cache-Source:HIT,如果有就是命中了fastcgi缓存,如果没命中则是X-Cache-Source:MISS

    补充:网上有个路径的生成方法,我未检验,不知是否可行,放这里一下:

$cacheFile = $this->_cacheRoot . '/' . substr($md5, -1) . '/' . substr($md5, -3, 2) . '/' . $md5;

二、nginx开启fastcgi缓存时请求php出现页面内容为空问题的原因

     某次碰到一个怪问题,请求的接口好好的,但是偶尔出现了请求的内容为空,查看header信息,表示命中了fastcgi缓存:X-Cache-Source:HIT,经过排查发现问题出在fastcgi的缓存key上。

fastcgi_cache_key           $host$uri$is_args$args;

     如上是服务器里的fastcgi_cache_key的配置,其中的$host$uri$is_args$args参数意义如下:

$host 等于请求头中Host的值。
$uri  等于当前请求中的URI(没有参数,不包括$args)的值。
$is_args   如果设置了$args,那么值为“?”,否则为“”
$args      该变量的值是GET请求在请求行中的参数。

     比如访问本站页面:http://kermit.linge/article/99.html?user=kermit 则缓存的KEY为http://kermit.linge/article/99.html?user=kermit,然后所有指向这个URL的请求都会调用这个缓存,看上去没有问题,但是我们忽略了请求不只有GET,还有POST,还有HEAD。而默认fasctcgi是缓存GET和HEAD两种请求。

fastcgi_cache_methods
语法:fastcgi_cache_methods [GET HEAD POST]; 
默认值:fastcgi_cache_methods GET HEAD; 
使用字段:main,http,location 

     看配置好像当设置为fastcgi_cache_methods  GET;时就只缓存GET,其实不仍,fastcgi无法禁用GET和HEAD请求。即不管你怎么设置它都会缓存GET和HEAD,只有POST是一个可选项,所以当你配置了fastcgi_cache_methods  GET后,如果你的页面在fastcgi缓存过期而新缓存未建立的这段时间里有一些HEAD请求(特别是一个服务器监控方面的请求)过来的话(head请求不会返回内容实体信息),就会导致fastcgi生成一些空内容的缓存。可以使用一些在线的head模拟请求或者使用postman测试。而之后再进行GET请求时就会命中这些空内容缓存,显示内容为空。

    解决方法是,对缓存根据请求方式进行缓存,修改fastcgi_cache_key的配置值:

fastcgi_cache_key           $request_method$host$uri$is_args$args;

    然后重启nginx即可(因为key变了,所以不会命中原有的缓存,所以只需重启nginx)。

    补充:后来看到有的配置里还会加上:$scheme。

    $scheme  表示HTTP scheme(例如HTTP,HTTPS),如果你的页面访问分为https和http,则需要看情况是不是需要加上$scheme当做缓存的key。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林戈的IT生涯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值