《图解HTTP》--第5章-与HTTP协作的Web服务器

读《图解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-Control
  • Expires
  • ETag
  • Last-Modified
  • Age

其中 no-cacheno-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-Control
  • Expires
  • ETag
  • Last-Modified
  • Age

实际开发中怎么用这些知识

下面这部分是结合开发场景的补充理解,不属于第 5 章原文逐条展开的内容。

配置反向代理时

需要关注:

  • Host 是否正确传给后端
  • 是否存在多层代理
  • 是否需要通过代理层记录访问日志
  • 是否存在缓存导致资源没有及时更新

排查缓存问题时

可以按这个顺序看:

  1. 响应里有没有缓存相关首部
  2. 浏览器或代理是否命中缓存
  3. 缓存是否已经过期
  4. 是否向源服务器确认过资源有效性
  5. 源服务器是否返回了新资源

小结

第 5 章虽然篇幅不长,但它把 HTTP 从"客户端和服务器的两点通信"扩展到了更真实的 Web 通信链路里。

可以这样记:

  • 虚拟主机 :一台服务器承载多个站点,核心靠 Host 区分
  • 代理:位于客户端和源服务器之间,负责转发请求和响应
  • 网关:让 HTTP 通信连接到非 HTTP 服务,也可提高通信安全性
  • 隧道:建立安全通信线路,本身不解析 HTTP 请求
  • 缓存:保存资源副本,减少源服务器访问和通信时间

理解这些概念后,再看 Web 服务器、代理缓存、浏览器缓存和网关类系统,就能更清楚它们在 HTTP 通信链路里到底扮演什么角色。


不过,到这里我们其实还留下了一个更细的问题:代理为什么知道自己要追加 Via?缓存为什么知道资源什么时候过期?浏览器和服务器又是靠什么传递这些控制信息的?

答案都藏在 HTTP 报文的"标签"里,也就是下一篇要看的重点:HTTP 首部。如果说前面几章是在看 HTTP 怎么跑起来,那下一篇就要开始拆它身上贴满的说明书了。

相关推荐
AlienZHOU8 小时前
AI Coding 时代下,我的技术面试实践分享
前端·后端·面试
国际云,接待10 小时前
华为云 EVS 性能诊断:用 CES、ECS QoS 与 fio 定位 IOPS 和吞吐瓶颈
服务器
Captaincc11 小时前
AI用量v0.1.11更新发布 新增 jusage doctor 诊断指令 托盘展示token 和余额 新增 AutoClaw 支持
前端·后端·vibecoding
计算机魔术师13 小时前
德国Wiki被黑后两周,OpenAI终于把模型失控的账本摊开了
前端
智恒百亿13 小时前
RTX 5090 八卡服务器 vs RTX PRO 6000 整机:AI 推理、微调与渲染选型部署指南
运维·服务器·rtx5090
ManageEngineITSM13 小时前
DevOps和ITIL是什么关系?是替代还是互补一文讲清
java·服务器·资产管理·变更管理
kyriewen13 小时前
我让 AI 当面试官面了我一轮:第 3 个追问我就卡住了(附 10 道追问清单)
前端·面试·ai编程
IT_陈寒13 小时前
Python的GIL把我坑惨了,多线程跑得比单线程还慢
前端·人工智能·后端
前端snow14 小时前
ai agent --- 多agent框架之图编排引擎-langgraph
前端
竹林81814 小时前
OmniPic Studio v3.2.1 核心技术架构与全平台发版解析文档
前端·浏览器