从前端看CDN

135 阅读4分钟

CDN原理

CDN的最终目的:性能优化

1. CDN原理

1.1 几个名词

  1. 源站: 提供Web服务的站点,简单来说就是一个放index.html的服务器
  2. 边缘节点: CDN 集群里离用户最近的那个结点

1.2 基本原理

浏览器发起HTTP请求到本地DNS服务器本地DNS服务器使用CNAME的方式,将资源域名重定向到CDN服务,依靠CDN的策略,查找到最佳CDN节点IP。浏览器访问该节点,用最短访问时延,下载所需的资源。

至于这个 CNAME ,个人理解是DNS解析的延伸,DNS解析一般是解析出一个IP,但是这里可以解析出一个 CNAME ,再凭借CNAME ,走到CDN厂商,CDN厂商返回一个最终的IP

1.2 流程

  1. 当终端用户向www.a.com下的指定资源发起请求时,首先向LDNS(本地DNS)发起域名解析请求。
  2. LDNS检查缓存中是否有www.a.com的IP地址记录。如果有,则直接返回给终端用户;如果没有,则向授权DNS查询。
  3. 当授权DNS解析www.a.com时,返回域名CNAME www.a.tbcdn.com对应IP地址。
  4. 域名解析请求发送至阿里云DNS调度系统,并为请求分配最佳节点IP地址。
  5. LDNS获取DNS返回的解析IP地址。
  6. 用户获取解析IP地址。
  7. 用户向获取的IP地址发起对该资源的访问请求
  • 如果该IP地址对应的节点已缓存该资源,则会将数据直接返回给用户,此时请求结束。
  • 如果该IP地址对应的节点未缓存该资源,则节点向源站发起对该资源的请求。获取资源后结合用户自定义配置的缓存策略,将资源缓存到CDN节点并返回给用户,例如图中的北京节点,此时请求结束

2. DNS预解析

当网站第一次请求某个跨域域名时,需要先解析该域名(例如页面访问cdn资源,第一次访问需要先解析cdn)。

可以在请求的Timing上看到有一个DNS Lookup阶段,而在这个请求之后的其他该域名的请求都没有这项时间支出。

image.png

如何开启DNS预解析

<link rel="dns-prefetch" href="xxx.com">

💡 所以有没有可能,我们可以在页面的头部加入`一串` , 解析我们的CDN的域名;

需要有一串 Link 吗

浏览器对于同一域名下的同时发起的请求数是有上限的,谷歌(6个),但是现在HTTP2普及,甚至HTTP3都开始有苗头的时刻;

如果还是采用古早的手段:把资源分发到不同域名下,以提高一个站点同时发起请求的数量。我想可以抛弃不用了: 域名发散 → 域名收敛

所以:

  1. 我们只需要在 Head 加入一个 本网站用到的CDN的预解析就好啦
  2. 如果该 html文件 和 静态资源在同一个CDN地址下,那在请求html文件的时候,这个域名的DNS解析已经被本地缓存了,也没有必要加入预解析啦

2.1 DNS预解析的姊妹篇 - 网络预链接

<link rel="preconnect" href="<https://lf-cdn-tos.bytescm.com/>">

这样在后面的请求中,可以跳过三次握手 + TLS加密 的过程哦

注意:

  1. http页面下所有的a标签的href都会自动去启用DNS Prefetch,也就是说,你网页的a标签href带的域名,是不需要在head里面加上link手动设置的。https页面需要使用meta标签强制开启:

    <meta http-equiv="x-dns-prefetch-control" content="on">

  2. dns-prefetch适用于网页引用了大量其他域名的资源,例如淘宝。

3. 几个概念

资源刷新

强制删除CDN所有节点上的缓存资源,当您向CDN节点请求资源时,CDN会直接回源站获取对应的资源并返回给您,同时将资源重新缓存到CDN节点。刷新功能会降低缓存命中率。

资源预热

源站主动将对应的资源缓存到CDN节点,当您首次请求资源时,即可直接从CDN节点获取到最新的资源,无需再回源站获取。预热功能会提高缓存命中率。

💡 所以我们的CDN资源,都应该在发布后进行资源预热,对于CSS/JS资源,尽量使用长时间的缓存时间, 可能一年?