如何在您的VPS上使用Nginx设置FastCGI缓存
序幕
Nginx 包含一个 FastCGI 模块,该模块具有用于缓存从 PHP 后端提供的动态内容的指令。 设置此设置消除了对额外页面缓存解决方案的需要,例如反向代理(想想 Varnish)或特定于应用程序的插件。 也可以根据请求方法、URL、cookie 或任何其他服务器变量将内容从缓存中排除。
在您的 VPS 上启用 FastCGI 缓存
本文假设您已经在您的 Droplet 上使用 PHP 设置和配置了 Nginx。 编辑必须启用缓存的 Virtual Host 配置文件。
nano /etc/nginx/sites-enabled/vhost
将以下行添加到 server { } 指令之外的文件顶部:
fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=MYAPP:100m inactive=60m; fastcgi_cache_key "$scheme$request_method$host$request_uri";
“fastcgi_cache_path”指令指定缓存的位置(/etc/nginx/cache)、大小(100m)、内存区域名称(MYAPP)、子目录级别和inactive`计时器。
该位置可以是硬盘上的任何位置; 但是,大小必须小于 Droplet 的 RAM + Swap,否则您将收到“无法分配内存”的错误消息。 我们将查看清除部分中的“级别”选项——如果在“非活动”选项指定的特定时间(此处为 60 分钟)内未访问缓存,则 Nginx 将其删除。
“fastcgi_cache_key”指令指定缓存文件名将如何散列。 Nginx 根据该指令使用 MD5 对访问的文件进行加密。
接下来,将传递 PHP 请求的 location 指令移动到 php5-fpm。 在“location ~ .php$ { }”中添加以下行。
fastcgi_cache MYAPP; fastcgi_cache_valid 200 60m;
“fastcgi_cache”指令引用我们在“fastcgi_cache_path”指令中指定的内存区域名称,并将缓存存储在该区域中。
默认情况下,Nginx 将缓存对象存储由以下任何标头指定的持续时间:X-Accel-Expires/Expires/Cache-Control.
如果这些标头丢失,“fastcgi_cache_valid”指令用于指定默认缓存生命周期。 在我们上面输入的语句中,仅缓存状态代码为 200 的响应。 也可以指定其他响应代码。
做一个配置测试
service nginx configtest
如果一切正常,请重新加载 Nginx
service nginx reload
完整的 vhost 文件将如下所示:
fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=MYAPP:100m inactive=60m; fastcgi_cache_key "$scheme$request_method$host$request_uri"; server { listen 80; root /usr/share/nginx/html; index index.php index.html index.htm; server_name example.com; location / { try_files $uri $uri/ /index.html; } location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_cache MYAPP; fastcgi_cache_valid 200 60m; } }
接下来我们将做一个测试,看看缓存是否有效。
在您的 VPS 上测试 FastCGI 缓存
创建一个输出 UNIX 时间戳的 PHP 文件。
/usr/share/nginx/html/time.php
插入
<?php echo time(); ?>
使用 curl 或您的网络浏览器多次请求此文件。
root@droplet:~# curl http://localhost/time.php;echo 1382986152 root@droplet:~# curl http://localhost/time.php;echo 1382986152 root@droplet:~# curl http://localhost/time.php;echo 1382986152
如果缓存工作正常,您应该在所有请求上看到与缓存响应相同的时间戳。
执行缓存位置的 递归 列表以查找此请求的缓存。
root@droplet:~# ls -lR /etc/nginx/cache/ /etc/nginx/cache/: total 0 drwx------ 3 www-data www-data 60 Oct 28 18:53 e /etc/nginx/cache/e: total 0 drwx------ 2 www-data www-data 60 Oct 28 18:53 18 /etc/nginx/cache/e/18: total 4 -rw------- 1 www-data www-data 117 Oct 28 18:53 b777c8adab3ec92cd43756226caf618e
命名约定将在清除部分解释。
我们还可以让 Nginx 在响应中添加一个“X-Cache”标头,指示缓存是否丢失或命中。
在 server { } 指令上方添加以下内容:
add_header X-Cache $upstream_cache_status;
重新加载 Nginx 服务并使用 curl 执行详细请求以查看新标头。
root@droplet:~# curl -v http://localhost/time.php * About to connect() to localhost port 80 (#0) * Trying 127.0.0.1... * connected * Connected to localhost (127.0.0.1) port 80 (#0) > GET /time.php HTTP/1.1 > User-Agent: curl/7.26.0 > Host: localhost > Accept: */* > * HTTP 1.1 or later with persistent connection, pipelining supported < HTTP/1.1 200 OK < Server: nginx < Date: Tue, 29 Oct 2013 11:24:04 GMT < Content-Type: text/html < Transfer-Encoding: chunked < Connection: keep-alive < X-Cache: HIT < * Connection #0 to host localhost left intact 1383045828* Closing connection #0
设置缓存例外
不应缓存某些动态内容,例如需要身份验证的页面。 可以根据“request_uri”、“request_method”和“http_cookie”等服务器变量将此类内容排除在缓存之外。
这是必须在 server{ } 上下文中使用的示例配置。
#Cache everything by default set $no_cache 0; #Don't cache POST requests if ($request_method = POST) { set $no_cache 1; } #Don't cache if the URL contains a query string if ($query_string != "") { set $no_cache 1; } #Don't cache the following URLs if ($request_uri ~* "/(administrator/|login.php)") { set $no_cache 1; } #Don't cache if there is a cookie called PHPSESSID if ($http_cookie = "PHPSESSID") { set $no_cache 1; }
要将“$no_cache”变量应用于适当的指令,请将以下行放在 location ~ .php$ { }
fastcgi_cache_bypass $no_cache; fastcgi_no_cache $no_cache;
“fasctcgi_cache_bypass”指令忽略与我们之前设置的条件相关的请求的现有缓存。 如果满足指定条件,“fastcgi_no_cache”指令根本不会缓存请求。
清除缓存
缓存的命名约定基于我们为“fastcgi_cache_key”指令设置的变量。
fastcgi_cache_key "$scheme$request_method$host$request_uri";
根据这些变量,当我们请求“http://localhost/time.php”时,实际值如下:
fastcgi_cache_key "httpGETlocalhost/time.php";
将此字符串通过 MD5 散列 将输出以下字符串:
b777c8adab3ec92cd43756226caf618e
这将形成缓存的文件名,就像我们输入“levels=1:2”的子目录一样。 因此,目录的第一级将命名为该 MD5 字符串最后一个字符 e 的 1 字符; 第二级将具有第一级之后的最后 2 个字符,即 18。 因此,这个缓存的整个目录结构如下:
/etc/nginx/cache/e/18/b777c8adab3ec92cd43756226caf618e
基于这种缓存命名格式,您可以使用您喜欢的语言开发一个清除脚本。 对于本教程,我将提供一个简单的 PHP 脚本来清除 __POST__ed URL 的缓存。
/usr/share/nginx/html/purge.php
插入
<?php $cache_path = '/etc/nginx/cache/'; $url = parse_url($_POST['url']); if(!$url) { echo 'Invalid URL entered'; die(); } $scheme = $url['scheme']; $host = $url['host']; $requesturi = $url['path']; $hash = md5($scheme.'GET'.$host.$requesturi); var_dump(unlink($cache_path . substr($hash, -1) . '/' . substr($hash,-3,2) . '/' . $hash)); ?>
使用要清除的 URL 向此文件发送 POST 请求。
curl -d 'url=http://www.example.com/time.php' http://localhost/purge.php
该脚本将根据缓存是否被清除而输出 true 或 false。 确保从缓存中排除此脚本并限制访问。
提交者:http: [[“%3Ca|//jesin.tk/]] [[“%3C/a|”>杰辛A]]