预告片
Nginx 包括一个 FastCGI 模块,该模块具有从 PHP 后端提供的动态内容缓存指令. 设置此设置消除了需要额外的页面缓存解决方案,如反向代理(想想 Varnish)或应用程序特定的插件。
在您的 VPS 上启用 FastCGI 缓存
本文假定您已在您的 dropplet 上设置并配置了 Nginx with PHP。
1nano /etc/nginx/sites-enabled/vhost
在 server { } 指令之外的文件顶部添加以下行:
1fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=MYAPP:100m inactive=60m;
2fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_path
指令规定了缓存(/etc/nginx/cache)的位置,其大小(100m),内存区域名称(MYAPP),子目录级别和 _inactive` 计时器。
位置可能在硬盘上的任何地方;然而,大小必须小于您的滴子的RAM + Swap否则你会收到一个错误,上面写着不能分配内存
。
fastcgi_cache_key
指令规定了缓存文件名将如何进行缓存。
接下来,移动将 PHP 请求传递到 php5-fpm 的位置指令。
1fastcgi_cache MYAPP;
2fastcgi_cache_valid 200 60m;
fastcgi_cache
指令是指我们在fastcgi_cache_path
指令中指定的内存区域名称,并在该区域存储缓存。
默认情况下, Nginx 会将缓存对象存储在以下任何标题中所指定的时间: **X-Accel-Expires/Expires/Cache-Control。
fastcgi_cache_valid
指令用于指定默认的缓存寿命,如果这些标题不存在。在我们上面输入的声明中,只有具有状态代码200的响应被缓存。
** 进行配置测试**
1service nginx configtest
重新加载 Nginx 如果一切正常
1service nginx reload
完整的vhost文件将看起来像这样:
1fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=MYAPP:100m inactive=60m;
2fastcgi_cache_key "$scheme$request_method$host$request_uri";
3
4server {
5 listen 80;
6
7 root /usr/share/nginx/html;
8 index index.php index.html index.htm;
9
10 server_name example.com;
11
12 location / {
13 try_files $uri $uri/ /index.html;
14 }
15
16 location ~ \.php$ {
17 try_files $uri =404;
18 fastcgi_pass unix:/var/run/php5-fpm.sock;
19 fastcgi_index index.php;
20 include fastcgi_params;
21 fastcgi_cache MYAPP;
22 fastcgi_cache_valid 200 60m;
23 }
24}
接下来我们将进行测试,看看缓存是否有效。
在您的 VPS 上测试 FastCGI 缓存
创建一个 PHP 文件,输出一个 UNIX 时间戳。
1/usr/share/nginx/html/time.php
插入
1<?php
2echo time();
3?>
请使用 curl或您的 Web 浏览器多次请求此文件。
1root@droplet:~# curl http://localhost/time.php;echo
21382986152
3root@droplet:~# curl http://localhost/time.php;echo
41382986152
5root@droplet:~# curl http://localhost/time.php;echo
61382986152
如果缓存正常工作,您应该在所有请求上看到相同的时刻标记,因为答案已缓存。
对缓存位置进行 recursive 列表,以查找此请求的缓存。
1root@droplet:~# ls -lR /etc/nginx/cache/
2/etc/nginx/cache/:
3total 0
4drwx------ 3 www-data www-data 60 Oct 28 18:53 e
5
6/etc/nginx/cache/e:
7total 0
8drwx------ 2 www-data www-data 60 Oct 28 18:53 18
9
10/etc/nginx/cache/e/18:
11total 4
12-rw------- 1 www-data www-data 117 Oct 28 18:53 b777c8adab3ec92cd43756226caf618e
命名公约将在净化部分中解释。
我们还可以让 Nginx 将X-Cache
标题添加到响应中,表示是否错过了缓存或被击中。
在服务器 { } 指令上添加以下内容:
1add_header X-Cache $upstream_cache_status;
重新加载 Nginx 服务,并使用 curl 进行单词请求,以查看新标题。
1root@droplet:~# curl -v http://localhost/time.php
2* About to connect() to localhost port 80 (#0)
3* Trying 127.0.0.1...
4* connected
5* Connected to localhost (127.0.0.1) port 80 (#0)
6> GET /time.php HTTP/1.1
7> User-Agent: curl/7.26.0
8> Host: localhost
9> Accept: */*
10>
11* HTTP 1.1 or later with persistent connection, pipelining supported
12< HTTP/1.1 200 OK
13< Server: nginx
14< Date: Tue, 29 Oct 2013 11:24:04 GMT
15< Content-Type: text/html
16< Transfer-Encoding: chunked
17< Connection: keep-alive
18< X-Cache: HIT
19<
20* Connection #0 to host localhost left intact
211383045828* Closing connection #0
设置缓存例外
某些动态内容,如需要身份验证的页面,不应缓存,此类内容可以根据服务器变量,如request_uri
,request_method
和http_cookie
,排除缓存。
以下是必须在 server{ } 环境中使用的示例配置。
1#Cache everything by default
2set $no_cache 0;
3
4#Don't cache POST requests
5if ($request_method = POST)
6{
7 set $no_cache 1;
8}
9
10#Don't cache if the URL contains a query string
11if ($query_string != "")
12{
13 set $no_cache 1;
14}
15
16#Don't cache the following URLs
17if ($request_uri ~* "/(administrator/|login.php)")
18{
19 set $no_cache 1;
20}
21
22#Don't cache if there is a cookie called PHPSESSID
23if ($http_cookie = "PHPSESSID")
24{
25 set $no_cache 1;
26}
若要将$no_cache
变量应用于相应的指令,请将下列行放入 location ~.php$ { }
1fastcgi_cache_bypass $no_cache;
2fastcgi_no_cache $no_cache;
fasctcgi_cache_bypass
指令忽略了与我们之前设定的条件相关的请求的现有缓存。
清除隐藏
缓存命名公约基于我们为fastcgi_cache_key
指令设置的变量。
1fastcgi_cache_key "$scheme$request_method$host$request_uri";
根据这些变量,当我们要求http://localhost/time.php
时,以下将是实际值:
1fastcgi_cache_key "httpGETlocalhost/time.php";
通过 MD5 哈希传输此字符串将产生以下字符串:
1b777c8adab3ec92cd43756226caf618e
这将形成缓存的文件名作为我们输入的子目录级别=1:2.
因此,目录的第一个级别将被命名为 1字符从这个MD5字符串的最后一个,这是 e;第二个级别将有最后一个 2字符之后的第一个级别即 18。
1/etc/nginx/cache/e/18/b777c8adab3ec92cd43756226caf618e
基于此缓存命名格式,您可以在您最喜欢的语言中开发一个清除脚本. 对于本教程,我将提供一个简单的PHP脚本,该脚本清除 __POST__ed URL的缓存。
「/usr/share/nginx/html/purge.php」
- 插入 *
1<?php
2$cache_path = '/etc/nginx/cache/';
3$url = parse_url($_POST['url']);
4if(!$url)
5{
6 echo 'Invalid URL entered';
7 die();
8}
9$scheme = $url['scheme'];
10$host = $url['host'];
11$requesturi = $url['path'];
12$hash = md5($scheme.'GET'.$host.$requesturi);
13var_dump(unlink($cache_path . substr($hash, -1) . '/' . substr($hash,-3,2) . '/' . $hash));
14?>
向此文件发送一个 POST 请求,其中包含要清除的 URL。
1curl -d 'url=http://www.example.com/time.php' http://localhost/purge.php
脚本将输出 true 或 false 取决于是否已清除缓存,请确保将此脚本排除在缓存中,并限制访问。
發表 由: Jesin A