关于 CDN 的灵魂 16 问

如果你把你的站点部署在 CDN 的后面,网站的 IP 地址是 CDN 还是后端服务器?

是 CDN 的 IP

所有请求都会发到 CDN,然后 CDN 在需要的情况下向后端服务器发出请求。

CDN 是否只有一个数据中心用于缓存内容?

不是

CDN 会将内容缓存在不同地区的多个服务器上,这样你的用户无论在哪里都能迅速得到响应。

CDN 只会缓存 HTTP 响应的 body(比如图片)吗?

不是

它可以缓存整个 HTTP 响应,包括状态码和响应头。

所以,举例来说,如果你的服务器不小心返回了 404,CDN 将这个响应进行了缓存,那么即使服务器已经恢复,你的网站仍然可能是 404。

如果你不小心缓存了错误的内容,是否能清理掉?

是的

CDN 提供方通常有清除缓存的方法。不过有时需要几分钟才能完成(CDN 可能要去告诉世界各地的数百台服务器来清理它们的缓存)。

你可以选择从缓存中只删除特定文件或者删除所有缓存的文件。

CDN 如何知道它应该把 HTTP 响应放在缓存中?

依赖于客户端的请求

当 CDN 收到一个资源请求时,它会从你的服务器上请求资源,然后会把资源放在它的缓存中,这样下次就不用再到你的服务器上请求了。

CDN 可以缓存任何类型的 HTTP 的响应吗?

是的

如果你要求 CDN 进行缓存,它通常可以缓存任何你想要的 HTTP 响应,比如可以将响应头设置为: Cache-Control: public; max-age=3600

不过大多数 CDN 会对缓存内容的大小进行限制,所以你可能无法缓存一个电影。

CDN 是否可以在你的服务器宕机的情况下继续为你的站点提供服务?

也许

即使你的服务器没有运行,CDN 也可以继续提供缓存页面。

但是如果你告诉它只缓存一定时间(比如 1 小时),内容可能会在一段时间后过期,无法访问。而如果内容根本没有被缓存,CDN 也帮不了你。

如果你在 CDN 后面的网站使用 TLS,CDN 能读取你未加密的网站流量吗?

是的

如果你想让CDN缓存内容,它需要能够解密和读取。

通常人们处理这个问题的方法是,只把静态内容(如 CSS/JS/图片)放在 CDN 后面的域名上,而使用一个单独的域名来处理带有用户数据的请求。例如,https://github.githubassets.com/ 在 CDN 后面,但https://github.com 不是。

CDN 总是对资源进行缓存吗?

不是

如果你想,可以配置你的 CDN 不进行缓存,只是代理每个请求到你的后端服务器。

是否可以判断出某个网站使用了 CDN?

是的

你通常可以从 header 中找出答案:运行curl -I https://jiapan.me,看看我使用的是什么 CDN。

是否能判断出你收到的是一个被缓存的响应?

是的

CDN 通常会设置一个响应头,比如 x-cache: HIT,你可以用它来判断是缓存命中还是缓存失效。

及时没有缓存,CDN 是否可以使请求更快?

是的

  1. CDN通常可以在离客户端更近的地方终止 TLS,这意味着 TLS 握手可以快很多。如果你的后端服务器离客户端很远,这可以节省一秒左右的时间。这样做的原因是,它经常会与后端服务器保持一个开放的 TLS 连接,所以它不必每次都重新建立一个新的连接。
  2. 它可能比客户机有更快的路由连接到你的后端服务器。
  3. CDN还可以通过更多的方式来提高性能!

如果你的站点只支持 HTTP/1.1,CDN 可以接收 HTTP/2.0 的请求吗?

大部分情况下可以

许多CDN可以透明地将 HTTP/2 请求翻译成 HTTP/1 请求到你的后端服务器,所以你可以在不做任何工作的情况下获得 HTTP/2 的很多性能优势。

是否可以让 CDN 对响应只缓存一段时间(如10分钟)?

是的

您可以通过设置 Cache-Control 响应头来实现,比如 Cache-Control: max-age=600

是否允许资源只被浏览器缓存而不被 CDN 缓存?

是的

你可以通过设置 Cache-Control: private, max-age=3600 来实现。private 意味着内容只能存储在浏览器的缓存中,而不是 CDN 的缓存中。

如果你用同一个 URL 请求 CDN,但 header 不同,是否会得到相同的缓存响应?

视情况而定

默认情况下,会得到相同的响应。但如果服务器设置了 Vary: 头,那么 CDN 将为该头的每个值存储不同的缓存值。

例如,Vary: Accept-Encoding 将使 CDN 同时存储压缩和非压缩版本。