Nginx学习:FastCGI模块(二)缓存配置通过上篇文章的学习,普通的 PHP 与 Nginx 的连接就已经没啥大问题了。一般的网站直接那套配置就够了,这也是 Nginx 非常友好的一面。很多在默认的配置文件中注释掉的内容,只要打开就是可以直接使用的。不过,FastCGI 可不是一个小模块,还有很多的配置指令,要想深入,要想调优,这些指令还是多少要了解一下的。 今天学习的内容基本上也都是可以设置在 http、server、location 中的,有特殊情况的我会单独说。 FastCGI缓存配置是的,你没看错,FastCGI 也有缓存系统,但它走的是文件缓存。通过之前的学习,我们知道 Nginx 对静态文件的优化还是相当强悍的,因此,文件缓存的效率并不低。 对于动态网站来说,如果走 UnixSocket ,其实网络开销不大,而且即使是走端口请求的 FastCGI ,通常也是本地部署,对于动态语言来说不会有太大的性能影响。当然,如果你使用的是 Laravel 这种重型框架,即使啥都不做,也是有一些性能损耗的。如果再加上数据库读写或者其它 IO 操作的话,性能还会进一步下降。通常来说我们会怎么做呢?上 Redis 做缓存。是的,这没问题,不过 Nginx 的 FastCGI 缓存也值得一试,起码不用再装第三方组件了。 我们先来看一套配置。 首先,需要在 http 模块下定义缓存路径。
先不用管参数是啥意思,现在你只要知道第一个参数是指定缓存文件存放的路径就好了。这个路径可以是相对也可以是绝对路径,现在我们配的是相对路径,默认就会是程序运行目录下新建一个 cache 目录。我这里就是 /usr/local/nginx/cache 。 然后进行缓存相关的配置。
上半部分没什么新鲜的,不过有一点,我们使用了 alias ,并且将 SCRIPT_FILENAME 设置为 然后加了三个 fastcgi_cache 相关的配置,暂时也不用管它,我们后面会一个一个地介绍,先看效果。 现在重载配置,并且访问 /fastcgi2/1.php?c=1 。结果正常,不急,先看下目录情况。
目录生成了,还有一个缓存文件也出现了。接着,查看一下文件内容。
上面一堆乱码,下面有个 Key 信息,然后是响应头信息,最后是正常返回的响应体内容。没错,就是我们所请求的页面的内容。 接下来,尝试修改 /fastcgi1/1.php 文件,然后再次请求,你会发现返回的结果不会有什么变动了,这就是缓存生效了。啥时候失效呢?等 5 分钟,也就是 fastcgi_cache_valid 配置项定义的时间,或者添加一个条件可以不走缓存,比如:
好了,一套简单的配置就完成了。不过 FastCGI 的缓存模块所拥有的配置指令远不止这些,我们接下来就一个一个详细地学习一下。 fastcgi_cache_path设置缓存的路径和其他参数,只能配置在 http 模块中。
缓存数据会存储在这个配置所指定的目录的文件中。缓存中的键名和文件名都是将 MD5 函数应用于代理 URL 的结果。 levels 参数定义缓存的层次级别:从 1 到 3,每个级别接受值 1 或 2。它和后面我们会学到的 第一个参数 path 就是路径,这个是需要我们指定的,这个配置项没有默认值,不配置 fastcgi_cache_path ,后面的 fastcgi_cache 就没法用,整个缓存功能也就无法使用。缓存中最终存储的完整文件名就像是我们上面看到的:
缓存的响应会首先写入临时文件,然后重命名该文件到指定的缓存目录。从 0.8.9 版本开始,临时文件和缓存可以放在不同的文件系统上。但是,请注意,在这种情况下,文件是跨两个文件系统复制的,而不是廉价的重命名操作。因此,建议对于任何给定位置,缓存和保存临时文件的目录都放在同一个文件系统上。根据 use_temp_path 参数 (1.7.10) 设置临时文件的目录。如果此参数被省略或设置为值 on,将使用由 fastcgi_temp_path 指令为给定位置设置的目录。如果该值设置为 off,则临时文件将直接放在缓存目录中。 这个指令我们将在下篇文章中学习到。 在 inactive 参数指定的时间内未访问的缓存数据将从缓存中删除,无论其新鲜度如何。默认情况下,非活动设置为 10 分钟。 特殊的“缓存管理器”进程监控由 max_size 参数设置的最大缓存大小,以及由 min_free (1.19.1) 参数设置的带缓存文件系统上的最小可用空间量来决定。当超出大小或没有足够的可用空间时,它会删除最近最少使用的数据。数据在 manager_files、manager_threshold 和 manager_sleep 参数 (1.11.5) 配置的迭代中被删除。在一次迭代中,最多删除 manager_files 个项目(默认为 100)。一次迭代的持续时间受 manager_threshold 参数的限制(默认为 200 毫秒)。在迭代之间,由 manager_sleep 参数配置的暂停(默认为 50 毫秒)。 启动后一分钟,特殊的“缓存加载器”进程被激活。它将有关存储在文件系统上的先前缓存数据的信息加载到缓存区域中。加载也是在迭代中完成的。在一次迭代中,最多加载 loader_files 个项目(默认情况下,100 个)。此外,一次迭代的持续时间受 loader_threshold 参数的限制(默认为 200 毫秒)。在迭代之间,由 loader_sleep 参数配置的暂停(默认为 50 毫秒)。 最后,其它的一些参数都是商业版的,没法用,也没法测,不讨论了。我们直接来看看多配置一个,然后将前面的例子换成新的路径配置。
重载配置后,看看新的缓存文件是不是生成到了 cache1 目录下了。这里有两个小问题需要注意下:
fastcgi_cache定义用于缓存的共享内存区域。
默认值是 off ,就是上面那个配置中 keys_zone 所定义的共享区域名称。同一个区域可以在多个地方使用。参数值可以包含变量 (1.7.9)。 off 参数禁用从先前配置级别继承的缓存。 最主要的作用就是表明当前的 server 或 location 使用哪个缓存路径配置,或者在 http 下定义一个全局的也可以。 fastcgi_cache_background_update允许启动后台子请求以更新过期的缓存项,同时将过时的缓存响应返回给客户端。
默认是关闭的,请注意,有必要在更新时允许使用陈旧的缓存响应。 fastcgi_cache_bypass定义不从缓存中获取响应的条件。
没有默认值,上面我们已经用过啦,其实它的意思是如果字符串参数中至少有一个值不为空且不等于“0”,则不会从缓存中获取响应:
这两行有点复杂了吧,其实是一样的意思,cookie 或请求参数中有 nocache 字段,或者请求头有 Pragma 或 Authoriaztion ,并且这些字段都不是空或0的时候,就不走缓存,前面我们演示过效果啦。它可以与 fastcgi_no_cache 指令一起使用。 fastcgi_cache_key定义一个用于缓存的键。
上面也已经用过了,并且还提到注意的地方了,一般来说,请求地址加 URI 就够了,不过最好再加上请求方法以及你可能需要的字段拼接成一个字符串就好了。 fastcgi_cache_lock启用后,一次只允许一个请求通过将请求传递给 FastCGI 服务器来填充根据 fastcgi_cache_key 指令标识的新缓存元素。
默认值 off ,其实就是缓存过期后,如果有多个相同缓存元素的请求同时到达,要怎么处理,就像更新 Redis 时如果多个请求到达会产生击穿问题一样,这里也是加锁来解决。相同缓存元素的其他请求要么等待响应出现在缓存中,要么等待释放该元素的缓存锁,直到由 fastcgi_cache_lock_timeout 指令设置的时间。 fastcgi_cache_lock_age如果传递给 FastCGI 服务器以填充新缓存元素的最后一个请求在指定时间内未完成,则可以将另一个请求传递给 FastCGI 服务器。
默认值 5s 。 fastcgi_cache_lock_timeout为 fastcgi_cache_lock 设置超时。
默认值 5s ,当时间到期时,请求将被传递到 FastCGI 服务器,但是,响应不会被缓存。在 1.7.8 之前,可以缓存响应。 fastcgi_cache_max_range_offset为字节范围请求设置字节偏移量。
如果范围超出偏移量,范围请求将被传递到 FastCGI 服务器,并且响应不会被缓存。 fastcgi_cache_methods如果此指令中列出了客户端请求方法,则响应将被缓存。
“GET”和“HEAD”方法总是添加到列表中,但建议明确指定它们。另请参见 fastcgi_no_cache 指令。 这个好测,可以先删了缓存文件,然后使用 POST 请求我们之前的测试文件,就会发现没有缓存文件产生。这时配置一条这个指令加上 POST ,缓存就正常生效了。 fastcgi_cache_min_uses设置将缓存响应的请求数。
默认值 1 ,意思就是,只要有一条请求来了,就缓存,一般不用改它。 fastcgi_cache_purge定义将请求视为缓存清除请求的条件。
商业版本提供的,咱们没有。 fastcgi_cache_revalidate使用带有“If-Modified-Since”和“If-None-Match”标头字段的条件请求启用过期缓存项的重新验证。
默认值 off ,就是通过请求头中的 HTTP 缓存相关字段来做为缓存的更新依据,需要我们 PHP 代码中添加响应头及处理,我没测试也没写了,如果哪天有需要再试试。 fastcgi_cache_use_stale确定在与 FastCGI 服务器通信期间发生错误时可以使用陈旧缓存响应的情况。
默认值是 off ,这个指令的参数与 fastcgi_next_upstream 指令的参数相匹配。如果无法选择用于处理请求的 FastCGI 服务器,则错误参数还允许使用过时的缓存响应。此外,如果当前正在更新,更新参数允许使用陈旧的缓存响应。这允许在更新缓存数据时最大限度地减少对 FastCGI 服务器的访问次数。 在响应过时 (1.11.10) 后的指定秒数内,也可以直接在响应标头中启用使用过时的缓存响应。这比使用指令参数的优先级低。
为了在填充新缓存元素时尽量减少对 FastCGI 服务器的访问次数,可以使用 fastcgi_cache_lock 指令。 看明白了吗?是不是一脸懵B?其实我们只需要设置一个
fastcgi_cache_valid为不同的响应代码设置缓存时间。
这个命令我们已经使用过了,例如,以下指令
表示的就是为代码为 200 和 302 的响应设置 10 分钟的缓存时间,为代码为 404 的响应设置 1 分钟的缓存时间。 如果只指定缓存时间
那么只有 200、301 和 302 响应被缓存。 此外,可以指定 any 参数来缓存任何响应:
缓存的参数也可以直接在响应头中设置。这比使用指令设置缓存时间具有更高的优先级。
可以使用 fastcgi_ignore_headers 指令禁用对这些响应头字段中的一个或多个的处理。 最后这个响应头的设置我们可以单独测试一下,在 PHP 文件中,设置一个头 fastcgi_no_cache定义不将响应保存到缓存的条件。
如果字符串参数中至少有一个值不为空且不等于“0”,则不会保存响应,和 fastcgi_cache_bypass 配置方式类似的,那个是即使有缓存文件也不走缓存,这个是完全不生成缓存文件。 总结又是涨姿势的一天吧,原来我还真不知道有这个功能,很多东西在系统学习之前确实都不会了解得太深入。特别是现在各种方便的工具帮我们配置网站之后,更是很少人会去仔细查看文档中的内容。 不过话说回来,真正在使用动态语言进行缓存时,其实让动态语言自身去处理还是更方便一些,比如我们在这里就看到更新缓存或者删除缓存还是比较费劲的,不像 Redis 之类的非常简单,而且 Redis 走内存,速度比硬盘缓存可能还更占优势。使用 Nginx 缓存最大的好处还是减少一次内部的 CGI 调用。因此,如何使用,什么场景,还是要看具体的业务情况了。 |