http缓存指的是: 当客户端向服务器请求资源时,会先抵达浏览器缓存,如果浏览器有“要请求资源”的副本,就可以直接从浏览器缓存中提取而不是从原始服务器中提取这个资源。
http缓存都是从第二次请求开始的。第一次请求资源时,服务器返回资源,并在respone header头中回传资源的缓存参数;第二次请求时,浏览器判断这些请求参数,命中强缓存就直接200,否则就把请求参数加到request header头中传给服务器,看是否命中协商缓存,命中则返回304,否则服务器会返回新的资源。
常见的http缓存只能缓存get请求响应的资源
浏览器在第一次向服务器发送请求时,若服务器觉得该资源需要缓存,这是服务器就会在响应头response-header 里面添加一个cache-control,如设置max-age,这样浏览器就会在本地缓存中存下相应的文件。
在浏览器下一次请求同样的文件时,浏览器就会去检查 max-age 有没有过期,如果没有过期就直接从本地缓存里获取资源,不会向服务器去发请求,这样就会提升页面的加载速度。如果max-age过期了,那么浏览器又会向第一次一样去向浏览器发送请求。
这种方式页面的加载速度是最快的,性能也是很好的,但是在这期间,如果服务器端的资源修改了,页面上是拿不到的,因为它不会再向服务器发请求了。这种情况就是我们在开发种经常遇到的,比如你修改了页面上的某个样式,在页面上刷新了但没有生效,因为走的是强缓存,所以Ctrl + F5之后就好了。
from memory cache代表使用内存中的缓存,from disk cache则代表使用的是硬盘中的缓存,浏览器读取缓存的顺序为memory –> disk。在浏览器中,浏览器会在js和图片等文件解析执行后直接存入内存缓存中,那么当刷新页面时只需直接从内存缓存中读取(from memory cache);而css文件则会存入硬盘文件中,所以每次渲染页面都需要从硬盘读取缓存(from disk cache)。
浏览器在请求某一资源时,会先获取该资源缓存的 header 信息,判断是否命中强缓存(cache-control 和 expires 信息),若命中直接从缓存中获取资源信息,包括缓存 header 信息,本次请求根本就不会与服务器进行通信。
选项 | 解释 |
---|---|
max-age=100 | 缓存100秒后过期,资源缓存在本地 |
no-cache | 不使用本地缓存。使用协商缓存,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载。 |
no-store | 所有内容都不会被缓存,既不使用强制缓存也不适用协商缓存,每次用户请求该资源,都会向服务器发送一个请求,服务器再返回资源 |
public | 可以被所有的用户缓存,包括客户端和代理服务器 |
private | 只能被客户端缓存,不允许CDN等中继缓存服务器对其缓存 |
s-maxage | 覆盖 max-age,作用与max-age一样,但只用于代理服务器中缓存 |
注意:如果 cache-control 与 expires 同时存在的话,cache-control 的优先级高于 expires
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程
浏览器第一次请求的时候,若服务器使用了协商缓存的策略,则它会返回资源和资源标识,并且浏览器将返回的资源存储到本地缓存。
当浏览器再次请求该资源时,浏览器向服务器发送请求和资源标识,服务器这时就会去判断当前请求的资源浏览器本次缓存的版本跟服务器里面资源最新的版本是否一致:
资源标识:
Last-Modified/If-Modified-Since
:指资源上一次修改的时间
Etag/If-None-Match
:资源对应的唯一字符串
服务器会为每个资源生成一个唯一的标识字符串,只要文件内容不同,它们对应的 Etag 就是不同的;If-Modified-Since能检查到的精度是s级的,某些服务器不能精确的得到文件的最后修改时间,我们编辑了文件,但文件的内容没有改变。因为服务器是根据文件的最后修改时间来判断的,导致重新请求所以才出现了Etag,Etag对服务器也有性能损耗 Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。
在浏览器第一次请求时,服务器返回资源和资源标识符Last-Modified(在响应头中)
在后续请求中,浏览器就会在请求头带上资源标识 If-Modified-Since 发起请求,If-Modified-Since的值就是上一次请求时返回的 Last-Modified 的值,这时在服务器就会去对比If-Modified-Since 和 Last-Modified 的值判断是否是最新资源。
优先使用 ETag,原因如下:
我们的电脑访问一个网站的时候,这个网站的服务器可能距离我们十万八千里,越远的距离意味着中间要经过更多的节点,节点之间还可能会发生阻塞和丢包的情况,结果导致我们很久都打不开网页,我们就会选择关闭网页。服务器不知道哪里的用户会来访问,世界上任何角落的用户来访问都得做好准备。按卖东西的思维来说,就是多开分店,服务器也是这个策略,备份多个服务器到世界各地,但这需要场地、网络和人员来维护,因此在世界各地的服务器就形成了一个网络,就做内容分发网络。
关键词:加速加速加速!!!更快的分发用户想要的内容
CDN:内容分发网络(Content Delivery Network)是建立并覆盖在承载网之上,由分布在不同区域的边缘节点服务器群组成的分布式网络。其目的是通过在现有的 Internet 中增加一层新的网络架构,将网站的内容发布到最接近用户的网络“边缘”(边缘服务器),使用户可以就近取得所需的内容,提高用户访问网站的响应速度。
分发的内容可分为静态内容和动态内容
静态内容不是一直保存在CDN里,源服务器发送文件给 CDN 时可以利用 HTTP 头部的 cache-control,利用缓存机制,CDN 可以知道哪些资源可以保存,哪些不能等
CDN 没有网站的源内容,因此源服务器就会把静态内容提前备份给CDN,也叫push,这样在世界各地用户需要访问网页的时候,就近的CDN服务器就会把静态内容提供给用户,不需要每次都去请求源服务器了。
如果源服务器没有把静态内容提前备份给CDN,那当用户访问网页时,CDN就得向源服务器索取相应的静态内容,也就是pull,源服务器还可以让CDN进行备份,CDN得到内容以后再提供给用户,因为有了备份,其他同时做出该请求的用户也可以立刻拿到内容。
动态内容用CDN来进行分发就很困难了,因为动态内容实会根据每个用户来改变的或者根据每个时间段来变化的,源服务器就很难提前预测到每个用户的动态内容,然后提前push到CDN。如果等用户索取动态内容,CDN再向源服务器索取,这跟直接向服务器请求没有太大差别,CDN提供不了多少加速服务,就没有太大的必要。
但还是有CDN可以提供服务,比如现在要获取动态的时间,有些CDN会提供可以运行在CDN上的接口,让源服务器用这些CDN的接口,而不是源服务器自己的代码,这样用户就可以直接从CDN上获取时间。
CDN的布局相当于无形中给源服务器和用户之间增加了一道墙,用户不再直接访问服务器了,而是通过CDN进行沟通,这样就不用担心恶意的DDos攻击。
CDN网络是在用户和服务器之间增加 Cache 层,主要是通过接管 DNS 实现,将用户的请求引导到 Cache 上获得源服务器的数据,从而降低网络的访问时间。
www.a.com
,操作系统向 LocalDns 查询域名的ip地址;www.a.com
的IP地址记录。如果有,则直接返回给终端用户;如果没有,则向 ROOT DNS 查询域名的授权服务器。如上图,是使用CDN缓存后的网络访问流程:
www.a.com
,操作系统向 LocalDns 查询域名的ip地址;www.a.com
的IP地址记录。如果有,则直接返回给终端用户;如果没有,则向 ROOT DNS 查询域名的授权服务器。从这个例子可以了解到:
(1)CDN 的加速资源是跟域名绑定的。
(2)通过域名访问资源,首先是通过 DNS 查找离用户最近的CDN节点(边缘服务器)的IP
(3)通过 IP 访问实际资源时,如果 CDN 上并没有缓存资源,则会到源站请求资源,并缓存到 CDN 节点上,这样,用户下一次访问时,该 CDN 节点就会有对应资源的缓存了。
CDN的出现又导致了攻击者可能攻击 CDN ,CDN宕机了怎么办。
多个CDN服务器布局在各个地方,然后监控CDN 服务器的负载状况,若是某个服务器超载了或宕机了,就会把用户的请求转移到没有超载的CDN服务器这边,以此来平均分配网络流量,也就是负载均衡。
CDN转移这些流量的方法和DNS根服务器的做法有着异曲同工之妙,用的是任播这种技术,使用了任播这种技术后,服务器对外拥有同样的IP地址,如果这个IP地址收到了用户的请求之后,请求就会由距离用户最近的服务器来响应
CDN还会采用TSL/SSL证书来给网站进行保护
CDN应用广泛,支持多种行业、多种场景内容加速,例如:图片小文件、大文件下载、视音频点播、直播流媒体、全站加速、安全加速。