跳转至主要内容

晴雨技术笔记

Nginx 图标。

Nginx 配置 FastCGI 缓存

杏川铭心 杏川铭心
最后编辑于 2025年4月5日

众所周知,OpenLiteSpeed 能够实现高性能的主要原因是因为 OpenLiteSpeed 里面带了一个服务器缓存系统 LSCache。而事实上,Nginx 里面也有一个类似的系统,叫做 FastCGI 缓存 ,看名字就知道是针对 FastCGI 的一个缓存系统。(以防你一直用现成的面板不知道 FastCGI 是啥,这个东西是一种网关接口,实现了 Web 服务器与 CGI 程序的沟通。比如说如果我们用 Nginx 来运行 WordPress,那么 Nginx 就是通过 FastCGI 方式来运行 PHP 的。)

相较于 Varnish,由于 FastCGI 缓存内嵌在 Nginx 里面,配置起来较容易。当然,功能上肯定是比不过前者的,但是对于比较简单的网站来说,肯定是够用了。

配置 FastCGI 缓存

首先,在你要开启 FastCGI 缓存的站点配置文件的最顶上(即没有被包在任何一个 server 块下),添加下列内容:

fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=<缓存名称>:200m max_size=10g inactive=2h use_temp_path=off;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

解释一下每个配置的含义:

  • fastcgi_cache_path:定义了缓存下来的文件存到什么地方。后面的是额外参数,定义了缓存行为,例如文件的大小,过期时间等等;根据实际情况修改。注意 keys_zone 后面的缓存名称要改成自己能记得住的东西,一会儿要用。
  • fastcgi_cache_key:定义了缓存的键名,如果 URL 满足键名那么就会从缓存返回页面,而不是让 PHP 再动态生成一份。这里的配置会为每个不同的页面,包括不同的访问参数都存一份缓存,对于绝大多数网站来讲都是 OK 的。
  • fastcgi_ignore_headers:定义在缓存时要忽略哪些 HTTP 标头。

接下来,以 PHP 为例,在 location ~ \.php$ 块下面添加以下内容(注意要把配置添加到已有配置的下方):

fastcgi_cache <缓存名称>;
fastcgi_cache_valid 200 301 302 2h;
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:告诉 Nginx 启用 FastCGI 缓存。缓存名称就是上一步 keys_zone 后面的那个名称,一定要一致才行。
  • fastcgi_cache_valid:告诉 Nginx 针对不同的 HTTP 状态码要缓存多长时间。根据实际情况修改。
  • fastcgi_cache_use_stale:某些 HTTP 状态,特别是发生错误的时候,返回的内容是不怎么变的。这个选项告诉 Nginx 在哪些情况下,就算缓存过期也返回缓存内容。
  • fastcgi_cache_min_uses:页面在被缓存前必须要被访问多少次。设置的高一点有助于减少缓存存储占用,因为这样不经常被访问的页面就不会被存储。这里设置为 1 代表始终缓存。
  • fastcgi_cache_lock:指示 Nginx 如何处理并发请求。
  • 最后一个 add_header 只是用来昭告天下,老子启用了 FastCGI 缓存!主要是开发环境下查看缓存状况用的;生产环境可以不加,看心情。

至此,FastCGI 缓存就已经成功启用了。

微调 FastCGI 缓存

当然,以上这些只是默认的配置。我们当然不希望在网站后台辛辛苦苦写完一篇文章,发布之后却由于后台被缓存了,而在后台里面找不到刚写的文章,使我们心肺骤停……(当然,文章写完了肯定是进了数据库的,但是你在后台就是看不到,你说气不气人?)

所以我们要微调一下我们的缓存,主要是针对某些页面,绕过 FastCGI 缓存。

以下的配置以 WordPress 做例子,如果你用的是别的什么 CMS,请根据实际情况配置。

首先,在刚刚的 location ~ \.php$ 块下面,添加这两行配置:

fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;

这就是告诉 Nginx,在 $skip_cache 为真的情况下,绕过缓存。

当然,这并不是一个 Nginx 自带的变量,所以我们在 server 块里面要加一句话:

set $skip_cache 0;

这就定义了 $skip_cache 这个变量。

接下来就需要手动针对每一个需要绕过缓存的情况,把 $skip_cache 设置成 1。

以 WordPress 为例:

if ($request_method = POST) {
  set $skip_cache 1; 
} 
if ($query_string != "") {
  set $skip_cache 1; 
}  
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|^/feed/*|/tag/.*/feed/*|index.php|/.*sitemap.*\.(xml|xsl)") {
  set $skip_cache 1; }  
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
  set $skip_cache 1; 
}

上面的 $request_method$query_string 等都是 Nginx 自带的变量,都是可以用的。~* 是正则表达式的运算符,指示要把这个值和后面的正则做匹配。

完整的列表,在 Nginx 文档上面有。正则表达式,可以去菜鸟教程上面学。

其他 CMS 可以参考上面的写法,把对应的路径换掉就行。

至此 FastCGI 缓存被我们调教的就差不多了。

(遗憾的是,我那台装了 Nginx 的服务器被我拿来跑 Mastodon 了,所以暂时没办法给性能对比。等有机会一定补上!)

小结

Nginx 的 FastCGI 缓存是个非常强大的系统,而且配置简单,不像 Varnish 需要很抽象地 Nginx 套 Varnish 再套 Nginx。

当然,如果你觉得这依然很烦的话,那么就老老实实用页面缓存插件之类的东西吧。当然,你也可以考虑 OpenLiteSpeed,对于流行的 CMS,LiteSpeed 官方都有插件可以做到一键配置。

杏川铭心
杏川铭心

名字越改越尬,但是网站一点没动🤪 曾用名Frank419(现在也是我在很多地方的用户名),网站站长。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注