CDN内容分发网络

引言:CDN不是一个单独的应用层协议,而是一种基于网络架构和技术的内容分发解决方案

CDN

CDN本质

CDN(Content Delivery Networks,或CDNs)内容分发网络:本质是一个网络层面的分布式缓存架构

目的:在全球范围内部署分布式缓存节点,将内容存储在离用户更近的位置,从而减少传输延迟,提高内容的访问速度和性能

问题1:所谓的内容分发,其中的“内容”具体指网页的什么内容?

一个网页通常有:

  • 静态数据:HTML、CSS、JavaScript、图像、字体、文件、视频和流媒体
  • 动态数据:用户的个人数据、视频的点赞量、收藏量

静态数据通常不会发生变化,CDN可以将这些数据缓存起来,当用户访问时就无需将请求发送到源服务器,加快响应速度。

(注意:CDN并不是只能缓存静态数据,有些情况下也缓存了动态数据)

CDN内容分发的流程

CDN的网络布局有三种角色构成:客户端、服务器、CDN服务器

如图所示:

CDN缓存机制

假设现在有客户端A、B:

  1. 服务器会将静态资源主动push到CDN服务器
  2. 客户端A发送请求
  3. CDN缓存命中,直接响应
  4. 客户端B发送请求
  5. CDN缓存未命中,执行pull操作,请求源服务器
    • 关于未命中的原因有很多,需要根据具体的缓存策略来考虑
  6. 响应给客户端的同时缓存在本地CDN缓存中

问题2:为什么会出现缓存未命中呢?CDN如何判断资源是否过期?

缓存未命中的原因有很多:比如资源过期、或是其中含有动态数据

判断资源过期由不同的缓存策略决定:

  • 时间戳过期:根据文件的时间戳判断是否过期,当时间戳发生变化时,CDN服务器会重新请求最新的内容。
  • HTTP头部控制:通过HTTP头部中的Cache-ControlExpires等字段来控制缓存过期时间。
  • 内容分片:将内容分成多个小块进行缓存,可以更灵活地更新和替换内容。(比如HLS(HTTP Live Streaming)将视频和音频源文件编码并切割成小的.ts分段)

问题3:CDN与Nginx的关系

CDN服务器的具体实现和使用的软件可以有多种选择,其中Nginx是一个常见且广泛应用于CDN架构中的服务器软件之一

Nginx是一个web服务器软件,提供高性能的静态资源服务、反向代理等功能,他与Java服务端软件Tomcat经常配合使用,可以将Nginx作为反向代理服务器,将静态资源交给Nginx处理,动态请求转发给Tomcat。这种结合使用的方式可以充分利用Nginx的高性能和Tomcat的动态内容处理能力

CDN内容分发的原理:任播

任播(Anycast)是一种网络技术,并不是某个特定的应用或协议。

用户无论位于世界的哪个地方,都可以通过最近的缓存节点获取内容,减少了数据传输的延迟和网络拥塞,任播广泛应用于负载均衡、内容分发网络(CDN)、域名系统(DNS)等

任播的主要特点是它不依赖于特定的源节点和目标节点之间的一对一连接,而是将数据包传输到最近的可用节点,使得数据能够快速到达用户或目标地点。

CDN使用任播来实现内容的分发和路由

问题4:任播如何判断距离远近?

任播的实现依赖于网络路由协议和底层网络设备的支持:

任播的IP地址共享

  • IP地址共享:在任播中规定,多个不同位置的节点共享同一个IP地址
    • 这意味着在网络中的不同位置都存在具有相同IP地址的节点。当有数据包发送到该IP地址时,路由器会根据一定的规则选择距离最近的节点来处理数据包。
  • 路由选择:路由器在选择处理数据包的节点时,会根据网络拓扑和距离等因素进行选择。它可能使用基于距离向量的路由协议(如RIP、BGP)或链路状态协议(如OSPF)来获取网络拓扑信息并做出路由决策。

问题5:任播与组播的区别

  • 工作方式:
    • 组播:数据包从一个发送者传输给一组IP地址(多个节点,不同IP)
    • 任播:数据包从一个发送者传输给一个IP地址(多个节点,相同IP)
  • 数据包:
    • 组播:只需被发送一次,但可以被多个接收者共享
    • 任播:一个数据包被发送到多个服务器,但只有最近的服务器会处理该数据包
  • 应用场景:
    • 组播:实时视频、在线会议
    • 任播:负载均衡、CDN

补充:HTTP头部关于缓存的字段

Cache-Control是HTTP/1.1引入的缓存控制机制,而ExpiresLast-Modified是HTTP/1.0中的一种旧有的缓存机制,在HTTP/1.1中被Cache-Control所取代,但由于向下兼容的原因,依然保留这两个字段:

  1. Cache-Control字段:
    • Cache-Control是一个通用的头部字段,用于控制缓存行为。它可以包含多个指令,指定缓存的行为方式。
    • 常见的Cache-Control指令包括:
      • public:响应可以被任何缓存(包括公共缓存)缓存。
      • private:响应只能被单个用户缓存,不可被共享缓存存储。
      • no-cache:需要进行重新验证,缓存必须向服务器发送请求进行确认。
      • max-age=<seconds>:指定响应的有效时间,单位为秒。
    • Cache-Control的值可以是单个指令,也可以是多个指令通过逗号分隔。例如:Cache-Control: max-age=3600, private
  2. Expires字段:
    • Expires是一个HTTP响应头部字段,用于指定响应的过期时间。
    • 它的值是一个GMT(格林尼治标准时间)格式的日期时间字符串,指定了响应在该日期时间之后将被认为是过期的。
    • 如果Expires字段的日期时间已经过去,那么客户端会发送一个新的请求来获取最新的内容,而不是使用缓存中的过期内容。
    • 注意,Expires字段的缺点是它使用的是服务器的时间,而客户端和服务器的时间可能不完全同步。
  3. Last-Modified字段:
    • Last-Modified是一个表示资源最后修改时间的头部字段,由服务器在响应中返回。
    • 客户端可以通过发送If-Modified-Since头部字段,携带先前获取的Last-Modified值,来验证资源是否发生了修改。