一、简介

Nginx版本从0.7.48开始,支持了类似Squid的缓存功能。这个缓存是把URL及相关组合当做Key,用Md5算法对Key进行哈希,得到硬盘上对应的哈希目录路径,从而将缓存内容保存在该目录内。

Nginx Web 缓存服务只能为指定URL或状态码设置过期时间,不支持类似Squid的PURGE指令手动清除缓存;但是我们可以通过Nginx的模块ngx_cache_purge清除指定URL的缓存。

  • proxy_cache:缓存后端服务器的内容,可能是任何内容,包括静态的和动态,减少了nginx与后端通信的次数,节省了传输时间和后端宽带
  • fastcgi_cache:缓存fastcgi生成的内容,很多情况是php生成的动态的内容,少了nginx与php的通信的次数,更减轻了php和数据库(mysql)的压力,这比用memcached之类的缓存要轻松得多


图片来自网络

二、配置

nginx.conf

fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
fastcgi_temp_path  /tmp/nginx/fcgi/temp;

vhost配置

server {server_name example.com www.example.com;access_log   /var/log/nginx/example.com.access.log;error_log    /var/log/nginx/example.com.error.log;root /var/www/example.com/htdocs;index index.php;set $skip_cache 0;# POST requests and urls with a query string should always go to PHPif ($request_method = POST) {set $skip_cache 1;}   if ($query_string != "") {set $skip_cache 1;}   # Don't cache uris containing the following segmentsif ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {set $skip_cache 1;}   # Don't use the cache for logged in users or recent commentersif ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {set $skip_cache 1;}location / {try_files $uri $uri/ /index.php?$args;}    location ~ \.php($|/) {try_files $uri =404; include fastcgi_params;fastcgi_split_path_info         ^(.+\.php)(/.+)$;fastcgi_param PATH_INFO         $fastcgi_path_info;fastcgi_param SCRIPT_FILENAME   $document_root$fastcgi_script_name;fastcgi_pass unix:/dev/shm/php-socket;fastcgi_cache_bypass $skip_cache;fastcgi_no_cache $skip_cache;fastcgi_cache WORDPRESS;include fcgi_cache_params;}location ~ /purge(/.*) {fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";} location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {access_log off;   log_not_found off; expires max;}location = /robots.txt { access_log off; log_not_found off; }location ~ /\. { deny  all; access_log off; log_not_found off; }
}

fcgi_cache_params配置

#include fcgi_cache_params;
#fastcgi_cache_valid 200 302 1s;
### fcgi-cache
fastcgi_cache fcgi;
fastcgi_cache_valid 200 302 1s;
fastcgi_cache_valid 404 500 502 503 504 0s;
fastcgi_cache_valid any 1m;
fastcgi_cache_min_uses 1;
fastcgi_cache_use_stale error timeout invalid_header http_500 http_503 updating;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
#add_header X-Cache "$upstream_cache_status - $upstream_response_time";
fastcgi_cache_key "$scheme$request_method$host$request_uri"

大概解释下各个参数的含义:

fastcgi_cache  该指令用于设置哪个缓存区将被使用,zone_name的值为fastcgi_cache_path指令创建的缓存名称

fastcgi_cache_path 作用域:http

fastcgi_cache_path path
[levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time]
[max_size=size] [loader_files=number] [loader_sleep=time] [loader_threshold=time]
[purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];

该指令用于设置缓存文件的存放路径,示例如下:fastcgi_cache_path /data/nginx/cache levels=1:2  keys_zone=cache_one:100M  inactive=1d  max_size=10g;

a、levels:指定了该缓存空间有两层hash目录,设置缓存目录层数,levels=1:2,表示创建两层目录缓存,最多创建三层。第一层目录名取fastcgi_cache_key md5的最后一个字符,第二层目录名取倒数2-3字符,如:fastcgi_cache_key md5为b7f54b2df7773722d382f4809d65029c,则:

levels=1:2为/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c
levels=1:2:3为/data/nginx/cache/c/29/650/b7f54b2df7773722d382f4809d65029c

b、keys_zone为这个缓存区起名为zone_name,500m指代缓存空间为500MB;

c、inactive=1d 代表如果缓存文件一天内没有被访问,则删除;

d、max_size=30g代表硬盘缓存最大为30G;

设置缓存多个磁盘

fastcgi_cache_path /path/to/hdd1 levels=1:2 keys_zone=my_cache_hdd1:10m max_size=10g  inactive=60m use_temp_path=off;
fastcgi_cache_path /path/to/hdd2 levels=1:2 keys_zone=my_cache_hdd2:10m max_size=10g  inactive=60m use_temp_path=off;split_clients $request_uri $my_cache {50%          "my_cache_hdd1";50%          "my_cache_hdd2";
}server {...location / {fastcgi_cache $my_cache;}
}

将缓存文件放入内存中

编辑/etc/fstab  或者 放入 /dev/shm

tmpfs /etc/nginx/cache tmpfs defaults,size=100M 0 0
mount -a
df -ah | grep tmpfs 

需要注意的是fastcgi_cache缓存是先写在fastcgi_temp_path再移到fastcgi_cache_path,所以这两个目录最好在同一个分区,从0.8.9之后可以在不同的分区,不过还是建议放同一分区

fastcgi_cache_methods 该指令用于设置缓存哪些HTTP方法,默认缓存HTTP GET/HEAD方法。

fastcgi_cache_min_uses  URL经过多少次请求将被缓存

fastcgi_cache_valid  reply_code [reply_code ... ] time

该指令用于对不同返回状态码的URL设置不同的缓存时间,例如: 

fastcgi_cache_valid 200 302 10m;
fastcgi_cache_valid 404      1m;

设置202 302状态URL缓存10分钟,404状态的URL缓存1分钟。

注意:如果不指定状态码,直接指定缓存时间,则只有200,301,302状态码会进行缓存。

fastcgi_cache_valid 5m;

any 可以指定缓存任何响应码    

fastcgi_cache_valid 200 302 10m;
fastcgi_cache_valid 301      1h;
fastcgi_cache_valid any      1m;

缓存的参数也可以在响应头直接设置。这些的优先级高于缓存时间设定使用该指令

  • The “X-Accel-Expires” header field sets caching time of a response in seconds. The zero value disables caching for a response. If the value starts with the @ prefix, it sets an absolute time in seconds since Epoch, up to which the response may be cached.
  • If the header does not include the “X-Accel-Expires” field, parameters of caching may be set in the header fields “Expires” or “Cache-Control”.
  • If the header includes the “Set-Cookie” field, such a response will not be cached.
  • If the header includes the “Vary” field with the special value “*”, such a response will not be cached (1.7.7). If the header includes the “Vary” field with another value, such a response will be cached taking into account the corresponding request header fields (1.7.7).

fastcgi_cache_key

该指令用来设置Web缓存的Key值,Nginx根据Key值MD5缓存。一般根据$host(域名),$request_uri(请求的路径)等变量组合成fastcgi_cache_key。

例如:fastcgi_cache_key "$scheme$request_method$host$request_uri";

定义fastcgi_cache的key,示例中就以请求的URI作为缓存的key,Nginx会取这个key的md5作为缓存文件,如果设置了缓存哈希目录,Nginx会从后往前取相应的位数做为目录。

注意一定要加上$request_method作为cache key,否则如果HEAD类型的先请求会导致后面的GET请求返回为空

fastcgi_temp_path  path [level1 [level2 [level3]]];  默认为 fastcgi_temp;

该指令用来设置fastcgi_cache临时文件目录

fastcgi_temp_path /spool/nginx/fastcgi_temp 1 2;

a temporary file might look like this:

/spool/nginx/fastcgi_temp/7/45/00000123457

fastcgi_cache_use_stale : fastcgi_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_503 | http_403 | http_404 | off ...;

定义哪些情况下用过期缓存

x-cache头,用于调试

$upstream_response_time为过期时间

$upstream_cache_status 变量表示此请求响应来自cache的状态,几种状态分别为:

  • MISS – The response was not found in the cache and so was fetched from an origin server. The response might then have been cached.
  • BYPASS – The response was fetched from the origin server instead of served from the cache because the request matched a proxy_cache_bypass directive (see Can I Punch a Hole Through My Cache? below.) The response might then have been cached.
  • EXPIRED – The entry in the cache has expired. The response contains fresh content from the origin server.
  • STALE – The content is stale because the origin server is not responding correctly, and proxy_cache_use_stale was configured.
  • UPDATING – The content is stale because the entry is currently being updated in response to a previous request, and proxy_cache_use_stale updating is configured.
  • REVALIDATED – The proxy_cache_revalidate directive was enabled and NGINX verified that the current cached content was still valid (If-Modified-Since or If-None-Match).
  • HIT – The response contains valid, fresh content direct from the cache.

有一些情况会影响到cache的命中 这里需要特别注意

  • Nginx fastcgi_cache在缓存后端fastcgi响应时,当响应里包含“set-cookie”时,不缓存;
  • 当响应头包含Expires时,如果过期时间大于当前服务器时间,则nginx_cache会缓存该响应,否则,则不缓存;
  • 当响应头包含Cache-Control时,如果Cache-Control参数值为no-cache、no-store、private中任意一个时,则不缓存,如果Cache-Control参数值为max-age时,会被缓存,且nginx设置的cache的过期时间,就是系统当前时间 + mag-age的值。
header("Expires: ".gmdate("D, d M Y H:i:s", time()+10000).' GMT');
header("Expires: ".gmdate("D, d M Y H:i:s", time()-99999).' GMT');
header("X-Accel-Expires:5"); // 5s
header("Cache-Control: no-cache"); //no cache
header("Cache-Control: no-store"); //no cache
header("Cache-Control: private"); //no cache
header("Cache-Control: max-age=10"); //cache 10s
setcookie('hello',"testaaaa"); //no cache

注意session使用的时候有坑,可以用下面来设置

session_cache_limiter("none");
session_start();
echo date("Y-m-d H:i:s",time());

可以看一下PHP源代码中的头信息 Expires等

//ext/session/session.c  line:1190 左右
// ...
CACHE_LIMITER_FUNC(private) /* {{{ */
{ADD_HEADER("Expires: Thu, 19 Nov 1981 08:52:00 GMT");CACHE_LIMITER(private_no_expire)(TSRMLS_C);
}
/* }}} */
//再到这里3 或者上面几个 ##默认是nocache
CACHE_LIMITER_FUNC(nocache) /* {{{ */
{ADD_HEADER("Expires: Thu, 19 Nov 1981 08:52:00 GMT");/* For HTTP/1.1 conforming clients and the rest (MSIE 5) */ADD_HEADER("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");/* For HTTP/1.0 conforming clients */ADD_HEADER("Pragma: no-cache");
}
/* }}} */
//这里2
static php_session_cache_limiter_t php_session_cache_limiters[] = {CACHE_LIMITER_ENTRY(public)CACHE_LIMITER_ENTRY(private)CACHE_LIMITER_ENTRY(private_no_expire)CACHE_LIMITER_ENTRY(nocache){0}
};static int php_session_cache_limiter(TSRMLS_D) /* {{{ */
{php_session_cache_limiter_t *lim;if (PS(cache_limiter)[0] == '\0') return 0;if (SG(headers_sent)) {const char *output_start_filename = php_output_get_start_filename(TSRMLS_C);int output_start_lineno = php_output_get_start_lineno(TSRMLS_C);if (output_start_filename) {php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent (output started at %s:%d)", output_start_filename, output_start_lineno);} else {php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent");}return -2;}for (lim = php_session_cache_limiters; lim->name; lim++) {if (!strcasecmp(lim->name, PS(cache_limiter))) {lim->func(TSRMLS_C);   //这里1return 0;}}return -1;
}

三、清除缓存

NGINX只在商业版中支持proxy_cache_purge指令清除缓存,开源的ngx_cache_purge模块只支持单一key的缓存清除。为了实现按目录清除缓存只能自己开发。

NGINX作为Cache服务器时将资源内容以文件形式进行缓存,缓存元信息存储于共享内存中,组织成一棵红黑树。红黑树中的每个节点代表一个Cache元信息。NGINX将Cache Key的HASH值作为红黑树节点的KEY。内容缓存文件以该HASH值作为文件名存储在磁盘上。

NGINX的处理流程简化描述是这样的:当请求到达时,根据Cache Key的HASH值在红黑树中进行查找。如果找到,并查看相关信息,如果Cache可用,返回相应的Cache文件。否则,则回源抓取。

因为元信息是以Cache Key的HASH值作为Key存储的,因而红黑树中并不能保留Cache Key中有层级关系. 如”/uri/foo”和”/uri/bar”在元信息红黑树中完全没有关系。要实现按照目录清除缓存,需要将Cache Key中层次关系存储起来。

可以这样做,在共享内存中建立一棵目录树来存储层级关系。将Cache Key类比于文件系统中的路径, 每级路径存储为树中的一个节点。当需要清除某一目录下的所有缓存时,将该节点子树的中的所有缓存清除即可。

安装Purge模块

Purge模块被用来清除缓存

wget http://labs.frickle.com/files/ngx_cache_purge-1.2.tar.gz
tar -zxvf ngx_cache_purge-1.2.tar.gz

编译

./configure \
…… \
--with-http_geoip_module \
--add-module=/usr/local/ngx_cache_purge-1.2

四、需要注意的一些问题

设置了之后重启nginx就可以生效了,这个时候再访问php的页面的话,就会被缓存了,可以查看/var/logs/nginx/fastcgi_cache_dir这个目录下面是有缓存文件的。最后再说明一点,如果更改了缓存目录的路径,一定要把缓存的名称也改掉,后端调用的名称也同步改掉,如果只改掉了缓存目录,不改缓存名称的话,缓存的时候还是会缓存到之前的路径下面去,但是调用的时候调用的是新的路径,这个时候就会出现找不到的情况

参考文章

http://www.nginxtips.com/configure-nginx-fastcgi-cache/

http://www.haidx.com/fastcgi-cache-details.html

http://www.just4coding.com/blog/2014/11/01/nginx-purge-directory/

http://weizhifeng.net/nginx-proxy-cache.html

https://www.nginx.com/blog/nginx-caching-guide/#gs.6PdbraI

http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache

https://www.cnxct.com/several-reminder-in-nginx-fastcgi_cache-and-php-session_cache_limiter/

https://rtcamp.com/wordpress-nginx/tutorials/single-site/fastcgi-cache-with-purging/

http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache

转载于:https://www.cnblogs.com/chenpingzhao/p/4983703.html

【nginx】关于fastcgi_cache相关推荐

  1. 利用nginx的fastcgi_cache模块来做缓存

    nginx不仅有个大家很熟悉的缓存代理后端内容的proxy_cache,还有个被很多人忽视的fastcgi_cache. proxy_cache的作用是缓存后端服务器的内容,可能是任何内容,包括静态的 ...

  2. Wordpress优化:网站用nginx前端缓存+Redis Cache缓存提速网站

    本问转载:https://www.src1024.com/xy/seo/31780.html 新手站长搭建网站一般为了省钱没去选择大厂的云服务器,而小厂的服务器虽然便宜,但是访问速度也很感人,同时如果 ...

  3. nginx服务器缓存文件清理,清除nginx缓存文件并不总是有效

    我运行nginx服务器+ PHP webservices API.我使用nginx的fastcgi_cache来缓存所有GET请求,当更新某些资源时,我清除一个或多个相关的缓存资源. 我用来执行此操作 ...

  4. linux+nginx+清楚缓存,缓存 – 清除nginx缓存文件并不总是有效

    我运行一个nginx服务器 PHP webservices API.我使用nginx的fastcgi_cache来缓存所有GET请求,当更新某些资源时,我清除一个或多个相关的缓存资源. 我用来执行此操 ...

  5. 技术晨读_2014_9_1

    #技术晨报# NoSQL反模式 – 文档数据库篇 文章说的是关系型数据库怎么转换为文档型数据库,比如mongoDB... http://blog.nosqlfan.com/html/4156.html ...

  6. nginx介绍及常用功能

    什么是nginx nginx跟Apache一样,是一个web服务器(网站服务器),通过HTTP协议提供各种网络服务. Apache:重量级的,不支持高并发的服务器.在Apache上运行数以万计的并发访 ...

  7. nginx 的proxy_cache才是王道

    nginx 的proxy_cache才是性价比最高的缓存, 我目前的配置是LiteSpeed+nginx,可以参考apache+nginx 将动态内容交给LiteSpeed或apache来处理,然后利 ...

  8. 使用Nginx的proxy_cache缓存功能取代Squid

    [文章作者:张宴 本文版本:v1.2 最后修改:2009.01.12 转载请注明原文链接:http://blog.s135.com/nginx_cache/] Nginx从0.7.48版本开始,支持了 ...

  9. Nginx与PHP(FastCGI)的安装、配置、优化

    一.什么是 FastCGIFastCGI是一个可伸缩地.高速地在HTTP server和动态脚本语言间通信的接口.多数流行的HTTP server都支持FastCGI,包括Apache.Nginx和l ...

最新文章

  1. CTFshow 命令执行 web54
  2. pyhanlp 停用词与用户自定义词典
  3. 梯度下降:求线性回归
  4. IntelliJ IDEA for Mac 文件结构侧边窗口/类文件内部结构(File Structure)
  5. [html] 说说你对cookie和session的理解
  6. MIP 组件库升级公告
  7. IPv6与IPv4比较
  8. android解析JSON数组
  9. struts1.x 标签库
  10. servlet异步请求
  11. java qq邮箱发送端口号,MediaWiki 设置QQ邮箱SMTP(SSl方式)发送邮件
  12. 高并发之阿里云弹性伸缩的使用记录
  13. CSS中的四种定位以及top和margin-top的区别
  14. Android Binder机制(1):Binder架构分析
  15. Access安全吗?Access安全性之QA详解
  16. 微信小程序之问卷调查
  17. 数据分析进阶必看干货!销售额下滑详细分析案例
  18. JAVA - 变量作用域
  19. git 取消合并与撤销
  20. iverilog仿真问题

热门文章

  1. 风格之争:Coroutine vs Callback
  2. 一个华为设备防病毒 ACL 配置
  3. 自己眼中的淡定生活!
  4. 卷积神经网络CNN(Convolutional Neural Network)原理与代码实现 Le-Net5
  5. 11-用两个栈实现一个队列
  6. 间接寻址级别不同_金属激光切割机的不同配置是什么
  7. 【conda】解决 An HTTP error occurred when trying to retrieve this URL.
  8. E: Malformed line 60 in source list /etc/apt/sources.list (dist parse)
  9. Sino Global Capital CEO:Robinhood暂停GME股票交易凸显了DeFi的重要性
  10. SAP License:SAP顾问是如何炼成的——SAP到底是什么?