设置Nginx FastCGI缓存以减少WordPress服务器响应时间

本教程将向您展示如何设置Nginx FastCGI缓存以减少WordPress网站的服务器响应时间。

什么是Nginx FastCGI缓存?

如果您按照之前的教程在各种Linux发行版上安装LEMP堆栈,则Nginx被配置为将PHP请求传递给PHP-FPM,因为Nginx本身无法处理PHP代码。 让我解释一下LEMP Stack网站的工作方式。

  1. Web浏览器将HTTP请求发送到Nginx,后者尝试从文件系统中获取页面。
  2. 如果Nginx在页面中找到PHP代码,它将请求传递给PHP-FPM以处理PHP代码。
  3. 如有必要,PHP-FPM将查询MySQL / MariaDB数据库以获取所需信息。
  4. PHP-FPM生成一个静态HTML页面,然后将其返回给Nginx。
  5. 最后,Nginx将静态HTML页面发送到Web浏览器。

Nginx在提供静态HTML页面方面非常快。 但是,尽管最新版本的PHP7比以前的版本要快得多,但众所周知PHP的运行速度很慢。 MySQL / MariaDB数据库是LEMP堆栈网站的另一个性能瓶颈。

Nginx无需将动态页面请求传递给PHP-FPM并让其每次生成HTML页面,而是可以缓存生成的HTML页面,以便下次将缓存的页面发送到Web浏览器时,消除了PHP和数据库请求。

  • 这可以大大缩短服务器响应时间,并减少PHP-FPM和数据库服务器上的负载。
  • 当上游PHP-FPM或数据库服务器关闭时,它还允许Nginx从缓存中提供网页(当Linux服务器内存不足时,MySQL / MariaDB通常是第一个被杀死的进程)。

FastCGI是Nginx和PHP-FPM之间的协议,因此该缓存称为FastCGI缓存。

如何配置Nginx FastCGI缓存

步骤1:编辑Nginx主配置文件

编辑Nginx主配置文件。

sudo nano /etc/nginx/nginx.conf

在里面 http 在上下文中,添加以下两行:

fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=phpcache:100m max_size=10g inactive=60m use_temp_path=off;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

第一条指令 fastcgi_cache_path 创建一个FastCGI缓存。 该指令仅在 http Nginx配置文件的上下文。

  • 第一个参数指定文件系统中的缓存位置(/etc/nginx/cache/)。
  • 等级 参数在下面建立两级目录层次结构 /etc/nginx/cache/。 在单个目录中包含大量文件可能会减慢文件访问速度,因此对于大多数部署,我建议使用两级目录。 如果 等级 参数不包括在内,Nginx将所有文件放在同一目录中。 第一个目录的名称中使用一个字符。 子目录的名称中使用两个字符。
  • 第3个参数指定共享内存区域名称(phpcache)的名称及其大小(100M)。 该存储区用于存储缓存键和元数据(例如使用时间)。 将密钥的副本存储在内存中使Nginx能够快速确定请求是HIT还是MISS,而不必进入磁盘,从而大大加快了检查速度。 1MB区域可以存储大约8,000个密钥的数据,因此100MB区域可以存储大约800,000个密钥的数据。
  • max_size 设置缓存大小的上限(在此示例中为10GB)。 如果未指定,则缓存可以使用所有剩余的磁盘空间。 一旦缓存达到其最大大小,Nginx缓存管理器将从缓存中删除最近最少使用的文件。
  • 在闲置时间段(60分钟)内未访问的数据将由高速缓存管理器从高速缓存中清除,无论该数据是否已过期。 默认值为10分钟。 您还可以使用类似的值 12h (12小时)和 7d (7天)。
  • Nginx首先将目的地为高速缓存的文件写入临时存储区(/var/lib/nginx/fastcgi/)。 use_temp_path=off 告诉Nginx将它们直接写入最终的缓存目录,以避免在文件系统之间不必要地复制数据。

第二条指令 fastcgi_cache_key 定义缓存查找的键。 Nginx将在缓存键上应用MD5sum哈希函数,并将哈希结果用作缓存文件的名称。 在输入两个指令后 http 上下文,保存并关闭文件。

步骤2:编辑Nginx服务器块

然后打开服务器块配置文件。

sudo nano /etc/nginx/conf.d/your-domain.conf

向下滚动到 位置〜 .php $ 部分。 在本节中添加以下行。

fastcgi_cache phpcache;
fastcgi_cache_valid 200 301 302 60m;
fastcgi_cache_use_stale error timeout updating invalid_header http_500 http_503;
fastcgi_cache_min_uses 1;
fastcgi_cache_lock on;
add_header X-FastCGI-Cache $upstream_cache_status;
  • fastcgi_cache 指令启用缓存,使用先前由以下人员创建的内存区域 fastcgi_cache_path 指示。
  • fastcgi_cache_valid 根据HTTP状态代码设置缓存时间。 在上面的示例中,状态码为200、301、302的响应将被缓存60分钟。 您也可以使用以下时间段 12h (12小时)和 7d (7天)。
  • 当Nginx无法从上游PHP-FPM服务器获取更新的内容时,它可以从其缓存中传递过时的内容。 例如,当MySQL / MariaDB数据库服务器关闭时。 Nginx可以将文件的陈旧版本从其缓存中传递出来,而不是将错误传递给客户端。 为启用此功能,我们添加了 fastcgi_cache_use_stale 目录。
  • fastcgi_cache_min_uses 设置客户端在Nginx缓存项目之前必须请求该项目的次数。 预设值为1。
  • fastcgi_cache_lock 启用后,如果多个客户端请求的文件不是高速缓存中的当前文件,则仅允许这些请求中的第一个进入上游PHP-FPM服务器。 其余请求等待该请求得到满足,然后将文件从缓存中拉出。 不带 fastcgi_cache_lock 启用后,所有请求都直接发送到上游PHP-FPM服务器。
  • 第三行在HTTP响应中添加X-FastCGI-Cache标头。 它可用于验证是否已从FastCGI缓存中满足请求。

现在保存并关闭服务器块配置文件。 然后测试您的Nginx配置。

sudo nginx -t

如果测试成功,请重新加载Nginx。

sudo service nginx reload

要么

sudo systemctl reload nginx

现在,缓存管理器启动,缓存目录(/etc/nginx/cache)将自动创建。

测试Nginx FastCGI缓存

重新加载您网站的主页几次。 然后使用curl获取http响应标头。

curl -I http://www.your-domain.com

像这样:

看一看X-FastCGI-Cache标头。 HIT 表示响应是从缓存提供的。

不应缓存的内容

登录会话,用户cookie,POST请求,查询字符串,WordPress后端,站点地图,提要和评论作者均不应缓存。 要禁用上述项目的缓存,请编辑服务器块配置文件。 将以下代码粘贴到 server 上下文,在 location ~ .php$ 线。

set $skip_cache 0;

# POST requests and urls with a query string should always go to PHP
if ($request_method = POST) {
    set $skip_cache 1;
}
if ($query_string != "") {
    set $skip_cache 1;
}

# Don't cache uris containing the following segments
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|^/feed/*|/tag/.*/feed/*|index.php|/.*sitemap.*.(xml|xsl)") {
    set $skip_cache 1;
}

# Don't use the cache for logged in users or recent commenters
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
    set $skip_cache 1;
}

有时我想测试上游(PHP-FPM和MariaDB)的响应时间,因此我还添加了以下几行以告知Nginx绕过我的IP地址的FastCGI缓存。

if ($remote_addr ~* "12.34.56.78|12.34.56.79") {
     set $skip_cache 1;
}

代字号(~)告诉Nginx,其后是一个正则表达式(regex)。 星号 * 使正则表达式不区分大小写。 竖线 | 用于多个值的交替。 如果$ remote_addr变量的值与正则表达式中的任何IP地址匹配,则将$ skip_cache的值设置为1。

请注意,如果您在WordPress网站中使用Google XML网站地图插件,那么您可能会在Nginx配置中看到以下重写规则。

rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?.xml$ "/index.php?xml_sitemap=params=$2" last;
rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?.xml.gz$ "/index.php?xml_sitemap=params=$2;zip=true" last;
rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?.html$ "/index.php?xml_sitemap=params=$2;html=true" last;
rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?.html.gz$ "/index.php?xml_sitemap=params=$2;html=true;zip=true" last;

这些重写规则应放在跳过缓存规则之下。 如果重写规则高于跳过缓存规则,则将始终缓存您的站点地图。 同样,如果您使用Yoast SEO插件生成站点地图,则还需要将Yoast重写规则移到跳过缓存规则下方。

现在在 location ~ .php$ 部分,粘贴以下指令。

fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;

第一个指令告诉Nginx将请求发送到上游PHP-FPM服务器,而不是尝试在缓存中查找文件。 第二个指令告诉Nginx不要缓存响应。 保存文件并重新加载Nginx。

sudo systemctl reload nginx

要么

sudo service nginx reload

如何使用WordPress自动清除缓存

首先,您需要在WordPress网站上安装并激活Nginx Helper插件。 然后去WordPress Settings -> Nginx helper 然后在 Enable Purge 框。 对于大多数WordPress博客而言,默认清除条件很好。 您还可以启用日志记录以检查清除是否正常工作。

nginx fastcgi缓存清除wordpress

点击 保存所有更改 按钮。

然后,您需要安装 http-cache-purge Linux服务器上的模块。 运行以下命令将其安装在Ubuntu 18.04及更高版本上。 在安装过程中,将在下面放置一个配置文件 /etc/nginx/modules-enabled/ 目录以启用此模块。

sudo apt install libnginx-mod-http-cache-purge

您也可以安装 nginx-extras 软件包以启用此模块,但此软件包还启用许多其他模块。 为了使Nginx尽可能轻巧,我不安装 nginx-extras 包。

接下来,打开您的Nginx服务器块配置文件。 将以下行添加到 server {...} 上下文。

location ~ /purge(/.*) {
      fastcgi_cache_purge phpcache "$scheme$request_method$host$1";
}

保存并关闭文件。 然后测试Nginx配置。

sudo nginx -t

如果测试成功,请重新加载Nginx。

sudo systemctl reload nginx

现在,您可以修改WordPress中的一篇文章,以查看是否会自动清除缓存。

如何预加载缓存

您可以在访问者进入您的网站之前生成页面缓存。 Nginx FastCGI缓存不提供预加载缓存的方法。 但是,您可以使用 wget 另一个盒子上的工具下载整个网站,这将迫使Nginx为每个网页生成一个缓存。

wget -m -p -E -k https://www.yourdomain.com/

确保另一个盒子的IP地址不在旁路列表中。 Wget将创建一个 www.yourdomain.com 目录并在其中存储内容。

有时我必须清除Nginx FastCGI缓存并让其重新生成,但是我不想手动键入 wget 每次命令。 因此,我创建了一个Cronjob来自动执行此任务。

crontab -e

将以下行放在crontab文件的末尾。 /tmp/ramdisk/ 是我创建的用于存储文件的RAM磁盘,因此内容将被写入RAM,并且我的SSD不会很快用完。

@hourly rm /tmp/ramdisk/www.yourdomain.com/ -r && wget -m -p -E -k -P /tmp/ramdisk/ https://www.yourdomain.com/

保存并关闭文件。 (我知道这不是解决问题的好方法,但可以完成工作。)

下一步

我希望本文能帮助您使用WordPress设置Nginx FastCGI缓存。 您可能还想使用Nginx Amplify监视LEMP堆栈性能。 与往常一样,如果您发现这篇文章很有用,请订阅我们的免费新闻通讯以获取更多提示和技巧。 保重🙂

Sidebar