读《图解HTTP》:代理、网关、隧道与缓存到底是什么?
本文是阅读《图解HTTP》第 5 章后的学习整理,结合个人理解做了少量补充。文中的流程图和表格用于概括本章概念,不使用原书截图,也不替代原书内容。
这篇文章解决什么问题
我们平时访问一个网站时,直觉上会以为浏览器直接连到了目标服务器。实际情况往往更复杂:请求可能先经过代理服务器,也可能经过网关、隧道、缓存服务器,最后才到达真正保存资源的服务器。
这一章主要讨论的就是这些与 HTTP 协作的 Web 服务器组件:
- 一台服务器如何承载多个网站:虚拟主机
- HTTP 请求在中途可能遇到哪些角色:代理、网关、隧道
- 为什么缓存能减少访问源服务器的次数
- 缓存服务器和客户端缓存分别是什么
一台服务器为什么能放多个网站:虚拟主机
HTTP/1.1 允许一台 HTTP 服务器搭建多个 Web 站点。物理上可能只有一台服务器,但使用虚拟主机功能后,表面上可以像多台服务器一样,分别承载不同域名的网站。
问题在于:多个域名经过 DNS 解析后,可能指向同一个 IP 地址。当请求到达服务器时,服务器需要知道客户端到底想访问哪个域名下的网站。
这个判断依赖 HTTP 请求中的 Host 首部。
http
GET /index.html HTTP/1.1
Host: blog.example.com
可以把虚拟主机的访问过程理解成这样:
#mermaid-svg-G6fUJNIMDLPAfjrL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-G6fUJNIMDLPAfjrL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-G6fUJNIMDLPAfjrL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-G6fUJNIMDLPAfjrL .error-icon{fill:#552222;}#mermaid-svg-G6fUJNIMDLPAfjrL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-G6fUJNIMDLPAfjrL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-G6fUJNIMDLPAfjrL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-G6fUJNIMDLPAfjrL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-G6fUJNIMDLPAfjrL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-G6fUJNIMDLPAfjrL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-G6fUJNIMDLPAfjrL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-G6fUJNIMDLPAfjrL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-G6fUJNIMDLPAfjrL .marker.cross{stroke:#333333;}#mermaid-svg-G6fUJNIMDLPAfjrL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-G6fUJNIMDLPAfjrL p{margin:0;}#mermaid-svg-G6fUJNIMDLPAfjrL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-G6fUJNIMDLPAfjrL .cluster-label text{fill:#333;}#mermaid-svg-G6fUJNIMDLPAfjrL .cluster-label span{color:#333;}#mermaid-svg-G6fUJNIMDLPAfjrL .cluster-label span p{background-color:transparent;}#mermaid-svg-G6fUJNIMDLPAfjrL .label text,#mermaid-svg-G6fUJNIMDLPAfjrL span{fill:#333;color:#333;}#mermaid-svg-G6fUJNIMDLPAfjrL .node rect,#mermaid-svg-G6fUJNIMDLPAfjrL .node circle,#mermaid-svg-G6fUJNIMDLPAfjrL .node ellipse,#mermaid-svg-G6fUJNIMDLPAfjrL .node polygon,#mermaid-svg-G6fUJNIMDLPAfjrL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-G6fUJNIMDLPAfjrL .rough-node .label text,#mermaid-svg-G6fUJNIMDLPAfjrL .node .label text,#mermaid-svg-G6fUJNIMDLPAfjrL .image-shape .label,#mermaid-svg-G6fUJNIMDLPAfjrL .icon-shape .label{text-anchor:middle;}#mermaid-svg-G6fUJNIMDLPAfjrL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-G6fUJNIMDLPAfjrL .rough-node .label,#mermaid-svg-G6fUJNIMDLPAfjrL .node .label,#mermaid-svg-G6fUJNIMDLPAfjrL .image-shape .label,#mermaid-svg-G6fUJNIMDLPAfjrL .icon-shape .label{text-align:center;}#mermaid-svg-G6fUJNIMDLPAfjrL .node.clickable{cursor:pointer;}#mermaid-svg-G6fUJNIMDLPAfjrL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-G6fUJNIMDLPAfjrL .arrowheadPath{fill:#333333;}#mermaid-svg-G6fUJNIMDLPAfjrL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-G6fUJNIMDLPAfjrL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-G6fUJNIMDLPAfjrL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-G6fUJNIMDLPAfjrL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-G6fUJNIMDLPAfjrL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-G6fUJNIMDLPAfjrL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-G6fUJNIMDLPAfjrL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-G6fUJNIMDLPAfjrL .cluster text{fill:#333;}#mermaid-svg-G6fUJNIMDLPAfjrL .cluster span{color:#333;}#mermaid-svg-G6fUJNIMDLPAfjrL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-G6fUJNIMDLPAfjrL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-G6fUJNIMDLPAfjrL rect.text{fill:none;stroke-width:0;}#mermaid-svg-G6fUJNIMDLPAfjrL .icon-shape,#mermaid-svg-G6fUJNIMDLPAfjrL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-G6fUJNIMDLPAfjrL .icon-shape p,#mermaid-svg-G6fUJNIMDLPAfjrL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-G6fUJNIMDLPAfjrL .icon-shape .label rect,#mermaid-svg-G6fUJNIMDLPAfjrL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-G6fUJNIMDLPAfjrL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-G6fUJNIMDLPAfjrL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-G6fUJNIMDLPAfjrL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 域名 A
DNS 解析到同一台服务器
域名 B
HTTP 请求携带 Host 首部
服务器根据 Host 区分目标网站
所以,虚拟主机的核心不是"一台机器真的变成了多台机器",而是服务器根据请求里的 Host 首部,把同一个 IP 上的不同域名区分开。
HTTP 请求路上的中间角色
HTTP 通信时,除了客户端和服务器,还可能存在一些用于转发通信数据的应用程序。书中重点介绍了三类:代理、网关、隧道。
它们都可以把请求转发给通信线路上的下一站服务器,也可以接收下一站服务器返回的响应,再转发给客户端。
代理:替客户端转发请求
代理是一种有转发功能的应用程序,扮演客户端和服务器之间的"中间人"角色。
它的基本行为是:
#mermaid-svg-vA52Y3XNmz8bfd5Y{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-vA52Y3XNmz8bfd5Y .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-vA52Y3XNmz8bfd5Y .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-vA52Y3XNmz8bfd5Y .error-icon{fill:#552222;}#mermaid-svg-vA52Y3XNmz8bfd5Y .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vA52Y3XNmz8bfd5Y .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-vA52Y3XNmz8bfd5Y .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vA52Y3XNmz8bfd5Y .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vA52Y3XNmz8bfd5Y .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-vA52Y3XNmz8bfd5Y .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vA52Y3XNmz8bfd5Y .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vA52Y3XNmz8bfd5Y .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vA52Y3XNmz8bfd5Y .marker.cross{stroke:#333333;}#mermaid-svg-vA52Y3XNmz8bfd5Y svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vA52Y3XNmz8bfd5Y p{margin:0;}#mermaid-svg-vA52Y3XNmz8bfd5Y .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-vA52Y3XNmz8bfd5Y .cluster-label text{fill:#333;}#mermaid-svg-vA52Y3XNmz8bfd5Y .cluster-label span{color:#333;}#mermaid-svg-vA52Y3XNmz8bfd5Y .cluster-label span p{background-color:transparent;}#mermaid-svg-vA52Y3XNmz8bfd5Y .label text,#mermaid-svg-vA52Y3XNmz8bfd5Y span{fill:#333;color:#333;}#mermaid-svg-vA52Y3XNmz8bfd5Y .node rect,#mermaid-svg-vA52Y3XNmz8bfd5Y .node circle,#mermaid-svg-vA52Y3XNmz8bfd5Y .node ellipse,#mermaid-svg-vA52Y3XNmz8bfd5Y .node polygon,#mermaid-svg-vA52Y3XNmz8bfd5Y .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-vA52Y3XNmz8bfd5Y .rough-node .label text,#mermaid-svg-vA52Y3XNmz8bfd5Y .node .label text,#mermaid-svg-vA52Y3XNmz8bfd5Y .image-shape .label,#mermaid-svg-vA52Y3XNmz8bfd5Y .icon-shape .label{text-anchor:middle;}#mermaid-svg-vA52Y3XNmz8bfd5Y .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-vA52Y3XNmz8bfd5Y .rough-node .label,#mermaid-svg-vA52Y3XNmz8bfd5Y .node .label,#mermaid-svg-vA52Y3XNmz8bfd5Y .image-shape .label,#mermaid-svg-vA52Y3XNmz8bfd5Y .icon-shape .label{text-align:center;}#mermaid-svg-vA52Y3XNmz8bfd5Y .node.clickable{cursor:pointer;}#mermaid-svg-vA52Y3XNmz8bfd5Y .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-vA52Y3XNmz8bfd5Y .arrowheadPath{fill:#333333;}#mermaid-svg-vA52Y3XNmz8bfd5Y .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-vA52Y3XNmz8bfd5Y .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-vA52Y3XNmz8bfd5Y .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vA52Y3XNmz8bfd5Y .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-vA52Y3XNmz8bfd5Y .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vA52Y3XNmz8bfd5Y .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-vA52Y3XNmz8bfd5Y .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-vA52Y3XNmz8bfd5Y .cluster text{fill:#333;}#mermaid-svg-vA52Y3XNmz8bfd5Y .cluster span{color:#333;}#mermaid-svg-vA52Y3XNmz8bfd5Y div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-vA52Y3XNmz8bfd5Y .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-vA52Y3XNmz8bfd5Y rect.text{fill:none;stroke-width:0;}#mermaid-svg-vA52Y3XNmz8bfd5Y .icon-shape,#mermaid-svg-vA52Y3XNmz8bfd5Y .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vA52Y3XNmz8bfd5Y .icon-shape p,#mermaid-svg-vA52Y3XNmz8bfd5Y .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-vA52Y3XNmz8bfd5Y .icon-shape .label rect,#mermaid-svg-vA52Y3XNmz8bfd5Y .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vA52Y3XNmz8bfd5Y .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-vA52Y3XNmz8bfd5Y .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-vA52Y3XNmz8bfd5Y :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 请求
不改变请求 URI,转发请求
响应
响应
客户端
代理服务器
源服务器
持有资源实体的服务器被称为源服务器。代理从客户端接收请求后,会把请求转发给前方持有资源的目标服务器;源服务器返回的响应也会先经过代理,再传给客户端。
在 HTTP 通信中,可以级联多台代理服务器。每次通过代理转发请求或响应时,需要追加 Via 首部,用来标记经过的主机信息。
#mermaid-svg-SzcZQbDHJMHvMoCh{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-SzcZQbDHJMHvMoCh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-SzcZQbDHJMHvMoCh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-SzcZQbDHJMHvMoCh .error-icon{fill:#552222;}#mermaid-svg-SzcZQbDHJMHvMoCh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-SzcZQbDHJMHvMoCh .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-SzcZQbDHJMHvMoCh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-SzcZQbDHJMHvMoCh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-SzcZQbDHJMHvMoCh .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-SzcZQbDHJMHvMoCh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-SzcZQbDHJMHvMoCh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-SzcZQbDHJMHvMoCh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-SzcZQbDHJMHvMoCh .marker.cross{stroke:#333333;}#mermaid-svg-SzcZQbDHJMHvMoCh svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-SzcZQbDHJMHvMoCh p{margin:0;}#mermaid-svg-SzcZQbDHJMHvMoCh .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-SzcZQbDHJMHvMoCh .cluster-label text{fill:#333;}#mermaid-svg-SzcZQbDHJMHvMoCh .cluster-label span{color:#333;}#mermaid-svg-SzcZQbDHJMHvMoCh .cluster-label span p{background-color:transparent;}#mermaid-svg-SzcZQbDHJMHvMoCh .label text,#mermaid-svg-SzcZQbDHJMHvMoCh span{fill:#333;color:#333;}#mermaid-svg-SzcZQbDHJMHvMoCh .node rect,#mermaid-svg-SzcZQbDHJMHvMoCh .node circle,#mermaid-svg-SzcZQbDHJMHvMoCh .node ellipse,#mermaid-svg-SzcZQbDHJMHvMoCh .node polygon,#mermaid-svg-SzcZQbDHJMHvMoCh .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-SzcZQbDHJMHvMoCh .rough-node .label text,#mermaid-svg-SzcZQbDHJMHvMoCh .node .label text,#mermaid-svg-SzcZQbDHJMHvMoCh .image-shape .label,#mermaid-svg-SzcZQbDHJMHvMoCh .icon-shape .label{text-anchor:middle;}#mermaid-svg-SzcZQbDHJMHvMoCh .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-SzcZQbDHJMHvMoCh .rough-node .label,#mermaid-svg-SzcZQbDHJMHvMoCh .node .label,#mermaid-svg-SzcZQbDHJMHvMoCh .image-shape .label,#mermaid-svg-SzcZQbDHJMHvMoCh .icon-shape .label{text-align:center;}#mermaid-svg-SzcZQbDHJMHvMoCh .node.clickable{cursor:pointer;}#mermaid-svg-SzcZQbDHJMHvMoCh .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-SzcZQbDHJMHvMoCh .arrowheadPath{fill:#333333;}#mermaid-svg-SzcZQbDHJMHvMoCh .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-SzcZQbDHJMHvMoCh .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-SzcZQbDHJMHvMoCh .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-SzcZQbDHJMHvMoCh .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-SzcZQbDHJMHvMoCh .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-SzcZQbDHJMHvMoCh .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-SzcZQbDHJMHvMoCh .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-SzcZQbDHJMHvMoCh .cluster text{fill:#333;}#mermaid-svg-SzcZQbDHJMHvMoCh .cluster span{color:#333;}#mermaid-svg-SzcZQbDHJMHvMoCh div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-SzcZQbDHJMHvMoCh .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-SzcZQbDHJMHvMoCh rect.text{fill:none;stroke-width:0;}#mermaid-svg-SzcZQbDHJMHvMoCh .icon-shape,#mermaid-svg-SzcZQbDHJMHvMoCh .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-SzcZQbDHJMHvMoCh .icon-shape p,#mermaid-svg-SzcZQbDHJMHvMoCh .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-SzcZQbDHJMHvMoCh .icon-shape .label rect,#mermaid-svg-SzcZQbDHJMHvMoCh .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-SzcZQbDHJMHvMoCh .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-SzcZQbDHJMHvMoCh .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-SzcZQbDHJMHvMoCh :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 客户端
代理 proxy1
代理 proxy2
源服务器
使用代理服务器的理由包括:
- 利用缓存减少网络带宽流量
- 在组织内部针对特定 URI 进行访问控制
- 获取访问日志
书中还按两个维度给代理分类:
| 分类维度 | 类型 | 含义 |
|---|---|---|
| 是否使用缓存 | 缓存代理 | 转发响应时预先保存资源副本,再次收到相同资源请求时可直接返回缓存 |
| 是否修改报文 | 透明代理 | 转发请求或响应时不对报文做任何加工 |
| 是否修改报文 | 非透明代理 | 转发请求或响应时会对报文内容进行加工 |
网关:让 HTTP 连接到非 HTTP 服务
网关和代理的工作机制很相似,也会转发其他服务器的通信数据。不同的是,网关能让通信线路上的服务器提供非 HTTP 协议服务。
对客户端来说,网关有时就像自己拥有资源的源服务器一样处理请求,客户端未必能察觉通信目标其实是网关。
#mermaid-svg-5xxufd0fDqQc3e13{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5xxufd0fDqQc3e13 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5xxufd0fDqQc3e13 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5xxufd0fDqQc3e13 .error-icon{fill:#552222;}#mermaid-svg-5xxufd0fDqQc3e13 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5xxufd0fDqQc3e13 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5xxufd0fDqQc3e13 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5xxufd0fDqQc3e13 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5xxufd0fDqQc3e13 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5xxufd0fDqQc3e13 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5xxufd0fDqQc3e13 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5xxufd0fDqQc3e13 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5xxufd0fDqQc3e13 .marker.cross{stroke:#333333;}#mermaid-svg-5xxufd0fDqQc3e13 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5xxufd0fDqQc3e13 p{margin:0;}#mermaid-svg-5xxufd0fDqQc3e13 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5xxufd0fDqQc3e13 .cluster-label text{fill:#333;}#mermaid-svg-5xxufd0fDqQc3e13 .cluster-label span{color:#333;}#mermaid-svg-5xxufd0fDqQc3e13 .cluster-label span p{background-color:transparent;}#mermaid-svg-5xxufd0fDqQc3e13 .label text,#mermaid-svg-5xxufd0fDqQc3e13 span{fill:#333;color:#333;}#mermaid-svg-5xxufd0fDqQc3e13 .node rect,#mermaid-svg-5xxufd0fDqQc3e13 .node circle,#mermaid-svg-5xxufd0fDqQc3e13 .node ellipse,#mermaid-svg-5xxufd0fDqQc3e13 .node polygon,#mermaid-svg-5xxufd0fDqQc3e13 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5xxufd0fDqQc3e13 .rough-node .label text,#mermaid-svg-5xxufd0fDqQc3e13 .node .label text,#mermaid-svg-5xxufd0fDqQc3e13 .image-shape .label,#mermaid-svg-5xxufd0fDqQc3e13 .icon-shape .label{text-anchor:middle;}#mermaid-svg-5xxufd0fDqQc3e13 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5xxufd0fDqQc3e13 .rough-node .label,#mermaid-svg-5xxufd0fDqQc3e13 .node .label,#mermaid-svg-5xxufd0fDqQc3e13 .image-shape .label,#mermaid-svg-5xxufd0fDqQc3e13 .icon-shape .label{text-align:center;}#mermaid-svg-5xxufd0fDqQc3e13 .node.clickable{cursor:pointer;}#mermaid-svg-5xxufd0fDqQc3e13 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5xxufd0fDqQc3e13 .arrowheadPath{fill:#333333;}#mermaid-svg-5xxufd0fDqQc3e13 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5xxufd0fDqQc3e13 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5xxufd0fDqQc3e13 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5xxufd0fDqQc3e13 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5xxufd0fDqQc3e13 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5xxufd0fDqQc3e13 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5xxufd0fDqQc3e13 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5xxufd0fDqQc3e13 .cluster text{fill:#333;}#mermaid-svg-5xxufd0fDqQc3e13 .cluster span{color:#333;}#mermaid-svg-5xxufd0fDqQc3e13 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5xxufd0fDqQc3e13 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5xxufd0fDqQc3e13 rect.text{fill:none;stroke-width:0;}#mermaid-svg-5xxufd0fDqQc3e13 .icon-shape,#mermaid-svg-5xxufd0fDqQc3e13 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5xxufd0fDqQc3e13 .icon-shape p,#mermaid-svg-5xxufd0fDqQc3e13 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5xxufd0fDqQc3e13 .icon-shape .label rect,#mermaid-svg-5xxufd0fDqQc3e13 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5xxufd0fDqQc3e13 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5xxufd0fDqQc3e13 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5xxufd0fDqQc3e13 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 转换为非 HTTP 协议通信
处理结果
HTTP 响应
客户端 HTTP 请求
网关
非 HTTP 服务器/后端系统
书中举到的例子包括:
- 网关连接数据库,使用 SQL 语句查询数据
- Web 购物网站通过网关和信用卡结算系统联动
网关还能提高通信的安全性,例如在客户端与网关之间的通信线路上加密,以确保连接安全。
隧道:建立一条安全通信线路
隧道是在相隔较远的客户端和服务器之间进行中转,并保持双方通信连接的应用程序。
它的目的,是按要求建立一条与其他服务器的通信线路,并使用 SSL 等加密手段进行通信,确保客户端能与服务器安全通信。
#mermaid-svg-NaHSxQQN5u5fGQui{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-NaHSxQQN5u5fGQui .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-NaHSxQQN5u5fGQui .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-NaHSxQQN5u5fGQui .error-icon{fill:#552222;}#mermaid-svg-NaHSxQQN5u5fGQui .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-NaHSxQQN5u5fGQui .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-NaHSxQQN5u5fGQui .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-NaHSxQQN5u5fGQui .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-NaHSxQQN5u5fGQui .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-NaHSxQQN5u5fGQui .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-NaHSxQQN5u5fGQui .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-NaHSxQQN5u5fGQui .marker{fill:#333333;stroke:#333333;}#mermaid-svg-NaHSxQQN5u5fGQui .marker.cross{stroke:#333333;}#mermaid-svg-NaHSxQQN5u5fGQui svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-NaHSxQQN5u5fGQui p{margin:0;}#mermaid-svg-NaHSxQQN5u5fGQui .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-NaHSxQQN5u5fGQui .cluster-label text{fill:#333;}#mermaid-svg-NaHSxQQN5u5fGQui .cluster-label span{color:#333;}#mermaid-svg-NaHSxQQN5u5fGQui .cluster-label span p{background-color:transparent;}#mermaid-svg-NaHSxQQN5u5fGQui .label text,#mermaid-svg-NaHSxQQN5u5fGQui span{fill:#333;color:#333;}#mermaid-svg-NaHSxQQN5u5fGQui .node rect,#mermaid-svg-NaHSxQQN5u5fGQui .node circle,#mermaid-svg-NaHSxQQN5u5fGQui .node ellipse,#mermaid-svg-NaHSxQQN5u5fGQui .node polygon,#mermaid-svg-NaHSxQQN5u5fGQui .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-NaHSxQQN5u5fGQui .rough-node .label text,#mermaid-svg-NaHSxQQN5u5fGQui .node .label text,#mermaid-svg-NaHSxQQN5u5fGQui .image-shape .label,#mermaid-svg-NaHSxQQN5u5fGQui .icon-shape .label{text-anchor:middle;}#mermaid-svg-NaHSxQQN5u5fGQui .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-NaHSxQQN5u5fGQui .rough-node .label,#mermaid-svg-NaHSxQQN5u5fGQui .node .label,#mermaid-svg-NaHSxQQN5u5fGQui .image-shape .label,#mermaid-svg-NaHSxQQN5u5fGQui .icon-shape .label{text-align:center;}#mermaid-svg-NaHSxQQN5u5fGQui .node.clickable{cursor:pointer;}#mermaid-svg-NaHSxQQN5u5fGQui .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-NaHSxQQN5u5fGQui .arrowheadPath{fill:#333333;}#mermaid-svg-NaHSxQQN5u5fGQui .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-NaHSxQQN5u5fGQui .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-NaHSxQQN5u5fGQui .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NaHSxQQN5u5fGQui .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-NaHSxQQN5u5fGQui .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NaHSxQQN5u5fGQui .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-NaHSxQQN5u5fGQui .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-NaHSxQQN5u5fGQui .cluster text{fill:#333;}#mermaid-svg-NaHSxQQN5u5fGQui .cluster span{color:#333;}#mermaid-svg-NaHSxQQN5u5fGQui div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-NaHSxQQN5u5fGQui .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-NaHSxQQN5u5fGQui rect.text{fill:none;stroke-width:0;}#mermaid-svg-NaHSxQQN5u5fGQui .icon-shape,#mermaid-svg-NaHSxQQN5u5fGQui .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NaHSxQQN5u5fGQui .icon-shape p,#mermaid-svg-NaHSxQQN5u5fGQui .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-NaHSxQQN5u5fGQui .icon-shape .label rect,#mermaid-svg-NaHSxQQN5u5fGQui .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NaHSxQQN5u5fGQui .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-NaHSxQQN5u5fGQui .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-NaHSxQQN5u5fGQui :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 通过隧道建立安全通信线路
客户端
隧道
服务器
隧道本身不会解析 HTTP 请求,而是把请求保持原样中转给之后的服务器。通信双方断开连接时,隧道也会结束。
代理、网关、隧道的区别
这三个概念容易混在一起,可以用下面这张表快速区分:
| 概念 | 书中核心描述 | 典型作用 |
|---|---|---|
| 代理 Proxy | 位于客户端和服务器之间,接收客户端请求并转发给源服务器,再把响应转发给客户端 | 缓存、访问控制、访问日志 |
| 网关 Gateway | 转发其他服务器的通信数据,让服务器提供非 HTTP 协议服务 | 连接数据库、连接信用卡结算系统、提高通信安全性 |
| 隧道 Tunnel | 在客户端和服务器之间中转并保持通信连接,本身不解析 HTTP 请求 | 使用 SSL 等加密手段建立安全通信线路 |
一句话记忆:
代理偏"转发",网关偏"转换",隧道偏"透明传输"。
缓存为什么能让 Web 更快
缓存是指代理服务器或客户端本地磁盘内保存的资源副本。
利用缓存,可以减少对源服务器的访问,从而节省通信流量和通信时间。缓存服务器属于代理服务器的一种,也就是缓存代理。
缓存服务器的基本工作方式可以概括为:
#mermaid-svg-0Rh1U2I3QxtM67OL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0Rh1U2I3QxtM67OL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0Rh1U2I3QxtM67OL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0Rh1U2I3QxtM67OL .error-icon{fill:#552222;}#mermaid-svg-0Rh1U2I3QxtM67OL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0Rh1U2I3QxtM67OL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0Rh1U2I3QxtM67OL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0Rh1U2I3QxtM67OL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0Rh1U2I3QxtM67OL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0Rh1U2I3QxtM67OL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0Rh1U2I3QxtM67OL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0Rh1U2I3QxtM67OL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0Rh1U2I3QxtM67OL .marker.cross{stroke:#333333;}#mermaid-svg-0Rh1U2I3QxtM67OL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0Rh1U2I3QxtM67OL p{margin:0;}#mermaid-svg-0Rh1U2I3QxtM67OL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-0Rh1U2I3QxtM67OL .cluster-label text{fill:#333;}#mermaid-svg-0Rh1U2I3QxtM67OL .cluster-label span{color:#333;}#mermaid-svg-0Rh1U2I3QxtM67OL .cluster-label span p{background-color:transparent;}#mermaid-svg-0Rh1U2I3QxtM67OL .label text,#mermaid-svg-0Rh1U2I3QxtM67OL span{fill:#333;color:#333;}#mermaid-svg-0Rh1U2I3QxtM67OL .node rect,#mermaid-svg-0Rh1U2I3QxtM67OL .node circle,#mermaid-svg-0Rh1U2I3QxtM67OL .node ellipse,#mermaid-svg-0Rh1U2I3QxtM67OL .node polygon,#mermaid-svg-0Rh1U2I3QxtM67OL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0Rh1U2I3QxtM67OL .rough-node .label text,#mermaid-svg-0Rh1U2I3QxtM67OL .node .label text,#mermaid-svg-0Rh1U2I3QxtM67OL .image-shape .label,#mermaid-svg-0Rh1U2I3QxtM67OL .icon-shape .label{text-anchor:middle;}#mermaid-svg-0Rh1U2I3QxtM67OL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0Rh1U2I3QxtM67OL .rough-node .label,#mermaid-svg-0Rh1U2I3QxtM67OL .node .label,#mermaid-svg-0Rh1U2I3QxtM67OL .image-shape .label,#mermaid-svg-0Rh1U2I3QxtM67OL .icon-shape .label{text-align:center;}#mermaid-svg-0Rh1U2I3QxtM67OL .node.clickable{cursor:pointer;}#mermaid-svg-0Rh1U2I3QxtM67OL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0Rh1U2I3QxtM67OL .arrowheadPath{fill:#333333;}#mermaid-svg-0Rh1U2I3QxtM67OL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0Rh1U2I3QxtM67OL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0Rh1U2I3QxtM67OL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0Rh1U2I3QxtM67OL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0Rh1U2I3QxtM67OL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0Rh1U2I3QxtM67OL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0Rh1U2I3QxtM67OL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0Rh1U2I3QxtM67OL .cluster text{fill:#333;}#mermaid-svg-0Rh1U2I3QxtM67OL .cluster span{color:#333;}#mermaid-svg-0Rh1U2I3QxtM67OL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0Rh1U2I3QxtM67OL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0Rh1U2I3QxtM67OL rect.text{fill:none;stroke-width:0;}#mermaid-svg-0Rh1U2I3QxtM67OL .icon-shape,#mermaid-svg-0Rh1U2I3QxtM67OL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0Rh1U2I3QxtM67OL .icon-shape p,#mermaid-svg-0Rh1U2I3QxtM67OL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0Rh1U2I3QxtM67OL .icon-shape .label rect,#mermaid-svg-0Rh1U2I3QxtM67OL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0Rh1U2I3QxtM67OL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0Rh1U2I3QxtM67OL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0Rh1U2I3QxtM67OL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 没有缓存
已有缓存
有效
需要确认或已失效
客户端请求资源
缓存服务器内是否已有资源副本?
向源服务器请求资源
转发响应时复制资源并保存
返回给客户端
缓存是否仍然有效?
向源服务器确认有效性
必要时重新获取新资源
缓存的优势在于:如果某个资源已经被缓存,客户端就可以从缓存服务器获取资源,源服务器也不必反复处理相同请求。
但缓存并不是只要存在就一定能直接使用。书中强调,即使缓存服务器中有缓存,也可能因为客户端要求、缓存有效期、源服务器资源更新等因素,需要向源服务器确认资源的有效性。若判断缓存失效,缓存服务器会再次从源服务器获取新资源。
客户端也有缓存
缓存不仅可以存在于缓存服务器内,也可以存在于客户端浏览器中。
浏览器缓存如果有效,就不必再向服务器请求相同资源,可以直接从本地磁盘读取。和缓存服务器一样,当浏览器判断缓存过期后,也会向源服务器确认资源有效性;如果缓存已经失效,就会再次请求新资源。
补充理解:缓存相关首部要到后面一起看
第 5 章主要讲"缓存是什么、缓存服务器和客户端缓存怎么工作"。具体的缓存控制细节,会在 HTTP 首部相关内容里展开。
实际排查缓存问题时,常见会关注这些字段:
Cache-ControlExpiresETagLast-ModifiedAge
其中 no-cache 和 no-store 很容易混淆:no-cache 不是"完全不缓存",而是"使用缓存前需要确认有效性";真正不保存内容的是 no-store。
实践:用 curl 观察 Host、代理和缓存首部
下面是结合开发场景的补充实践,不是原书中的命令示例。
1. 通过 Host 首部模拟访问虚拟主机
bash
curl -H "Host: www.example.com" http://192.168.1.100/
curl -H "Host: blog.example.com" http://192.168.1.100/
同一个 IP 地址可以因为 Host 不同而路由到不同站点。
2. 通过 HTTP 代理发送请求
bash
curl -x http://proxy.example.com:8080 -v http://www.example.com/
如果链路中存在代理,可以重点观察是否出现 Via 等字段。
3. 查看缓存相关响应首部
bash
curl -I https://www.example.com/ \
| grep -i "cache-control\|expires\|etag\|last-modified\|age"
常见需要关注的字段包括:
Cache-ControlExpiresETagLast-ModifiedAge
实际开发中怎么用这些知识
下面这部分是结合开发场景的补充理解,不属于第 5 章原文逐条展开的内容。
配置反向代理时
需要关注:
Host是否正确传给后端- 是否存在多层代理
- 是否需要通过代理层记录访问日志
- 是否存在缓存导致资源没有及时更新
排查缓存问题时
可以按这个顺序看:
- 响应里有没有缓存相关首部
- 浏览器或代理是否命中缓存
- 缓存是否已经过期
- 是否向源服务器确认过资源有效性
- 源服务器是否返回了新资源
小结
第 5 章虽然篇幅不长,但它把 HTTP 从"客户端和服务器的两点通信"扩展到了更真实的 Web 通信链路里。
可以这样记:
- 虚拟主机 :一台服务器承载多个站点,核心靠
Host区分 - 代理:位于客户端和源服务器之间,负责转发请求和响应
- 网关:让 HTTP 通信连接到非 HTTP 服务,也可提高通信安全性
- 隧道:建立安全通信线路,本身不解析 HTTP 请求
- 缓存:保存资源副本,减少源服务器访问和通信时间
理解这些概念后,再看 Web 服务器、代理缓存、浏览器缓存和网关类系统,就能更清楚它们在 HTTP 通信链路里到底扮演什么角色。
不过,到这里我们其实还留下了一个更细的问题:代理为什么知道自己要追加 Via?缓存为什么知道资源什么时候过期?浏览器和服务器又是靠什么传递这些控制信息的?
答案都藏在 HTTP 报文的"标签"里,也就是下一篇要看的重点:HTTP 首部。如果说前面几章是在看 HTTP 怎么跑起来,那下一篇就要开始拆它身上贴满的说明书了。