Pre
我们使用的电商、直播、社交工具、视频网站中都含有大量的图片、视频、文档等,这些资源需要分发给用户。
对于一些体量较大的应用来说,如果把大量资源集中到单一节点进行分发,恐怕很难有某个机房可以支撑得住这么大的流量。
例如一个日活在 100W 的小型互联网产品,如果每次请求需要 1M 的数据,那就刚好是近 1TB 数据。对于这样的数据规模而言,完全由单一节点进行分发是不现实的。
因此现在 互联网应用在分发内容的时候,并不是从自己架设的服务器上直分发内容,而是走一个叫作内容分发网络(Content Dilivery Network)的互联网底层建设 。
我们就以“CDN 回源是如何工作的”为引, 一起探索 CDN 的原理和场景。
CDN 是什么?
和域名系统类似, 内容分发网络(Content Dilivery Network,CDN)是一个专门用来分发内容的分布式应用 。
CDN 构建在现有的互联网之上,通过在各地部署数据中心,让不同地域的用户可以就近获取内容 。
这里的内容通常指的是文件、图片、视频、声音、应用程序安装包等,它们具有一个显著的特征—— 无状态,或者说是静态的 。这些资源不像订单数据、库存数据等,它们一旦发布,就很少会发生变化。另一个显著的特征,是这些资源往往会被大量的用户需要,因此分发它们的流量成本是较高的。
为什么不能集中提供这些静态资源呢?这和域名系统的 DNS 记录不能集中提供是一个道理,需要考虑到流量、单点故障、延迟等因素。在离用户更近的地理位置提供资源,可以减少延迟。按照地理位置分散地提供资源,也可以降低中心化带来的服务压力。
因此,CDN 的服务商会选择在全球布点,或者在某个国家布点。具体要看 CDN 服务提供商的服务范围。目前国内的阿里云、腾讯云等也在提供 CDN 业务。
内容的分发
CDN 是一个分布式的内容分发网络。当用户请求一个网络资源时,用户请求的是 CDN 提供的资源。和域名系统类似,当用户请求一个资源时,首先会接触到一个类似域名系统中目录的服务,这个服务会告诉用户究竟去哪个 IP 获取这个资源 。
事实上,很多大型的应用,会把 DNS 解析作为一种负载均衡的手段 。当用户请求一个网址的时候,会从该网站提供的智能 DNS 中获取网站的 IP。
例如当你请求百度的时候,具体连接到哪个百度的 IP,是由百度使用的智能 DNS 服务决定的。域名系统允许网站自己为自己的产品提供 DNS 解析
所以总体静态资源的使用路径如下图所示
当用户请求一个静态资源的时候,首先会触发域名系统的解析。域名系统会将解析的责任交由 CDN 提供商来处理,CDN 的智能 DNS 服务会帮助用户选择离自己距离最近的节点,返回这个节点的 A(或 AAAA)记录。然后客户端会向 CDN 的资源节点发起请求,最终获得资源。
在上面整个过程当中,CDN 的智能 DNS 还充当了负载均衡的作用。如果一个节点压力过大,则可以将流量导向其他的节点。
回源
目前我们已经讨论了 CDN 的主要设计和架构,但是还有一个问题没有解决——就是资源怎么进入内容分发网络。资源的生产者,也是 CDN 的购买者,目的是向用户提供网络服务。那么服务提供者的静态资源如何进入 CDN 呢? 手动上传、用接口推送,还是通过其他别的方式呢?
你可以把 CDN 想象成一个分布式的分级缓存,再加上数据库的两层设计,如下图所示:
用户的请求先到达缓存层,如果缓存被穿透,才到达最终的存储层。缓存的设计必须是分布式的,因为绝大多数的资源使用都会发生在缓存上,只有极少数的请求才会穿透到底层的存储。通常这种设计,我们期望缓存层至少需要帮挡住 99% 的流量。既然缓存层能挡住 99% 的流量,那么实际的数据存储就可以交由源站点完成。
值得一提的是, 在程序设计当中有一个核心的原则,叫作单一数据源(Single Souce of Truth, SSOT)。这个原则指的是,在程序设计中,应该尽可能地减少数据的来源,最好每个数据来源只有单独一份 。这样能够避免大量的数据不一致以及同步数据的问题。基于这样的设计,谁来提供资源的存储呢?谁来提供这个单一的数据源呢?当然是服务提供者本身。如果 CDN 再提供 一份资源的存储,不就有两个数据源了吗?而且,只有服务的提供者才能更好地维护这个资源仓库。
在 CDN 的设计当中,CDN 实际上提供的是数据的缓存。而原始数据,则由服务的提供者提供 。
用户请求静态资源通常用自己的域名(防止跨域和一些安全问题)。为了让用户请求的是自己的网站,而使用的是 CDN 的服务,这里会使用 CNAME 让自己的域名作为 CDN 域名的一个别名。当请求到 CDN 服务的时候,会首先由 CDN 的 DNS 服务帮助用户选择一个最优的节点,这个 DNS 服务还充当了负载均衡的作用。接下来,用户开始向 CDN 节点请求资源。 如果这个时候资源已经过期或者还没有在 CDN 节点上,就会从源站读取数据,这个步骤称为CDN 的回源 。
另一方面,CDN 上缓存的资源通常也会伴随失效时间的设置,当失效之后同样会触发回源。另一种情况是可以通过开放的 API 或者 CDN 管理后台直接删除缓存(让资源失效),这个操作结束后,同样会触发回源。
小结
总结一下,CDN 是一种网络应用,作用是分发互联网上的资源。CDN 服务的提供商,会在世界(或国家)范围内设立数据中心,帮助分发资源。用户请求的资源会被 CDN 分发到最临近的节点获取。
CDN 作为一门生意,CDN 的服务商会大批量的从运营商处获取流量,然后再以较高但是可以接受的价格卖给服务提供方。
对于中小型互联网公司来说,购买一定的 CDN 流量成本可控,比如 1G 流量在 1 元以内。对于大型的互联网公司,特别是对 CDN 依赖严重的公司,可能还需要自己建设。比如 2021 年抖音每天分发的数据量在 50PB 左右(1PB=1024TB),如此庞大的数据量如果换算成钱是非常高的。按照阿里云的报价,50PB 的价格是 480W 人民币。按照这种体量计算,抖音每天要花 480W 人民币,一年是 17 亿。
所以当你设计一个内容分发的方案时,除了要考虑到其中的技术细节,也要从成本上进行思考,看看能不能从 数据压缩、资源格式 角度做一些文章。
QA
请简述 CDN 回源是如何工作的?
【解析】CDN 回源就是 CDN 节点到源站请求资源,重新设置缓存。通常服务提供方在使用 CDN 的时候,会在自己的某个域名发布静态资源,然后将这个域名交给 CDN。
比如源站在 s.example.com 中发布静态资源,然后在 CDN 管理后台配置了这个源站。在使用 CDN 时,服务提供方会使用另一个域名,比如说 b.example.com。然后配置将 b.example.com 用 CNAME 记录指向 CDN 的智能 DNS。
这个时候,如果用户下载b.example.com/a.jpg,CDN 的智能 DNS 会帮用户选择一个最优的 IP 地址(最优的 CDN 节点)响应这次资源的请求。如果这个 CDN 节点没有 a.jpg,CDN 就会到 s.example.com 源站去下载,缓存到 CDN 节点,然后再返回给用户。
CDN 回源有 3 种情况,
- 一种是 CDN 节点没有对应资源时主动到源站获取资源;
- 另一种是缓存失效后,CDN 节点到源站获取资源;
- 还有一种情况是在 CDN 管理后台或者使用开放接口主动刷新触发回源。
如果你的应用需要智能 DNS 服务,你将如何实现?
【解析】首先你可以在你的域名解析系统中增加两条(或以上)ns 记录。比如说你的域名是 example.com,那么你可以增加 ns1.exmaple.com, ns2.example.com。当然,指定这两个域名的 IP 还需要配置两个 A 记录。
然后你需要两台机器(也可以是容器或者虚拟机),对应 ns1 和 ns2。最好用不在同一个物理机上的两个容器,这样可以避免一台物理机故障导致服务瘫痪。然后在每个容器(虚拟机)上安装一个 Named 服务。
Named 是一个专门用来提供 DNS 服务的工具,在虚拟机上安装完成 Named 后,这个虚拟机就变成了一个权威服务器节点。
配置好 Named 后,你需要写几个脚本文件,给要提供 DNS 的域名配置信息。Named 配套使用的有个叫作 GeoDNS 的插件,可以提供基于地理位置的智能 DNS 服务。
更具体的操作,可以参考这篇文档:https://bind9.readthedocs.io/en/latest/configuration.html。
Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。
它的内容包括:
- 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
- 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
- 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
- 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
- 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
- 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
- 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
- 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw
目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:
想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询
同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。