透视 HTTP 协议
罗剑锋(Chrono)
前奇虎 360 技术专家,Nginx/OpenResty 开源项目贡献者
63943 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 48 讲
开篇词 (1讲)
透视 HTTP 协议
15
15
1.0x
00:00/00:00
登录|注册

22 | 冷链周转:HTTP的缓存代理

only-if-cached
min-fresh
max-stale
no-cache
no-store
max-age
为报文加上"Last-modified"或"ETag"字段
no-transform
s-maxage
proxy-revalidate
must-revalidate
no-cache
no-store
max-age
既不是客户端又不是服务器
既是客户端又是服务器
提升用户体验
节约带宽
减少响应时间
2. 缓存的时间策略
1. 画出有缓存代理时浏览器的工作流程图
缓存代理可能带来负面影响
"Cache-Control"字段控制缓存代理
缓存代理增加了缓存功能
HTTP缓存属于"空间换时间"
Purge功能
Vary字段
客户端的"Cache-Control"属性
重要性
服务器端的"Cache-Control"属性
缓存代理的特殊身份
缓存代理的作用
课下作业
小结
其他问题
客户端的缓存控制
源服务器的缓存控制
缓存代理服务
HTTP缓存代理

该思维导图由 AI 生成,仅供参考

第 20 讲中,我介绍了 HTTP 的缓存控制,第 21 讲我介绍了 HTTP 的代理服务。那么,把这两者结合起来就是这节课所要说的“缓存代理”,也就是支持缓存控制的代理服务。
之前谈到缓存时,主要讲了客户端(浏览器)上的缓存控制,它能够减少响应时间、节约带宽,提升客户端的用户体验。
但 HTTP 传输链路上,不只是客户端有缓存,服务器上的缓存也是非常有价值的,可以让请求不必走完整个后续处理流程,“就近”获得响应结果。
特别是对于那些“读多写少”的数据,例如突发热点新闻、爆款商品的详情页,一秒钟内可能有成千上万次的请求。即使仅仅缓存数秒钟,也能够把巨大的访问流量挡在外面,让 RPS(request per second)降低好几个数量级,减轻应用服务器的并发压力,对性能的改善是非常显著的。
HTTP 的服务器缓存功能主要由代理服务器来实现(即缓存代理),而源服务器系统内部虽然也经常有各种缓存(如 Memcache、Redis、Varnish 等),但与 HTTP 没有太多关系,所以这里暂且不说。

缓存代理服务

我还是沿用“生鲜速递 + 便利店”的比喻,看看缓存代理是怎么回事。
便利店作为超市的代理,生意非常红火,顾客和超市双方都对现状非常满意。但时间一长,超市发现还有进一步提升的空间,因为每次便利店接到顾客的请求后都要专车跑一趟超市,还是挺麻烦的。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

HTTP缓存代理在传输链路中扮演着重要角色,通过缓存代理可实现快速响应和节约带宽。文章以生鲜冷链周转为比喻,生动介绍了缓存代理的工作原理。缓存代理既是客户端又是服务器,需使用特定的缓存控制属性约束其行为。服务器端引入了private和public等新属性,客户端则需区别对待代理和源服务器,引入了max-stale和min-fresh等新属性。实验环境通过URI“/22-1”进行实验,以便读者更直观了解缓存代理的工作情况。文章深入浅出地介绍了HTTP的缓存代理原理和相关技术特点,对于深入了解该领域的读者具有很高的参考价值。此外,文章还简要介绍了Vary字段和Purge功能,强调了缓存代理的重要性和清理方法。总结时空转换、缓存代理的功能、Cache-Control字段的控制、以及缓存代理可能带来的负面影响。建议读者通过整理知识、绘制浏览器工作流程图和思考缓存时间策略来加深理解。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《透视 HTTP 协议》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(36)

  • 最新
  • 精选
  • Teresa
    针对作业一的回答: 浏览器拿到一个网址的时候,先判断是否允许缓存,允许会先查看本地缓存: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个赞!

    2020-04-27
    3
    158
  • 首先,老师的敬业精神令人钦佩,几乎每问必答,再者,没有给人一种你怎么这么笨这么简单的问题你还问的感受,而且看到有些地方不严谨也会干净利索的说自己可能弄错了。是个经验丰富技术精干为人真诚的大哥形象,工作或生活中有这样的朋友或大哥是一件很幸运的事情。 缓存的时间策略很重要,太大太小都不好,你觉得应该如何设置呢? 我觉得需要根据具体情况来定: 如果缓存的内容不变,那可以把缓存时间设置为永久。 如果缓存的内容会变化,但周期较长,可以根据她的变化周期来设置,比如:一天或一周 如果缓存的内容变化频繁,那缓存的过期时间就需要更短了,比如:一分钟 如果缓存的内容随时变化,且没啥规律,那还是不用用了 总之是根据场景来的核心是在提速的愿望能实现的前提下,数据也是最新的,否则不如不用缓存,从另一个角度来讲不用缓存几乎是不可能的,缓存在处处使用着,因为计算机本身就在各种各样的使用着缓存。如果完全不用直接从磁盘获取数据,也可以认为是使用缓存的一种特殊情况,缓存的过期时间为零即使即过期。

    作者回复: 1.我的缺点就是太实在,所以一直只能当小兵,当不了boss,笑。 2.从http的缓存里也可以学到很多通用的知识,用在系统的其他地方也是可以的,所以说学习协议对程序员真的是一个基本功。

    2020-03-30
    3
    33
  • 龙宝宝
    max-stale相当于延长了过期时间,min-fresh相当于缩短了过期时间,可以这样理解吗

    作者回复: 可以这么理解,也是一个很好的角度。

    2019-07-29
    3
    32
  • 院长。
    老师您好,我想请问一下,为什么有的地方说cache-control默认是private(比如cache-control的百度百科),有的地方说默认是public(比如您这篇文章),是百度百科的是错误的吗?还是根据场景不同所以默认不同吗?

    作者回复: 我看了一下rfc,对于private和public没有明确的默认值说法,可能是我弄错了,需要再测试看看。

    2019-07-17
    2
    15
  • magict4
    老师您好, 我想问一下,现在大多数网站都开启了 HTTPS,缓存代理还有用武之地吗?我对 HTTPS 的理解是它是端到端加密。介于客户端与服务器中间的缓存服务器是没法解密,缓存数据的。

    作者回复: 这个需要看缓存代理怎么配置了。 如果它在四层,只是转发,看不到https的内容,就无法缓存。 如果它在七层,本身实际上也是一个客户端,能够与后端通信看到https的内容,就可以缓存。

    2021-06-06
    14
  •        鸟人
    请问时间换空间是什么呢?

    作者回复: 比如数据压缩,就是时间换空间,增加了计算时间,减少了数据量。

    2019-07-29
    8
  • ttsunami
    代理服务器真的那么听话吗? 源给个private,结果自己却偷偷做一些操作也可以吧?如何验证代理服务器的处理是否夹带私心呢? 纯靠自觉吗? 哈哈 颇有 将在外军令有所不受的味道

    作者回复: 说的很对,http不是强制性的规范,代理不遵守也是完全可以的,如果有私下操作我们也很难判断出来,http本身没有这方面的要求。

    2020-06-10
    6
  • 闫飞
    min-fresh的含义是距离过期时间必须不短于约定的时间,保证取到的是短期内不会过时的内容。 但是这里有个风险是,万一服务器端因为某些原因重新刷新了资源(服务迁移等),那么怎么反向通知缓存服务器去清理资源呢?尤其是已经返回给客户端的之前标记为fresh的资源?

    作者回复: http协议里没有对此做出规定,一般的做法是由源站向代理发送pull请求,要求代理主动更新缓存。 这个pull请求不属于http协议,具体实现就看两者之间的约定了。

    2019-07-18
    6
  • 何用
    老师,CDN 服务是不是就是缓存代理的一种应用?还有文中图片的 X-Accel 是什么意思呢?

    作者回复: 1,是的。 2. X-Accel是自定义字段,和x-powered-by差不多,意思是被谁加速。

    2019-07-17
    5
  • 乘风破浪
    “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意思是客户端可以到存储在代理服务器上的缓存做验证,私有缓存必须回源,其他不必回源。 同时代理服务器上的缓存失效了当然也必须回源验证。 表述上稍微有点绕,抱歉。

    2021-04-03
    4
收起评论
显示
设置
留言
36
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部