最近发现自己学习的东西太杂,不成系统,所以准备整理后再出发。整理也是一种升华。在学习的路上多总结,感觉很好!

这里从缓存开始说起,好久都没有写什么博客了,内容有不对的地方欢迎指正linux缓存系统学习之浏览器缓存_浏览器

好像大多问题都能通过加缓存解决,什么叫缓存呢,缓存就是把需要花费昂贵开销的计算结果保存起来,在之后访问直接取出,这个昂贵的开销可以是昂贵的计算,也可以是昂贵的带宽费用等等

从client端出发,首先来说说浏览器缓存,也许从某种角度上看,浏览器也是一个web服务器,也能算一级缓存,内部也存在的各种缓存协商的过程


last-modified

原理

这个从名字上就基本上能了解他是什么呢,最后一次修改时间,

流程图:

linux缓存系统学习之浏览器缓存_linux_02

第一次访问的时候,web服务端首次返回给client端last-modified最后一次修改时间,然后再一次访问的时候,client请求头中就会以if-modified-since带入最后一次修改时间,用户询问web服务端,在这个时间之后有没有做过修改,如果没有,直接本地返回304状态,如果做了修改,从web服务端直接返回给用户,用户本地保存一份,然后下次已经这一次最后的修改时间为准!这个还是比较好理解!

配置

Apache last-modified是默认开启的

模块为:mod_headers.so

关闭方法

要关掉Last-Modified的方法麻烦点,先想好你要去掉Last-Modified 的标签.然后用header模块来控制

LoadModule headers_module modules/mod_headers.so
<FilesMatch "\.(gif|jpg|png)">
Header unset Last-Modified
< /FilesMatch>

不足

1、last-modified只能精确到秒,如果在秒内做了修改,是检测不到

2、如果是集群环境的话,相同文件的last-modified可能会不相同的,用户可能要缓存获取两次

3、不管你的内容有没有真正的修改

暂时只知道这几点不足


ETag

原理

ETag:网上的有很正确的理解,我个人的理解是在client端发起访问的时候,web服务端会在返回头中带入资源的ETag值(通过算法对内容进行一个计算得出的一个唯一id)客户端缓存这个资源,然后这个ETag值也会被保存,在再一次请求相同资源的时候,浏览器会把第一次服务端返回过来的值带入请求头中(if-none-match)如果服务端内容没有表换就返回304如果有变化就返回200内容从服务端返回,如果跟last-modified一起使用的话ETag优先级高于last-modified

linux缓存系统学习之浏览器缓存_浏览器_03

配置

Apache

apache 默认开启Etag

格式:apache Etag由inode+大小+时间戳

关闭方式:

FileETag None
Header unset ETag
Header unset Last-Modified

nginx默认没有这个模块,需要重新编译进去

不足

1、没有进行实际的测试,感觉如果文件多了,大了,还有如果自己写的算法烂也会影响性能



expires

原理

这个最吊,直接可以不用跟web服务端进行缓存协商,本地协商就能完成,web服务端中返回head中带入过期时间,然后浏览器每一次只需要date与expires进行比较就好,如果过期就去服务端获取,如果没有过期就本地返回!

linux缓存系统学习之浏览器缓存_流程图_04

配置

Apache是通过expires模块实现

格式:

ExpiresActive on
ExpiresByType p_w_picpath/gif “access plus 1 month”
ExpiresByType p_w_picpath/jpg “access plus 1 month”
ExpiresByType p_w_picpath/jpeg “access plus 1 month”

。。。。。

nginx上面默认有的并开启状态

格式:

location ~ .*\.(js|css)?$
{
expires 1h;

不足:

1、expires受服务端跟client端时间影响,如果客户端时间如果慢了还是快了都会影响缓存的有效行,而客户端时间这种不可控的信息我们不能去实现时间一致



因为expires的不足,cache-control出来了

cache-control

原理

cache-control跟expires一样都是说明资源的一个有效时间,而不通的在于是expires是date时间到服务端给出的时间的一个有效时间,cache-control有效时间是client访问web服务端之后开始计算的一个时间内。如果max-ago=60 就是第一次访问后的60后资源过期,这样子就去除了expires依赖client时间的弊端,如果expires与cache-control同时存在,cache-control的优先级高于expires

nginx配置


 if ($request_uri ~* "^/$|^arch/.+/|^/company/.+/") {
 add_header    Cache-Control  max-age=3600;

}
if ($request_uri ~* "^arch-suggest/|^/categories/") {
   add_header    Cache-Control  max-age=86400;
}



小注释:

浏览器的三种刷新方式:

  1. 使用浏览器的转到按钮、或者在地址栏直接回车、或者打开新窗口重新输入该网址

    优先走浏览器本地缓存,如果本地有缓存则根本不会访问服务器

    注:如果是chrome下,在本窗口下的地址栏直接回车,html不会走本地缓存,如果是新开窗口在地址栏输入网址回车,则html依然会走本地缓存。估计是chrome的策略,firefox下则都会走本地缓存

  2. 使用浏览器的刷新按钮、F5刷新或者是Mac Chrome下的Command + r刷新

    不走浏览器本地缓存,不过会走服务端缓存,会返回304

  3. 使用浏览器的强制刷新,如Ctrl+ F5或者是Mac Chrome下的Command + Shift + r

    既不走浏览器本地缓存,也不走服务端缓存,不返回304

无法被浏览器缓存的请求:

  1. HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0等告诉浏览器不用缓存的请求

  2. 需要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的

  3. 经过HTTPS安全加密的请求(有人也经过测试发现,ie其实在头部加入Cache-Control:max-age信息,firefox在头部加入Cache-Control:Public之后,能够对HTTPS的资源进行缓存,参考《HTTPS的七个误解》)

  4. POST请求无法被缓存

  5. HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存