点赞
评论
收藏
分享
举报
Nginx缓存详解(一)之客户端缓存
发表于2021-01-25 21:24

浏览 5.6k

文章标签

缓存的作用

缓存对于Web服务至关重要,尤其对于大型高负载Web站点。缓存作为性能优化的一个重要手段,可以在极大程度上减轻后端服务器的负载。通常对于静态资源,即不经常更新的资源,如图片,CSS或JS等进行缓存,而不用每次都向服务器请求,这样就可以减轻服务器的压力。

缓存的分类

缓存可以分为客户端缓存和服务端缓存。

  • 客户端缓存指的是浏览器缓存, 浏览器缓存是最快的缓存, 因为它直接从本地获取(但有可能需要发送一个协商缓存的请求), 它的优势是可以减少网络流量, 加快请求速度。

  • 服务端缓存指的是反向代理服务器或CDN的缓存, 他的作用是用于减轻后端实际的Web Server的压力。

浏览器缓存可以分为两种模式,强缓存和协商缓存。

  • 强缓存(无HTTP请求,无需协商)

    直接读取本地缓存,无需向服务端发送请求确认,HTTP返回状态码是200(from memory cache或者from disk cache ,不同浏览器返回的信息不一致的)。

    相关的HTTP Header有:

    • Cache-Control
    • Expires
  • 协商缓存(有HTTP请求,需协商)

    浏览器虽然发现了本地有该资源的缓存,但是缓存已经过期,于是向服务器询问缓存内容是否还可以使用,若服务器认为浏览器的缓存内容还可用,那么便会返回304(Not Modified)HTTP状态码,告诉浏览器读取本地缓存;如果服务器认为浏览器的缓存内容已经改变,则返回新的请求的资源。

    相关的HTTP Header有:

    • Last-Modified
    • ETag

缓存校验流程

由于网站内容的经常变化,为了保持缓存的内容与网站服务器的内容一致,客户端会通过内容缓存的有效期(强制缓存)以及Web服务器提供的访问请求的校验(协商缓存),快速判断请求的内容是否已经更新。客户端缓存校验流程图如下:

强制缓存

强制缓存原理: 浏览器在加载资源的时候,会先根据本地缓存资源的header中的信息(Expires 和 Cache-Control)来判断缓存是否过期。如果缓存没有过期,则会直接使用缓存中的资源;否则,会向服务端发起协商缓存的请求。

客户端判断缓存是否过期和先前请求时服务端返回的HTTP消息头字段有关:

服务端返回字段 作用
Cache-Control: max-age=x 客户端缓存时间超出x秒后则缓存过期。
Cache-Control: no-cache 客户端不能直接使用本地缓存的响应,需要进行协商缓存,发送请求到服务器确认是否可以使用缓存。如果Web服务器返回304,则客户端使用本地缓存,如果返回200,则使用Web服务器返回的新的数据。
Cache-Control: no-store 客户端不能对响应进行缓存。
Cache-Control: public 可以被所有的用户缓存,包括终端用户和 CDN 等中间代理服务器。
Cache-Control:private 只能被终端用户的浏览器缓存,不允许 CDN 等中继缓存服务器对其缓存。
expires x 客户端缓存时间超出x秒后则缓存过期,优先级比Cache-Control: max-age=x低。

协商缓存

协商缓存原理: 当客户端向服务端发起请求时,服务端会检查请求中是否有对应的标识(If-Modified-Since或Etag),如果没有对应的标识,服务器端会返回标识给客户端,客户端下次再次请求的时候,把该标识带过去,然后服务器端会验证该标识,如果验证通过了,则会响应304,告诉浏览器读取缓存。如果标识没有通过,则返回请求的资源。

Last-Modified与If-Modified-Since属于HTTP/1.0,是用于服务端对响应数据修改时间进行校验的服务端校验方法。Last-Modified的值是由服务端生成后传递给客户端的,客户端发送请求时,会将本地内容缓存中的Last-Modified的值由请求消息头的If-Modified-Since字段传递给服务端,如果服务端的被请求的内容的最后修改时间和If-Modified-Since的(默认是exact精确匹配)值不一致,则将返回新的内容,否则返回响应状态码304,客户端将使用本地缓存。

Etag与If-None-Match属于HTTP/1.1,优先级高于Last-Modified的验证,是用于服务端对响应数据进行实体标签校验的服务端校验方法。Etag类似于身份指纹,是一个可以与Web资源关联的记号。当客户端第一次发起请求时,Etag的值在响应头中传递给客户端;当客户端再次发起请求时,如果验证完本地内容缓存后需要发起服务端验证,Etag的值将由请求消息头的If-None-Match字段传递给服务端。如果服务端验证If-None-Match的值与服务端的Etag值不匹配,则认为请求的内容已经更新,服务端将会返回新的内容,否则返回响应状态码304,客户端将使用本地缓存。

下图可以看到客户端第一次请求时,客户端请求中没有If-Modified-Since和Etag标识,服务端响应了200,并且返回了Etag和Last-Modified消息头。

当第二次客户端请求时,带上了If-Modified-Since和If-None-Match消息头,并且服务端经过校验后返回了304让客户端使用本地缓存。

用户行为对浏览器缓存的影响

当按下F5或者刷新时,客户端浏览器会添加请求消息头字段Cache-Control: max-age=0,该请求不进行内容缓存的本地验证,会直接向Web服务器发起请求,服务端根据If-Modified-Since或者If-None-Match的值进行验证。

当按下Ctrl+F5或者强制刷新时,客户端浏览器会添加请求消息头字段Cache-Control: no-cache,并且忽略所有服务端验证的消息头字段(Etag和Last-Modified),该请求不进行内容缓存的本地验证,它会直接向Web服务器发起请求,因为请求中没有携带服务端验证的消息头字段,服务端会直接返回新的内容。

Cache-Control字段在请求和响应中的含义

客户端请求

  • max-age:不想要在代理服务器中缓存了太长时间(>max-age seconds)的资源。
  • max-stale:可以接收代理服务器上的过期缓存。若max-stable后没有值,则表示无论过期多久客户端都可以使用。
  • min-fresh:要求服务器使用其缓存时,至少保证在min-fresh秒内不会过期。
  • no-cache:告诉代理服务器,不能直接使用已有缓存作为响应返回,除非带着缓存条件到上游服务端得到 304 验证返回码才可使用现有缓存。
  • no-store:告诉各代理服务器不得缓存这个请求及其相应。
  • no-transform: 告诉代理服务器不要修改消息包体的内容。
  • only-if-cached:告诉代理服务器仅能返回缓存,没有缓存的话就返回 504。

服务端响应

  • max-age:告诉客户端缓存 Age 超出 max-age 秒后则缓存过期。
  • s-maxage:与max-age相似,但仅针对共享缓存,且优先级高于max-age和Expires。
  • public:可以被所有的用户缓存,包括终端用户和 CDN 等中间代理服务器。
  • private: 只能被终端用户的浏览器缓存,不允许 CDN 等中继缓存服务器对其缓存。
  • no-store:告诉所有下游节点不能对响应进行缓存。
  • no-cache: 告诉客户端不能直接使用缓存的响应,使用前必须在源服务器验证得到304返回码。
  • no-transform:告诉代理服务器不能修改消息包体的内容。
  • must-revalidate:告诉客户端一旦缓存过期,必须向服务器验证后才可使用。
  • proxy-revalidate:与 must-revalidate 类似,但它仅对代理服务器的共享缓存有效。
已修改于2023-03-06 17:06
本作品系原创
创作不易,留下一份鼓励
cr7258

暂无个人介绍

关注



写下您的评论
发表评论
全部评论(2)

按点赞数排序

按时间排序

很棒的文章

赞同

0

回复举报

发表于2022-01-10 14:37



回复星火燎愿
回复

好文章!

赞同

0

回复举报

发表于2021-02-16 14:31



回复皮皮鲁
回复
关于作者
cr7258
这家伙很懒还未留下介绍~
2
文章
0
问答
2
粉丝
相关文章
分布式系统提升可用性时,最有效的方案就是在空间维度上,将资源复制一份作为缓存,并把缓存放在离用户更近的地方。这样,通过缩短用户的访问路径,不只可以降低请求的时延,多份资源还能提升系统的健壮性。比如WEB服务中的CDN就是这样一个缓存系统。 Nginx由于具有下面3个特性,因此是最合适的缓存系统:l 首先,高并发、低延迟赋予了Nginx优秀的性能;l 其次,多进程架构让Nginx具备了很高的稳定性;l 最后,模块化的开源生态,以及从开放中诞生的Openresty、Kong等其他体系,这都让Nginx的功能丰富而强大。 所以,Nginx往往部署在企业最核心的边缘位置,在最外层的Nginx上部署共享缓存,能够给服务带来更大的收益,更短的访问路径带来了更佳的用户体验。然而,当整个系统的可用性极度依赖Nginx的缓存功能时,我们必须仔细地配置Nginx,还得使用到缓存的许多进阶功能。 比如,在超大流量下如果热点资源的缓存失效,那么在巨大的流量穿透Nginx缓存后,非常有可能把脆弱的上游服务打挂。此时合并回源请求功能,就是你的最佳应
点赞 12
浏览 6.2k
本文是我对2019年GOPS深圳站演讲的文字整理。这里我希望带给各位读者的是,如何站在整个互联网背景下系统化地理解Nginx,因为这样才能解决好大流量分布式网络所面临的高可用问题。标题里有“巧用”二字,何谓巧用?同一个问题会有很多种解决方案,但是,各自的约束性条件却大不相同。巧用就是找出最简单、最适合的方案,而做到这一点的前提就是必须系统化的理解Nginx!本文分四个部分讲清楚如何达到这一目的:首先要搞清楚我们面对的是什么问题。这里会谈下我对大规模分布式集群的理解;Nginx如何帮助集群实现可伸缩性;Nginx如何提高服务的性能;从Nginx的设计思路上学习如何用好它。1.大规模分布式集群的特点互联网是一个巨大的分布式网络,它有以下特点:多样化的客户端。网络中现存各种不同厂商、不同版本的浏览器,甚至有些用户还在使用非常古老的浏览器,而我们没有办法强制用户升级;多层代理。我们不知道用户发来的请求是不是通过代理翻墙过来的;多级缓存。请求链路上有很多级缓存,浏览器、正反向代理、CDN等都有缓存,怎么控制多级缓存?RFC规范中有明确的定义,但是有些Server并不完全遵守;不可控的流量风暴。
点赞 11
浏览 8.1k
1.nginx缓存原理及配置nginx的http_proxy模块,可以实现类似于squid的缓存功能。基于nginx静态缓存的解决方案:1.1nginxcache的基本配置proxy_cache_path/data/nginx/cache_itemlevels=1:1:2keys_zone=cache_item:10mmax_size=10ginactive=60m; server{         location~\.(gif|jpg|jpeg|png|bmp|ico)${ proxy_set_headerHost$host; proxy_set_headerX-Forwarded-For$remote_addr; proxy_passhttp://127.0.0.1:8080;              proxy_cachecache_item;               
点赞 3
浏览 6.6k