用Nginx fastcgi_cache缓存为你的PHP网站加速
Nginx + PHP7-FPM + FastCGI (+ProcessWire) = Fast!
用PW做了套前端JS/CSS文件分离的管理系统的后续,该项目今天正式部署,由于对Nginx的知识缺乏导致之前有一些错误的认知:
本来以为用ProcessWire输出成"text/css
"和"application/javascript
"这类前端静态文件会被Nginx自动缓存,殊不知Nginx默认缓存的物理文件,而由PHP输出成的文件需要特别用fastcgi_cache
来处理。
静态文件的处理方法,在《Nginx如何设置HTML、JS、CSS和图片等文件的缓存时间?》一文记录过:
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|eot|otf|woff|woff2|ttc|ttf)$ { add_header Access-Control-Allow-Origin *; expires 1y; log_not_found off; access_log off; try_files $uri $uri/ /index.php?it=$uri&$args; }
注意:这里缓存的是物理文件。
用Nginx缓存PHP文件的方法
缓存位置的基础配置
找到站点配置.conf
文件,在server{}
配置上面加上:
fastcgi_cache_path /path/to/nginx/cache levels=1:2 keys_zone=microcache:10m max_size=1024m inactive=1h; add_header X-Cache $upstream_cache_status;
需要修改的参数:/path/to/nginx/cache
是缓存文件的存放目录;keys_zone=microcache
就是当前的应用名称,这里的microcache
后面还会用到。
注意:$upstream_cache_status
参数的几个值,后面测试查看X-Cache
的状态都依赖于该参数:
MISS
未命中,请求被传送到后端HIT
缓存命中EXPIRED
缓存已经过期请求被传送到后端UPDATING
正在更新缓存,将使用旧的应答STALE
后端将得到过期的应答
缓存触发条件的设定
在server{}
中加入以下配置:
#缓存全部 set $no_cache 0; #仅限于GET请求,其它请求禁止缓存 if ($request_method != GET){ set $no_cache 1; } #URL中带有Query参数的时候禁止缓存,应为ProcessWire由index.php文件作为入口,所以我这里用不到 #if ($query_string != ""){ # set $no_cache 1; #} #URL中出现这些目录的时候禁止缓存 if ($request_uri ~* "/(admin|backendpath)"){ set $no_cache 1; } #如果cookie中有PHPSESSID的变量的时候禁止缓存 if ($http_cookie ~* "PHPSESSID"){ set $no_cache 1; } #如果cookie中有wire_challenge的时候不要缓存,该参数在用户登录后出现 if ($http_cookie ~* "wire_challenge"){ set $no_cache 1; }
让缓存工作
在location ~ \.php$ {}
中加入以下配置:
#Set cache fastcgi_cache_key $scheme$host$request_uri$request_method; fastcgi_cache microcache; fastcgi_cache_valid 200 301 302 30s; fastcgi_cache_use_stale updating error timeout invalid_header http_500; fastcgi_pass_header Set-Cookie; fastcgi_pass_header Cookie; fastcgi_ignore_headers Cache-Control Expires Set-Cookie; fastcgi_cache_bypass $no_cache; fastcgi_no_cache $no_cache; #Set cache end
缓存的测试方法
curl -X GET -I http://yourwebsite.com
HTTP/1.1 200 OK Server: nginx/1.10.1 Date: Mon, 27 Feb 2017 14:05:06 GMT Content-Type: text/html; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Set-Cookie: wire=4150jee3917k8e2dv4ioka1sq6; path=/; HttpOnly Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache X-Powered-By: ProcessWire CMS X-Cache: HIT
注意X-Cach
e参数,如果是HIT
就是已经缓存了的,因为缓存机制是访问后被缓存,所以如果你是第一次访问可能这里的值是MISS
.
同样你还可以通过Chrome F12开发者模式查看页面或文件的Headers信息查看X-Cache状态,下面是访问触发禁止缓存的页面或用户登录后的状态:
Response Headers
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Connection:keep-alive Content-Type:application/javascript Date:Mon, 27 Feb 2017 14:08:25 GMT Expires:Thu, 19 Nov 1981 08:52:00 GMT Pragma:no-cache Server:nginx/1.10.1 Transfer-Encoding:chunked X-Cache:BYPASS X-Powered-By:ProcessWire CMS
注意:这里的X-Cache:BYPASS
,即为非缓存内容.