22 | 冷链周转:HTTP的缓存代理
22 | 冷链周转:HTTP的缓存代理
讲述:Chrono
时长10:38大小12.16M
缓存代理服务
源服务器的缓存控制
客户端的缓存控制
实验环境
其他问题
小结
课下作业
赞 21
提建议
精选留言(36)
- Teresa2020-04-27针对作业一的回答: 浏览器拿到一个网址的时候,先判断是否允许缓存,允许会先查看本地缓存:1.有缓存并在缓存可用期那直接拿来用。2.缓存不存在或者不可用 那需要请求。 浏览器拿到host,判断:1.ip+port 那直接请求对应的服务器 2.域名 那开展一系列的dns递归查询:先拿dns缓存,没有缓存->本地dns服务器->根dns服务器->顶级dns服务器->权威dns服务器->GSLB,查到ip返回最优ip组实现负载均衡,浏览器随机或者轮询取一个ip开始它的http请求之旅。 浏览器判断该网页是否允许缓存,然后添加Cache-Control的各种字段no-store是否允许缓存/no-cache缓存必须进行验证/noly-if-cached只接受代理的缓存等,max-age最大生存时间 max-stale 短时间过期可用 min-fresh 最短有效时间等。If-Modified-Since/if-None-Match/Last-modified/ETag等字段用于判断服务端是否有更新。然后将请求发给代理服务器。请求代理服务器,如果是第一次,要经历浏览器和代理服务器的3次tcp握手进行连接,连接成功,发送http请求。 代理服务器拿到请求,首先查看是否允许缓存,允许那就查看自己本地缓存有没有,通过查看max-age/max-stale/min-fresh等信息判断是否过期,没有过期直接拿来用,将数据返回给客户端。如果过期了,代理服务器将用客户端的请求,再次像真实服务器进行请求。如果也是第一次连接,需要经历代理服务器和真实服务器的3次tcp握手,连接成功,发送请求。 真实服务器收到请求之后,通过if-Modified-Since/Last-Modified/if-None-Match/ETag等字段判断是否有更新,没有更新,直接返回304。如果有更新,则将数据打包http response 返回。返回头字段会添加Cache-Control字段,用来判断缓存的控制策略以及生存周期,no-store不允许缓存/no-cache使用缓存必须先验证/must-revalidate缓存不过期可用过期必须重新请求验证/proxy-revalidate缓存过期只要求代理进行请求验证 private不能在代理层保存只能在客户端保存/public缓存完全开放 s-maxage缓存在代理上可以缓存的时间 no-transform不允许代理对缓存做任何的改动。然后根据业务需求判断该地址是不是需要重定向,如果需要是短期的重定向还是永久的重定向,按需将状态码修改为301或者302。最后真实服务器将数据打包成http相应 回给代理服务器。 代理服务器收到真实服务器的回应数据,首先会查看Cache-Control里的字段,是否允许它进行缓存,如果是private,代理服务器不进行缓存,直接返回给客户端。public则根据s-maxage/no-transform进行缓存,如果可以优化并且代理服务器需要优化,那可能会先优化数据,否则同时将数据回发给客户端。 客户端收到数据,如果是304,则直接拿缓存数据进行渲染,并修改相关缓存变量,比如时间,以及缓存使用策略。如果收到了301或者302,那么客户端会再次发起新的url请求,进行跳转到最终的页面。 最后,底层tcp 经过4次挥手,完成关闭连接。展开
作者回复: 整理的非常详细完整,32个赞!
共 3 条评论148 - 龙宝宝2019-07-29max-stale相当于延长了过期时间,min-fresh相当于缩短了过期时间,可以这样理解吗
作者回复: 可以这么理解,也是一个很好的角度。
共 3 条评论30 - 钱2020-03-30首先,老师的敬业精神令人钦佩,几乎每问必答,再者,没有给人一种你怎么这么笨这么简单的问题你还问的感受,而且看到有些地方不严谨也会干净利索的说自己可能弄错了。是个经验丰富技术精干为人真诚的大哥形象,工作或生活中有这样的朋友或大哥是一件很幸运的事情。 缓存的时间策略很重要,太大太小都不好,你觉得应该如何设置呢? 我觉得需要根据具体情况来定: 如果缓存的内容不变,那可以把缓存时间设置为永久。 如果缓存的内容会变化,但周期较长,可以根据她的变化周期来设置,比如:一天或一周 如果缓存的内容变化频繁,那缓存的过期时间就需要更短了,比如:一分钟 如果缓存的内容随时变化,且没啥规律,那还是不用用了 总之是根据场景来的核心是在提速的愿望能实现的前提下,数据也是最新的,否则不如不用缓存,从另一个角度来讲不用缓存几乎是不可能的,缓存在处处使用着,因为计算机本身就在各种各样的使用着缓存。如果完全不用直接从磁盘获取数据,也可以认为是使用缓存的一种特殊情况,缓存的过期时间为零即使即过期。展开
作者回复: 1.我的缺点就是太实在,所以一直只能当小兵,当不了boss,笑。 2.从http的缓存里也可以学到很多通用的知识,用在系统的其他地方也是可以的,所以说学习协议对程序员真的是一个基本功。
共 3 条评论29 - 院长。2019-07-17老师您好,我想请问一下,为什么有的地方说cache-control默认是private(比如cache-control的百度百科),有的地方说默认是public(比如您这篇文章),是百度百科的是错误的吗?还是根据场景不同所以默认不同吗?
作者回复: 我看了一下rfc,对于private和public没有明确的默认值说法,可能是我弄错了,需要再测试看看。
共 2 条评论15 - magict42021-06-06老师您好, 我想问一下,现在大多数网站都开启了 HTTPS,缓存代理还有用武之地吗?我对 HTTPS 的理解是它是端到端加密。介于客户端与服务器中间的缓存服务器是没法解密,缓存数据的。
作者回复: 这个需要看缓存代理怎么配置了。 如果它在四层,只是转发,看不到https的内容,就无法缓存。 如果它在七层,本身实际上也是一个客户端,能够与后端通信看到https的内容,就可以缓存。
9 - 鸟人2019-07-29请问时间换空间是什么呢?
作者回复: 比如数据压缩,就是时间换空间,增加了计算时间,减少了数据量。
7 - ttsunami2020-06-10代理服务器真的那么听话吗? 源给个private,结果自己却偷偷做一些操作也可以吧?如何验证代理服务器的处理是否夹带私心呢? 纯靠自觉吗? 哈哈 颇有 将在外军令有所不受的味道
作者回复: 说的很对,http不是强制性的规范,代理不遵守也是完全可以的,如果有私下操作我们也很难判断出来,http本身没有这方面的要求。
6 - 闫飞2019-07-18min-fresh的含义是距离过期时间必须不短于约定的时间,保证取到的是短期内不会过时的内容。 但是这里有个风险是,万一服务器端因为某些原因重新刷新了资源(服务迁移等),那么怎么反向通知缓存服务器去清理资源呢?尤其是已经返回给客户端的之前标记为fresh的资源?
作者回复: http协议里没有对此做出规定,一般的做法是由源站向代理发送pull请求,要求代理主动更新缓存。 这个pull请求不属于http协议,具体实现就看两者之间的约定了。
6 - 何用2019-07-17老师,CDN 服务是不是就是缓存代理的一种应用?还有文中图片的 X-Accel 是什么意思呢?
作者回复: 1,是的。 2. X-Accel是自定义字段,和x-powered-by差不多,意思是被谁加速。
5 - Geek_steven_wang2019-08-23如果cache-control中没有 no-store no-cache must-revalidate这时浏览器会怎么处理? Max-stale min-fresh 那个优先级高,如果两个都有,那个生效?
作者回复: 1.没有这些就按普通的缓存策略来处理,在有效期内直接用,过期发条件请求。 2.这两个属性本身就是冲突的,如果同时给出,那就由服务器自己决定策略了,rfc本身没有对此做出规定。
4 - 徐海浪2019-07-17我们的做法是源服务器跟代理服务器联动,源服务器有文件变化(版本发布),触发更新代理服务器缓存。如果没有联动的机制,简单粗暴根据应用升级周期设置过期时间也可以,但这样会多做无用功。
作者回复: 欢迎经验分享!
共 2 条评论4 - 居培波2019-07-17老师能结合nginx讲下缓存及代理吗?还是后面探索篇有讲。
作者回复: 只要理解的http的缓存代理,nginx的是比较容易掌握的,可以结合nginx的文档,看proxy相关的指令,逐条对照http的功能。 单纯讲nginx就有点太大了,讲不过来。
4 - 乘风破浪2021-04-03“must-revalidate”是只要过期就必须回源服务器验证,而新的“proxy-revalidate”只要求代理的缓存过期后必须验证,客户端不必回源,只验证到代理这个环节就行了。 看了一下MDN关于这两个头字段的解释 must-revalidate Indicates that once a resource becomes stale, caches must not use their stale copy without successful validation on the origin server. proxy-revalidate Like must-revalidate, but only for shared caches (e.g., proxies). Ignored by private caches. 感觉MDN说的proxy-revalidate的意思似乎是对于存储在代理服务器上的共享缓存的验证策略,如果过期,必须回源验真,而不是说客户端的缓存【私有缓存】失效后回源到代理服务器验证。 而这也反过来推论,must-revalidate是向上游服务器验证cache,验证不一定回源到源服务器。 ---请大师指正。。展开
作者回复: 我又仔细看了一下rfc7234,感觉是我没有太表述清楚。 proxy-revalidate意思是客户端可以到存储在代理服务器上的缓存做验证,私有缓存必须回源,其他不必回源。 同时代理服务器上的缓存失效了当然也必须回源验证。 表述上稍微有点绕,抱歉。
3 - 旅途2020-08-12我还要提醒你一点,源服务器在设置完“Cache-Control”后必须要为报文加上“Last-modified”或“ETag”字段。否则,客户端和代理后面就无法使用条件请求来验证缓存是否有效,也就不会有 304 缓存重定向 老师 这句话 没理解 能再说下吗
作者回复: “Cache-Control”字段最好和“Last-modified”或“ETag”字段搭配使用,这样客户端就可以更好地利用缓存,用条件请求来验证缓存是否有效。 如果只有“Cache-Control”,没有“Last-modified”或“ETag”,那么客户端在缓存失效后就无法发出条件请求,就得重新传一遍内容,浪费了带宽。
3 - lesserror2019-12-101. 老师,我看那个完整的服务器端缓存控制策略图,在图上no-cache和must-revalidate两个一般只能存在一个吧?不能同时传递。 2. 还有:“比较常用的一种做法是使用自定义请求方法“PURGE””,意思是自己在代码里面写个方法处理缓存的数据,对吧?
作者回复: 1.是的。 2.没错,http允许自定义请求方法和处理逻辑。
1 - Geek_steven_wang2019-08-221. 文中第一张图服务器缓存控制,其实是服务器根据缓存策略向response中插入各header的过程,缓存服务器,浏览器根据header处理缓存。 2. 文中客户端缓存过程中,是浏览器根据自己的缓存策略,向服务器发请求时,设置各header。但这些策略浏览器怎么知道呢?是用户通过浏览器设置界面设置吗?还是ajax请求时设置?如果不是前后端分类的应用,怎么设置这些header? 3. 既然服务器端有自己的缓存策略,那客户端请求上来时,服务器会根据客户端请求header调整策略吗?如果会,是应用服务器自己处理,还是程序员代码预先写好处理逻辑? 4. 什么情况下客户端会有only-if-cached展开
作者回复: 1.正确。 2.http客户端有很多种,浏览器只是其中之一,如果用Python、php自己写客户端,那就可以使用这些缓存策略。 浏览器通常有一些最基本的策略,而ajax等就可以自己灵活设置。 3.服务器控制资源和缓存,它会检查请求资源的有效期,与客户端的请求比对,返回304或者是新的内容,应用服务器和应用服务器都可以设置。 4.only-if-cached这个我也没有见过具体的应用场景,但既然有这个属性,就应该是有用的。
共 2 条评论1 - 一步2019-07-17老师请教一个有关302的问题,就是再前端代码中有个post请求,去请求后端服务器,当后端服务器处理完业务逻辑后,需要重定向到另一个网站,返回的是一个302的状态码和响应头Location是另一个网站地址。这时候问题出现了,当返回到前端的时候,浏览器没有自动跳转重定向后的地址,而是当作接口去请求了需要跳转后的地址,然后就出现了跨域的问题 这个是什么原因呢?展开
作者回复: 可以参考一下第18讲,改用303 see other。
1 - djfhchdh2019-07-17max-stale和min-fresh还是不太明白~~
作者回复: max-stale是可以接受的过期时间,min-fresh是可以接受的新鲜时间。 不好理解也没事,这两个属性用的不多,可以以后实际遇到了再体会。
1 - ifelse2023-01-28 来自浙江HTTP 的服务器缓存功能主要由代理服务器来实现(即缓存代理),而源服务器系统内部虽然也经常有各种缓存(如 Memcache、Redis、Varnish 等),但与 HTTP 没有太多关系。--记下来
作者回复: very nice
1 - KaKaKa2022-10-17 来自北京老师,看到评论有这样一个问题,我也好奇 【作者回复: 1.max-age不能用在请求头里,只能在响应头里指定资源的有效期。】这句我有点疑问,在第20讲里,在客户端的缓存控制里,您说了,【当你点“刷新”按钮的时候,浏览器会在请求头里加一个“Cache-Control: max-age=0”。】
作者回复: 啊,看来是头字段太多,连我自己有时候也会弄糊涂,非常抱歉。