nginx php 缓存

这边一直有个php cache的应用,原理是发起一个对自身的请求,保存成静态文件
之前这个应用在apache worker模式跑得很好,换到nginx的fast-cgi 后一直不是很正常

这个问题跟spawn-fcgi的工作原理有关: spawn-fcgi起N个进程,然后FIFO排队处理请求
当有并发>N个PHP CACHE的应用请求过来的时候,php cache的应用会再对自身发起请求,这个请求排在了这些请求的后边,而实际上不会有新的进程来处理这些请求,从而形成死锁,日志中会充斥”upstream timed out” “no live upstreams”

因此,工作模式的排队理论本身决定了这个故障不可避免

解决办法:使用nginx proxy_cache 绕开这个问题,把php cache这个功能交给proxy_cache来完成,nginx的work process遇到阻塞等待的情况,会把这个请求的工作sleep一段时间处理接下来的请求,这个特点明显优于spawn-fcgi的行为

1.建立 /cache/打头的可缓存php location

location ~* ^/cache/(.*\.php)${

}

2. 设置相关的proxy_cache:

1) CACHEZONE:

proxy_cache_path /dev/shm/cache/app.gd.sohu.com levels=1:2 keys_zone=default:100m max_size=4g inactive=20m;

2) CACHE目录:

proxy_read_timeout 5s;
proxy_connect_timeout 5s;
proxy_set_header Host $host;
proxy_cache_use_stale updating;
proxy_cache_key “$host$uri$is_args$args”;
proxy_cache default;

proxy_ignore_headers “Cache-Control”;
proxy_hide_header “Cache-Control”;

proxy_ignore_headers “Expires”;
proxy_hide_header “Expires”;

proxy_hide_header “Set-Cookie”;
proxy_ignore_headers “Set-Cookie”;

add_header Cache-Control max-age=60;

proxy_cache_valid 200 3m;
proxy_cache_valid any 0m;
proxy_temp_path /dev/shm/cache/tmp;

proxy_pass http://serverIP/$1$is_args$args;

3) PURGE设置:

location ~* ^/purge/(.*\.php)$ {
access_log logs/purge_app_access.log sohu;

allow 10.10.0.0/16;
deny all;
set $purge_key “$host/$1$is_args$args”;
proxy_cache_purge default $purge_key;

}

3.需要注意的地方:

1) 影响动态应用能否cache的有几个header:一般是”X-Accel-Redirect”, “X-Accel-Expires”, “Expires” or “Cache-Control” ,跟某些文档提到的cookie是没有关系的,我这里根据自己的应用ignore了 “Expires” 和”Cache-Control” 的header
2) 需要注意,php使用cookie(session也是cookie header实现的一种)来识别用户,如果是私密应用,需要把cookie加入cachekey里边,开放式应用则不必如此
3)设置完毕后可以在访问路径的前边加上/cache/实现php内容的缓存,再加上/purge/就能清除其缓存
4) 需要特别说明,我这边的版本是0.7系列,从测试看1.x系列是会forward cookie的,所以需要抹掉:

proxy_hide_header Set-Cookie;
proxy_ignore_headers Set-Cookie;

2022.07补充

By default, NGINX respects other directives in the Cache-Control header: it does not cache responses when the header includes the PrivateNo-Cache, or No-Store directive. It also doesn’t cache responses with the Set-Cookie header. Further, it only caches responses to GET and HEAD requests. You can override these defaults as described in the answers below.

发表回复