一 自己缓存系列的博客
缓存的基本概念
HTTP浏览器缓存
二 Nginx代理缓存
Nginx的Web缓存服务主要由'proxy_cache'相关指令集和'fastcgi_cache'相关指令集构成;'前者'用于'反向代理时'对'后端内容源服务器'进行缓存、'后者'主要用于'对FastCGI的动态程序'进行缓存
效果: nginx 缓存是可以将'远程服务器上的内容'缓存到'本地',可以设置'缓存大小'、'缓存时间'、'缓存目录'等等
(1) nginx缓存相关指令
nginx的'缓存指令'在'proxy模块中'可以查到
+++++++++++++'掌握几个核心指令即可'+++++++++++++
核心指令就是 'proxy_cache'、proxy_cache_path、'proxy_cache_valid'
(1)缓存放在哪
① proxy_cache_path、proxy_cache、proxy_temp_path
+++++++++++'只能在http块中使用'+++++++++++
1)设置Web'缓存区名称'为cache_one,内存'缓存空间大小'为200MB,'1天没有'被访问的内容'自动清除','硬盘缓存空间'大小为30GB
proxy_cache_path /data0/proxy_cache_dir levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g;
2)'proxy_temp_path'和proxy_cache_path'指定的路径'必须在'同一分区'
proxy_temp_path /data0/proxy_temp_dir; -->从'后端服务器'接收的'临时文件'的存放路径
++++++++++'location中配置使用'++++++++++
proxy_cache cache_one;
(2)指定哪些请求被缓存
① proxy_cache_methods
++++++++++++指定'哪些方法的请求'被缓存++++++++++++
proxy_cache_methods GET HEAD POST;
备注:Nginx'默认会缓存'所有'get和head方法'的请求结果
② proxy_cache_min_uses
指定请求'至少'被'发送了多少次以上'时才缓存,可以防止'低频请求被缓存'
proxy_cache_min_uses 5;
③ proxy_cache_key
以'域名'、'URI'、'参数组合'成Web缓存的Key值,Nginx根据'Key值哈希',存储'缓存内容'到'二级缓存目录'内
proxy_cache_key $host$uri$is_args$args; -->最好'加上字符串'
+++++++++++'其它做法'+++++++++++
proxy_cache_key "$host$request_uri$cookie_user";
(3)缓存的有效期
① proxy_cache_valid
'默认'情况下,缓存的内容是'长期存留'的-->'除非'缓存的总量'超出限制'
备注: 可以指定'缓存的有效期'
+++++++++++对不同的'HTTP状态码'设置'不同的缓存'时间+++++++++++
1)'缓存有效期' --> 对应任何状态码,5分钟有效
proxy_cache_valid any 5m;
2)响应状态码为'200 302'时,'10分钟'有效
proxy_cache_valid 200 302 10m;
(4)指定哪些请求不被缓存
proxy_cache_bypass 该指令'响应来自原始服务器'而'不是缓存'
例如--> proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
如果任何一个'参数值不为空'或者'不等0',nginx就'不会查找缓存',直接进行'代理转发'
(5)proxy_cache_purge
wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
tar -xf ngx_cache_purge-2.3.tar.gz && cd nginx-1.12.2
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module\
--with-http_realip_module --with-http_addition_module --with-http_gzip_static_module\
--with-http_stub_status_module --with-http_sub_module --with-pcre\
--add-module=../'ngx_cache_purge-2.3' --add-module=./'nginx_upstream_check_module'
++++++++++++++'分割线'++++++++++++++
'第三方'的'ngx_cache_purge'模块:用于'清除指定URL'的缓存
用于清除缓存.假设一个URL为'http://192.168.8.42/test.txt',通过访问'http://192.168.8.42/purge/test.txt'就可以清除该URL的缓存!
location ~ /purge(/.*)
{
设置'只允许指定的IP或IP段'才可以'清除URL缓存'
allow 127.0.0.1;
allow 192.168.0.0/16;
deny all;
proxy_cache_purge cache_one $host$1$is_args$args;
}
(6)其它参数
备注:这部分'了解即可'
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
三 服务器设置浏览器强缓存
Nginx的ngx_http_headers_module模块可以对'Cache-Control头'相关的东西进行配置
四 网页缓存
'强缓存'的设置
(1)Expires
指令'生效范围':要配置expires,可以在'http'段中或者'server'段中或者'location-->推荐'段中加入-->'作用域问题'
'语法':expires [time|epoch|max|off]
'默认值':off
expires指令'控制HTTP应答中-->response'的"Expires"和"Cache-Control"的Header头部信息,启动'控制页面缓存'的作用
time:可以使用'正数或负数',"Expires"头标的值将通过'当前系统时间'+'设定time值'来设定
time值还控制"Cache-Control"的值:
1)'负数'表示no-cache
2)'正数或零'表示max-age=time
epoch:指定"Expires"的值为 1 January,1970,00:00:01 GMT
max:指定"Expires"的值为31 December2037 23:59:59GMT,"Cache-Control"的值为10年
-1:指定"Expires"的值为当前服务器时间-1s,即'永远过期'
off:不修改"Expires"和"Cache-Control"的值
expires使用了'特定的时间',并且要求服务器和客户端的是中'严格同步'
而Cache-Control是用max-age指令指定'组件被缓存多久'
对于'不支持http1.1'的浏览器,还是'需要expires来控制',所以最好能'指定两个响应头',但'HTTP规范'规定max-age指令将'重写expires头'
++++++++++++'expires常见设置'++++++++++++
expires 30s; 30 '秒'
expires 30m; 30 '分钟'
expires 2h; 2 '小时'
expires 30d; 30 '天'
expires -1; '永远不过期'
expires max; 表示'缓存10年'
实践
① nginx不配置缓存策略
说明: 主要是nginx'不配置'任何缓存策略,'看现象'
注意: systemctl 'reload' nginx
第一次访问
第二次访问
② nginx配置expires
说明: nginx常常是'配置这种缓存策略'
第一次访问
说明: 从服务器'回传的响应头'来看,同时给客户端了'强缓存-->expires和cache-control'和'协商缓存-->etag和last-modified'的策略,各'两种'
第二次访问
访问方式: 将'光标'定位到原Tab的'末尾'重新发起请求 -->'浏览器会加一些自身的行为'
第二次访问
'重新开'一个tab进行'请求访问'
辅助验证: nginx的'access.log'日志在'该请求的时间点'并'没有日志'记录
+++++++++++'访问方式的差异'+++++++++++
1)不同浏览器访问-->'chrome'、'firefox'
2)用户访问方式-->'F5或地址栏旁边的刷新按钮'、'ctrl+f5'的的差异
3)重新开一个tab进行'请求访问'和在'原来的tab'重新访问'差异
(2)Cache
Nginx下关于缓存控制字段cache-control的配置说明
'网页缓存'是由'HTTP消息头中'的"Cache-control"来控制的,'常见的取值'有private、no-cache、max-age、must-revalidate等,'默认'为private
add_header Cache-Control "public";
add_header X-proxy-Cache $upstream_cache_status;
add_header Nging-Cache "$upstream_cache_status";
(3)Expire和Cache同时设置
header中有一个参数叫'Last-Modified',这个是'由服务器自动加上'的,如果'有这个参数',那么浏览器每次都会'重新计算'本地的cache.如果浏览器'返回一个304的编码'就表示资源没有改变,那么浏览器就可以使用本地的cache
如果 'expires' 和 'add_header Cache-Control' 同时开启的情况下,则add_header'优于'expires生效;
备注: 所以使用过期时间属性一定要确认你的'Web服务器时间设置'正确,一个途径是通过网络时间同步协议(Network Time Protocol NTP)。
++++++++++++++'二者的差异性'++++++++++++++
Expires/Cache-Control Header是控制浏览器是'直接从'浏览器缓存取数据'还是'重新发请求到服务器取数据。只是Cache-Control比Expires可以控制的多一些, 而且Cache-Control会'重写'Expires的规则-->'优先级高的原因'
Last-Modified/If-Modified-Since和ETag/If-None-Match是浏览器'发送请求'到服务器后'判断'文件'是否已经修改过',如果'没有修改过'服务器就'只发送'一个304回给浏览器,告诉浏览器直接'从自己本地'的缓存取数据;如果修改过那就整个数据'重新发给'浏览器
注:服务器的时间要准确,如果服务器的时间'落后于'实际时间,可能导致'缓存失效'
注意: 服务器会'记录资源'的几个时间-->'最后读取时间'、'内容修改时间'、'属性修改时间'
五 校验原理
原理解读
1)浏览器'第一次'请求,服务器'响应文件内容时',同时响应'etag标签'(内容的签名:内容一变,它也变)和'last_modified_since'两个标签值
2)浏览器'下次'去请求时,头信息发送这2个标签,'服务器检查'文件有没有发生变化
(1) 如'没有发生变化',直接将头信息返回:'etag、last_modified_since',这个时候'浏览器知道'内容没有改变,于是'直接调用本地缓存'
注意: 这个过程'也请求了服务器',传输的'信息极少'
场景: 对于'变化周期短'的,如'静态html、css、js'比较适合用这个方式
六 最佳实践
(1)开发测试阶段不缓存
效果:等价'ctrl+f5'强制刷新
(2)nginx为静态资源配置缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 7d;
}
(3)nginx为动态资源配置缓存
+++++++++++主要是针对'php'的+++++++++++
http {
fastcgi_cache_path /wzj levels=1:2 keys_zone=wzj:100m;
add_header cachestatus $upstream_cache_status;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /var/www/html;
location ~^ /.*(\.php)$ {
fastcgi_pass 172.25.2.100:9000;
fastcgi_index index.php;
include fastcgi.conf;
fastcgi_cache kenken;
fastcgi_cache_valid any 10m;
fastcgi_cache_key $request_uri;
}
}
}
location / {
proxy_cache wzj;
proxy_pass http://wzj;
proxy_cache_valid 200 304 12h;
proxy_cache_valid any 10m;
proxy_cache_key $host$uri$is_args$args;
add_header Nginx-Cache "$upstream_cache_status";
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
}
(5)缓存不生效
排查方向:
1)首先'配置'是否有问题
例如1: Cache-control:no-cache、no-store
例如2: Expires:1980-01-01 -->如果'出现日期'比当前时间'早',也不会缓存
2)配置没有问题,看'实际效果'和浏览器的网络中的'请求头、响应头'的部分
+++++++++'可能的处理思路'+++++++++
proxy_ignore_headers Set-Cookie Cache-Control;
proxy_hide_header Cache-Control;
proxy_hide_header Set-Cookie;
+++++++++'相关的概念了解'+++++++++
六 参考博客
最佳实践
Nginx指令add_header和proxy_set_header的区别
搞懂nginx的HTTP Proxy 模块模块
验证缓存是否生效