<audio id="audio" title="35 | 如何构建云端一对多直播系统？" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/c7/9e/c7439b7f5f60c4fb5152d0af9610d09e.mp3"></audio>

在上一篇文章中，我们介绍了如何通过 Nginx 搭建传统直播系统的实验环境，知道了理论是如何与实际结合到一起的。但同时我们也提到，要想通过 Nginx 来实现商用的直播系统还有很长的路要走。

那么今天，我们就来介绍一下快速构建商用直播系统的方案。要想实现真正商用的直播系统，我们必须踩在巨人肩膀上，这个“巨人”就是CDN网络。

可以这么说，现在99%的传统直播系统都是在CDN网络的基础上搭建出来的。因此，我们本文主要介绍的内容就是如何通过CDN网络实现商用的直播系统。我们平时所说的“万人直播”就是使用的这种技术。

## 万人直播的原理

我们首先来看一下万人直播架构图，如下所示：

<img src="https://static001.geekbang.org/resource/image/15/14/152d2b86619a8a35e28967043f0c5a14.png" alt="">

通过该图我们可以看到，它与上一篇文章所介绍的直播架构是非常类拟的，包括了共享端、观看端和CDN网络。唯一的变化就是把之前架构中的流媒体服务器换成了现在的 CDN 网络。

对于共享端和观看端来说，使用 CDN 网络与使用流媒体服务器没什么区别。它们都是将流推送给指定的流媒体服务器，然后从指定的播放地址拉流，并最终进行展示这样一个过程。

关于 CDN 网络的基本知识，我们在[《31 | 一对多直播系统RTMP/HLS，你该选哪个？》](https://time.geekbang.org/column/article/140181)一文中已经向你做过详细介绍了，它是由源节点、主干结点和边缘节点组成。它们的具体作用我这里就不做赘述了，记不清的同学可以回顾一下那篇文章。

当共享端将媒体流分享到 CDN 网络后，媒体流在 CDN 内部的流转过程是十分复杂的。现在我们只要简单理解为，CDN网络通过主干结点将流推送到各边缘节点，观看端就近接入到CDN网的边缘节点就可以获取到它想观看的“节目”了。

观看端就近接入到 CDN 的边缘节点，使得它与CDN节点之间能够使用最好的网络线路传输音视频数据，从而达到非常好的音视频服务质量。

## CDN就近接入

CDN网络为了保证用户的音视频服务质量，它会让观众在观看节目时，就近接入到距离最近的CDN边缘节点。

咱们来举个例子，一名主播使用上海电信的网络分享它的“节目”，那么使用北京联通网络的观众想看该节目时，如何能得到更好的用户体验呢？换句话说，是观众从上海电信的节点上拉取到的音视频流的服务质量好呢，还是从北京联通的节点上拉取到的音视频流的服务质量好呢？我想答案是不言而喻的！

那么，CDN 网络是如何让用户就近接入到北京联通的边缘节点上的呢？这里的关键点就是 DNS 解析。

### 1. DNS 解析原理

要想解开CDN让用户就近接入的秘密，我们就必须要了解 DNS 的解析原理。下面这张图就是 DNS 解析原理的示意图：

<img src="https://static001.geekbang.org/resource/image/50/a9/504b7cbf63f82f616e4bc8e5baa767a9.png" alt="">

接下来，我们就对这张图做一下解析，看看 DNS 是如何工作的。假设你要访问 [learningrtc.cn](http://www.learningrtc.cn) 这个网址，浏览器收到你的命令后，会向本地DNS（如 Google 的 DNS 服务器 8.8.8.8） 的 53 端口（TCP/UDP都使用同样的端口）发送域名解析请求。

本地DNS收到该请求后，首先查看自己的缓存中是否已经有该域名的记录了。如果有，则直接返回该域名的 IP 地址。如果没有，它会按下列步骤查询域名所对应的IP地址。

- 步骤1：本地DNS向根域名发送查询请求。
- 步骤2：根域名一般都会说“我不知道”，但可以再问问 .net 顶级域名的服务地址。
- 步骤3：本地DNS获取到 [.net](https://learning.net) 顶级域名服务地址后，就向顶级域名服务发送查询域名IP地址的请求。
- 步骤4：如果顶级域名也不知道要查询域名的IP地址的话，它会给本地 DNS 返回二级域名服务地址。

通过这样的步骤，经过本地DNS一级一级的查询，最终才能确定浏览器访问域名的IP地址是多少。

### 2. CDN就近接入原理

当用户访问 CDN 网络时，它首先通过智能DNS获取与用户距离最近的边缘节点，如下图所示：

<img src="https://static001.geekbang.org/resource/image/00/3d/002237a6925afbdab0d05660fae6693d.png" alt="">

那么智能 DNS 是如何找到距离用户最近的CDN边缘节点的呢？

智能DNS与传统DNS解析略有不同。传统DNS不判断访问者来源，当有多个IP地址可用时，DNS会随机选择其中一个IP地址返回给访问者。而智能DNS会判断访问者的来源，也就是说，它会对访问者的IP地址做判断，对不同的访问者它会返回不同的IP地址。智能DNS可以根据用户的IP地址找到它所在的地区、使用的运营商等。通过这些信息，它就可以让访问者在访问服务的时候，获得最优的CDN 边缘节点，从而提升服务的质量。

## CDN的使用

了解了上面的原理后，接下来我们就来具体实操一下，看看如何通过 CDN 网络实现万人直播。

### 1. 开通 CDN 业务

在使用CDN业务之前，我们需要先在所使用的云服务厂商那里开通CDN服务。各云厂商开通CDN服务的步骤可能略有不同，但大同小异，我们只需要在云厂商提供的管理界面进行开通即可。

云厂商的CDN服务可以用于多种业务，如图片加速、文件加速、点播、直播等等。而我们这里是将它用于直播系统，所以在开通 CDN 的时候，一定要选对业务类型，这样它才能真正为我们提供服务。

另外，一般情况下CDN业务开通后还不能直接使用，还需要对账户进行充值。在管理界面生成推/拉流地址时，如果账户中没有钱，它就不给你产生推拉流地址。必竟天下没有免费的午餐，这一点是需要你特别注意的。

### 2. 申请域名

要想通过 CDN 来实现万人直播，除了开通CDN业务之外，还必须要有自己的域名。比如，我们分享了一个直播间地址给观众，观众只要访问该地址就可收听/观看我们的节目了，那这个地址一定是我们自己的域名构成的。

申请域名的方法非常简单，你可以到任何一家云服务厂商去购买，如阿里、腾讯、亚马逊或Google等等。域名的价格有高有低，因为我们只是做实验使用，所以购买最便宜的即可。

另外，需要注意的是，如果你是购买的国内域名，则还需要进行备案，域名在没有备案成功之前是无法使用的。备案的主要目的是为了确认你要通过该域名做些什么事情。

### 3. 域名解析

域名申请好并备案成功后，接下来我们就可以对域名进行配置了。域名的配置主要分为两步：一是对CDN直播域名的配置，二是在域名管理中对前面配置好的直播域名进行映射。

首先，我们来看一下如何对 CDN 直播域名进行配置：打开直播控制台的域名管理，点击添加域名，在弹出的添加域名界面中，添加上我们的直播域名即可。比如我的域名为 learningrtc.cn，因此我可以将直播域名写成 pushcdn.learningrtc.cn。

通过上面步骤添加好直播域名后，云厂商的直播管理系统会给我们返回真正的直播域名。比如我添加的 pushcdn.learningrtc.cn 直播域名，其实它真正的 CDN 域名地址为 pushcdn.learningrtc.cn.w.alikunlun.net。也就是说 pushcdn.learningrtc.cn 只不过是一个伪域名。

通过上面的描述我们可以知道，要想让用户访问在 pushcdn.learningrtc.cn 域名时，转到CDN真正的直播域名pushcdn.learningrtc.cn.w.alikunlun.net，那么我们还需要在云厂商的域名管理系统中配置一条 DNS CNAME 的记录。这样，在 DNS 解析时就会进行跳转，从而解析出真正提供服务的 IP 地址。

### 4. 生成推/拉流地址

域名配置好之后，我们就可能生成推/拉流地址了。在云厂商的直播管理界面中，专门有用于生成推/拉流地址的操作界面。

其操作非常简单，首先是选择要使用的直播域名，该域名就是我们上面配置好的域名，然后填入你的 Application 名字，最后是填入直播流（房间）名字。这些配置信息填好后，点击生成按钮，就可以生成直播的推流地址和拉流（播放）地址了。

通过上面的描述我们可以知道，在 CDN 网络的内部应该也是使用的 Nginx 或与 Nginx 相类似的流媒体服务器。因为从它的配置上看，与我们在上一篇文章中所介绍的配置是一致的。

下图是生成推流与拉流地址的拼接格式：

<img src="https://static001.geekbang.org/resource/image/ef/84/ef17751079eb90181246b786dc724e84.png" alt="">

### 5. 推流与播放

配置好CDN的推/拉流地址后，接下来我们就可以进行测试了。

相关的推流工具有 FFmpeg、OBS、自己通过 librtmp库实现的推流客户端等；拉流工具包括 VLC、FFplay、Flash、flv.js 、video.js等。因为这些工具我们在上一篇文章中已经介绍过了，所以这里就不再赘述了。

需要特别强调的是， OBS 这个推流工具是非常专业的推流工具，并且各个操作系统上都有对应的OBS客户端。比如在实际的测试中，我们可能会发现使用 FFmpeg 推流时，声音的质量非常差，但如果使用 OBS 工具推流的话，音质就非常好了。

## 小结

本文我们首先介绍了 CDN 实现万人直播的架构。通过该架构你会发现，它与我们上一篇文章介绍的架构没有什么区别，只是将 RTMP流媒体服务器换成了 CDN 网络而已，而这正是本质的差别。

之所以 CDN 网络可以支持万人直播，就是因为在 CDN 网络内部做了大量的工作，如网络、操作系统、CPU内存等的优化。正是通过这点点滴滴的优化才能做到上万人、甚至几十万人同时在线观看节目的效果。

之后，我又详细向你介绍 DNS 解析原理以及 CDN 就近接入原理。了解 DNS 解析原理对于你理解 CDN是至关重要的，只有对它理解清楚了之后，你才能理解智能DNS；而理解了智能 DNS后，你才可以理解用户是如何实现就近接入 CDN 边缘节点的。

中国的互联网分家为北联通、南电信之后，网络环境越来越复杂。各大运营商之间、各地区之间的自我保护导致我们在跨运营商、跨地区传输数据时会遇到各种各样的网络状况，如主动丢包、延迟增大、传输抖动等等。解决这个问题的最好办法就是“就近接入”，让用户在自己地区所在的运营商接入网络，而跨运营商、跨地区的数据传输交由 CDN 网络使用专用网进行传输，这样就可以让用户享受到更好的音视频服务质量了。

在文章的最后，我们还讲述了如何开通 CDN 服务，以及如何使用 CDN 网络。这部分的知识可能有点琐碎，但却是我们实践CDN网络必不可少的一步，所以搞清楚这部分内容依然很重要。

## 思考时间

你知道配置DNS记录时它都有哪些类型吗？各不同类型的含义是什么呢？

欢迎在留言区与我分享你的想法，也欢迎你在留言区记录你的思考过程。感谢阅读，如果你觉得这篇文章对你有帮助的话，也欢迎把它分享给更多的朋友。


