缓存对于Web至关重要,尤其对于大型高负载Web站点。Nginx缓存可作为性能优化的一个重要手段,可以极大减轻后端服务器的负载。通常对于静态资源,即较少经常更新的资源,如图片,css或js等进行缓存,从而在每次刷新浏览器的时候,不用重新请求,而是从缓存里面读取,这样就可以减轻服务器的压力。
Nginx设置缓存有两种方式:
对于站点中不经常修改的静态内容(如图片,JS,CSS),可以在服务器中设置expires过期时间,控制浏览器缓存,达到有效减小带宽流量,降低服务器压力的目的。
浏览器请求 ---> 无缓存 ---> 请求WEB服务器 ---> 请求响应 ---> 呈现
浏览器请求 ---> 有缓存 ---> 校验过期 ---> 是否有更新 ---> 呈现
Expires HTTP1.0, Cache-Control(max-age) HTTP1.1
协议中Etag头信息校验 Etag ()
Last-Modified头信息校验 Last-Modified (具体时间)




第一步:客户端第一次向Nginx请求数据A;
第二步:当Nginx发现缓存中没有数据A时,会向服务端请求数据A;
第三步:服务端接收到Nginx发来的请求,则返回数据A到Nginx,并且缓存在Nginx;
第四步:Nginx返回数据A给客户端应用;
第五步:客户端第二次向Nginx请求数据A;
第六步:当Nginx发现缓存中存在数据A时,则不会请求服务端;
第七步:Nginx把缓存中的数据A返回给客户端应用。
网页缓存是由HTTP消息头中的"Cache-control"来控制的,常见的取值有private、no-cache、max-age、must-revalidate等,默认为private。
其作用根据不同的重新浏览方式分为以下几种情况。
| Cache-directive | 说明 | 
|---|---|
| public | 所有内容都将被缓存(客户端和代理服务器都可缓存)。 | 
| private | 内容只缓存到私有缓存中(仅客户端可以缓存,代理服务器不可缓存)。 | 
| no-cache | 必须先与服务器确认返回的响应是否被更改,然后才能使用该响应来满足后续对同一个网址的请求。因此,如果存在合适的验证停牌(ETag),no-cache会发起往返通信来验证缓存的响应,如果资源未被更改,可以避免下载。 | 
| no-store | 所有内容都不会被缓存到缓存或Internet临时文件中,强制缓存和对比缓存都不会触发。 | 
| must-revalidation.proxy-revalidation | 如果缓存内容失败,请求必须发送到服务器、代理以进行重新验证。 | 
| max-age=xxx(xxx is numeric) | 缓存的内容将在xxx秒失效,这个选项只在HTTP 1.1可用,并如果和Last-Modified一起使用时,优先级较高。 | 
默认情况下,NGINX尊重Cache-Control源服务器的标头。它不缓存响应Cache-Control设置为Private,No-Cache或No-Store或Set-Cookie在响应头。NGINX只缓存GET和HEAD客户端请求。
如下配置可覆盖这些默认值:
  1 location /images/ {
  2     proxy_cache my_cache;
  3     proxy_ignore_headers Cache-Control;
  4     proxy_cache_valid any 30m;
  5     # ...
  6 }语法:expires [modified] time;
expires epoch | max | off;
默认值:expires off; #静态缓存
作用:Expires是服务端返回的到期时间。如果下一次请求如果小于服务端返回的过期时间,则直接使用缓存数据。Expires针对HTTP1.0的东西,当前通常浏览器默认都是使用HTTP1.1。而且由于该值是有服务端生成,而客户端的时间和服务端的时间有可能不一致,导致存在一定误差。所以HTTP1.1使用Cache-Control替代。
可配置段:http, server, location, if in location
参数释义:
max启用后为:Expires: Thu, 31 Dec 2037 23:55:55 GMT Cache-Control: max-age=315360000 (10年);
epoch启用后为:Expires: Thu, 01 Jan 1970 00:00:01 GMT Cache-Control: no-cache;
time:设定具体时间,可以携带单位(通过@),如:表示一天内的下午3点30分后失效expires @15h@30m;time是负数:表示”Cache-Control: no-cache”;time是正数或零:”Cache-Control: max-age=t”,其中t单位为秒。
配置示例:
  1 server {
  2     listen       80;
  3     server_name  xxx.xxx.com;
  4     root         /app/xxx/html/;
  5     location ~ .*\.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm)$
  6     {
  7         expires      7d;
  8     }
  9 
 10     location ~ .*\.(?:js|css)$
 11     {
 12         expires      7d;
 13     }
 14 
 15     location ~ .*\.(?:htm|html)$    #不缓存html
 16     {
 17         add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
 18     }
 19 }对于http协议头Cache-Control,其值释义如下:
语法:proxy_cache zone | off;
默认:proxy_cache off;
可配置段:http, server, location
作用:设置是否开启对后端响应的缓存,如果开启的话,参数值就是zone的名称。
示例:
  1 proxy_cache mycache;语法:proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size[inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
默认值:——
可配置段:http
作用:指定缓存位置、缓存名称、内存中缓存内容元数据信息大小限制、缓存总大小限制。缓存位置是一个目录应该先创建好,nginx并不会帮我们创建这个缓存目录。
参数释义:
注意:inactive 和 expired 配置项的含义是不同的,expired 只是判断过期时间,不会删除缓存;而 inactive 是直接删除过期缓存。
配置示例:
  1 http {
  2     ...
  3     // 缓存目录:/data/nginx/cache
  4     // 缓存名称:one
  5     // 缓存占用内存空间:10m
  6     // 缓存目录级别为2
  7     // 缓存最大时间为60分钟
  8     // 加载器每次迭代过程最多执行300毫秒
  9     // 加载器每次迭代过程中最多加载200个文件
 10     // 缓存硬盘空间最多为 200m
 11     proxy_cache_path /data/nginx/cache  levels=1:2 keys_zone=one:10m inactive=60m loader_threshold=300 loader_files=200 max_size=200m;
 12     server {
 13         listen 8080;
 14         // 使用名称为one的缓存
 15         proxy_cache one;
 16         location / {
 17             // 此location中使用默认的缓存配置
 18             proxy_pass http://backend1;
 19         }
 20         location /some/path {
 21             proxy_pass http://backend2;
 22         // 缓存有效期为1分钟
 23             proxy_cache_valid any 1m;
 24             // 被请求3次以上时才缓存
 25             proxy_cache_min_uses 3;
 26         // 请求中有下面参数值时不走缓存
 27             proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
 28         }
 29     }
 30 }提示:在如上缓存工作中有两个附加进程:
语法:proxy_cache_valid [code ...] time;
默认值:——
可配置段:http, server, location
作用:默认情况下,缓存的内容是长期存留的,除非缓存的总量超出限制,此字段可配置不同的响应码缓存不同的时长,即指定缓存的有效期。
示例:
响应状态码为200 302时,10分钟有效;
响应状态码为404时,1分钟有效;
  1 ……
  2 proxy_cache_valid 200 302 10m;
  3 proxy_cache_valid 404      1m;
  4 ……对应任何状态码,5分钟有效;
  1 ……
  2 proxy_cache_valid any 5m;
  3 ……语法:proxy_cache_methods GET | HEAD | POST ...;
默认值:proxy_cache_methods GET HEAD;
可配置段:http, server, location
作用:对哪些方法的请求进行缓存。
提示:更多缓存配置参考:https://shuwoom.com/?p=4311、https://linux.cn/article-5945-1.html。
第三方缓存模块参考:https://www.jianshu.com/p/1ba7d91afa39。
语法:proxy_cache_key string;
默认值:proxy_cache_key $scheme$proxy_host$request
可配置段:http, server, location
作用:用于设置不同维度进行缓存,即给缓存设定key。如缓存url。
示例:
语法:proxy_cache_min_uses string;
默认值:proxy_cache_min_uses 1;
可配置段:http, server, location
作用:指定请求至少被发送了多少次以上时才缓存,可以防止低频请求被缓存。
示例:
  1 ……
  2 proxy_cache_min_uses 5;
  3 ……
  4 语法:proxy_cache_bypass string;
默认值:——
可配置段:http, server, location
作用:指定哪些响应在某些值不为空或不为0的情况下不走缓存。
示例:
  1 ……
  2 proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment;
  3 ……
  4 语法:proxy_no_chache string;
默认值:——
可配置段:http, server, location
作用:指定定哪些请求不被缓存,即响应来自原始服务器而不是缓存。
示例:
  1 ……
  2 proxy_no_chache $cookie_nocache $arg_nocache $arg_nocache;
  3 ……
  4 语法:proxy_cache_use_stale off | on;
默认值:proxy_cache_use_stale off;
可配置段:http, server, location
作用:指定在后端服务器在返回什么状态码的情况下可以使用过期的缓存。
示例:
  1 ……
  2 proxy_cache_use_stale error timeout invalid_header http_500 http_502 http_503 http_504;
  3 ……
  4 语法:proxy_cache_lock off | on;
默认值:proxy_cache_lock off;
可配置段:http, server, location
作用:默认不开启,开启的话则每次只能有一个请求更新相同的缓存,其他请求要么等待缓存有数据要么限时等待锁释放。通常在多个客户端请求缓存未命中时,只有第一个请求可以发向原服务器,其他请求要等待第一个响应返回或者超时后,使用缓存响应客户端。该参数可以合并回源请求,减轻峰值流量下的压力。
示例:
  1 ……
  2 proxy_cache_lock on;
  3 ……
  4 语法:proxy_cache_lock_timeout time;
默认值:proxy_cache_lock_timeout 5s;
可配置段:http, server, location
作用:等待缓存锁超时之后将直接请求后端,结果不会被缓存。
示例:
  1 ……
  2 proxy_cache_lock_timeout 5s;
  3 ……
  4 提示:本实验结合反向代理演示最佳,具体配置参考《010.Nginx正反代理》步骤六。
参考文档:https://www.myfreax.com/nginx-caching-guide/。
  1 location ~ /purge(/.*) {
  2         allow       127.0.0.1;
  3         allow       192.168.55.0/24;
  4         deny        all;
  5         proxy_cache_purge cache_one $1$is_args$args;
  6     }注意:使用proxy_cache_purge清除缓存,必须提前安装ngx_cache_purge模块,安装模块必须基于编译安装的Nginx。之后使用url访问即可清除对应缓存,如cache.linuxds.com/purge/nginx.png即可清除cache.linuxds.com/nginx.png此文件的缓存。
清除缓存脚本如下,必须在缓存服务器上执行,
[root@nginx01 ~]# vi nginx_cache_clean.sh
  1 #!/bin/sh
  2 #****************************************************************#
  3 # ScriptName: nginx_cache_clean.sh
  4 # Author: null
  5 # Create Date: 2020-06-24 00:03
  6 # Modify Author: xhy
  7 # Modify Date: 2020-06-24 00:03
  8 # Version:
  9 #***************************************************************#
 10 echo -e "\n"
 11 echo -n -e "\e[35;1m请输入Nginx Proxy_cache缓存的具体路径(提示:可使用Tab补全!)\e[0m\e[34;5m:\e[0m"
 12 read -e path
 13 CACHE_DIR=$path
 14 echo -e "\e[32;1m----------------------------------------------------------------\e[0m"
 15 echo -e "\e[32;1m----------------------------------------------------------------\e[0m"
 16 echo -n -e "\e[32;1m请输入删除操作的类型:\n1.按文件类型删除\t2.按具体文件名删除\t3.按文件目录删除\n:"
 17 read action
 18      case $action in
 19 1)
 20 echo -e "\e[32;1m----------------------------------------------------------------\e[0m"
 21 echo -e "\e[32;1m----------------------------------------------------------------\e[0m"
 22 echo -n -e "\e[34;1m 请输入你要删除的缓存文件类型(多个参数可空格隔开)\e[0m\e[34;5m:\e[0m"
 23 read -a FILE
 24 for i in `echo ${FILE[*]}|sed 's/ /\n/g'`
 25 do
 26 grep -r -a  \.$i ${CACHE_DIR}| awk 'BEGIN {FS=":"} {print $1}'  > /tmp/cache_list.txt
 27  for j in `cat /tmp/cache_list.txt`
 28 do
 29    rm  -rf  $j
 30    echo "$i     $j 删除成功!"
 31  done
 32 done
 33 ;;
 34 2)
 35 echo -e "\e[32;1m----------------------------------------------------------------\e[0m"
 36 echo -e "\e[32;1m----------------------------------------------------------------\e[0m"
 37 echo -n -e "\e[33;1m 请输入你要删除的缓存文件具体名称(多个参数可空格隔开)\e[0m\e[34;5m:\e[0m"
 38 read -a FILE
 39 for i in `echo ${FILE[*]}|sed 's/ /\n/g'`
 40 do
 41 grep -r -a  $i ${CACHE_DIR}| awk 'BEGIN {FS=":"} {print $1}'  > /tmp/cache_list.txt
 42  for j in `cat /tmp/cache_list.txt`
 43 do
 44    rm  -rf  $j
 45    echo "$i  $j 删除成功!"
 46  done
 47 done
 48 ;;
 49 3)
 50 echo -e "\e[32;1m----------------------------------------------------------------\e[0m"
 51 echo -e "\e[32;1m----------------------------------------------------------------\e[0m"
 52 echo -n -e "\e[33;1m支持的模式有:\n1.清除网站cache目录下的所有缓存:cache.aa.com/data/cache/\n2.清除网站shop下的所有缓存:cache.aa.com/data/upload/shop\n3.清除网站根目录下的所有缓存:cache.aa.com\e[0m\n"
 53 echo -n -e "\e[34;1m 请输入你要删除的缓存文件具体目录\e[0m\e[34;5m:\e[0m"
 54 read -a FILE
 55 for i in `echo ${FILE[*]}|sed 's/ /\n/g'`
 56 do
 57 grep -r -a  "$i" ${CACHE_DIR}| awk 'BEGIN {FS=":"} {print $1}'  > /tmp/cache_list.txt
 58  for j in `cat /tmp/cache_list.txt`
 59 do
 60    rm  -rf  $j
 61    echo "$i  $j 删除成功!"
 62  done
 63 done
 64 ;;
 65 *)
 66 echo "输入错误,请重新输入"
 67 ;;
 68 esac参考文档:https://lichi6174.github.io/nginx-cache/。