跳转至

EP17:从零部署:15 分钟跑起你自己的 CDN

在 YouTube 打开

上集回顾 EP16《如何应对突发性高并发场景》
下集预告 EP18《录像与回放:给直播加上 VOD》

0. 本集目标

看完这一集,观众应该能独立完成一次自建部署,具体是三件事:

  1. 部署准备:根据预期并发观众数,判断该部署一台 standalone 还是一套 origin + edge,要不要再加一台 record,以及为什么出口带宽比 CPU/内存更容易成为瓶颈。
  2. 部署过程:在控制台创建 ppmmx 节点拿到 License Code,用它配合官方一键部署脚本,在自己的云主机上几分钟内拉起节点。
  3. 部署验证:回到控制台确认节点状态变成"运行中",用 ppobs 填入 appId/appSecret 推一路流,再到控制台点 Preview 看到画面——整条链路才算真正跑通。

1. 部署准备:先定形态,再定规格

1.1 一张决策图

flowchart TD
    Start["预估这套自建节点要扛的<br/>最高并发观众数 n"] --> Q1{"n ≤ 200 ?"}
    Q1 -->|是| SA["部署 1 台 standalone 节点<br/>AWS 2vCPU/4GB 一台就够"]
    Q1 -->|否| OE["部署 1 台 origin + N 台 edge<br/>N = ⌈n / 200⌉,每台 2vCPU/4GB"]
    SA --> Q2{"需要录像功能?"}
    OE --> Q2
    Q2 -->|是| REC["再部署 1 台 record 节点<br/>由 origin 转发给它,不额外占播放带宽"]
    Q2 -->|否| Done["准备完成,进入部署过程"]
    REC --> Done
  • standalone(独立组网):单台机器同时承担"接推流"和"给观众播放"两件事,不转发、不回源、不参与跨节点调度。并发不高、只想要一个能跑起来的节点时,这是默认选择。
  • origin(接入)+ edge(分发):并发一旦超过单机承载上限,就要把"接流"和"分发给观众"拆开——origin 只管接住主播的流,再转发给一台或多台 edge 各自扛一部分观众。
  • record(录像):不服务任何观众播放,只被动接收 origin 转发来的流并落盘,所以不管后面挂了几台 edge,录像通常只需要一台。

1.2 为什么是 200 这个数字

这不是一个随手定的整数,而是留了安全余量之后的结果。官方对 ppmmx standalone 做过阶梯压测:在真正给得出带宽的云上(AWS Lightsail,实测公网出口约 2.4 Gbps),一台 2vCPU / 2GB 的节点干净扛住了 250 路并发 WHEP 观众、零断连;再加一档到 300 路才会因为内存耗尽失败。

AWS Lightsail 2vCPU/2GB 实测结果
250 路 ████████████████████████████████████████  PASS(零断连,仅剩 289MB 内存)
300 路 ████████████████████████████████████████████  FAIL(内存耗尽,主机失联)

把这条线搬到"建议值"时做了两件更保守的事:把门槛定在 250 以下的 200,并且建议用内存更宽裕的 2vCPU/4GB,而不是压测用的 2vCPU/2GB——多出来的内存全部变成余量,留给机型差异、系统开销和未来的编码升级。

1.3 关键不是 CPU,是出口带宽

同一份压测还对比了两家云厂商:

维度 标称 实测公网出口 200 路观众(约 2.5Mbps/路)够不够
某提供商小规格 VPS "1 Gbps" 实测只有 ~100 Mbps 不够——约 39 路就先撞到链路上限
AWS Lightsail "1 Gbps"(套餐) 实测 ~2.4 Gbps 够——200 路只用到约 500 Mbps

200 路 × 约 2.5 Mbps/路 ≈ 500 Mbps 实际出口带宽。很多便宜 VPS 标称"1 Gbps",实测只跑得出一两百 Mbps——这个差距只在实测里看得出来,套餐页面的数字不可靠。选型前一定要自己测一下这台机器的真实出口,而不是看标称值拍板。

1.4 选型对照表

预期并发观众数 n 需要录像? 部署方案 建议规格
n ≤ 200 否 1 台 standalone AWS 2vCPU/4GB × 1
n ≤ 200 是 1 台 standalone + 1 台 record AWS 2vCPU/4GB × 2
n > 200 否 1 台 origin + N 台 edge(N=⌈n/200⌉) AWS 2vCPU/4GB × (1+N)
n > 200 是 1 台 origin + N 台 edge + 1 台 record AWS 2vCPU/4GB × (2+N)

2. 部署过程:控制台拿 License Code,一键脚本跑起来

2.1 控制台创建节点

  1. 登录 PPCDN 控制台,打开 ppmmx 节点 标签页。
  2. 点 新增 ppmmx 节点:填节点名称,节点类型选 standalone / origin / edge / record 之一(对应上一节的方案)。
  3. 点 创建节点,立即拿到这台节点的 License Code(可以随时在列表里显示/复制)。
flowchart LR
    U["你"] -->|"1. 填节点名 + 选类型"| Console["控制台 · ppmmx 节点"]
    Console -->|"2. 创建节点"| Backend["ppcenter"]
    Backend -->|"3. 生成 License Code<br/>license_status = pending(未计费)"| Console
    Console -->|"4. 显示/复制"| U

计费口径:PPCDN 不收转码费,也不收推流方的上行带宽费,服务端是纯 RTP 透传、不解码不转码。创建节点本身免费,不限创建数量、放多久都不收钱;只有这台节点真的部署上线、第一次成功完成授权上报之后,状态才会从 pending 变成 active,从那一刻起按 $2.5 / 实例 / 天 计费,不限部署时长、不限节点规模。

2.2 一键部署脚本

拿着上一步的 License Code,到你自己准备好的云主机(例如前面选好规格的 AWS 实例)上执行官方 ppmmxDocker 仓库提供的一键脚本。

Linux(Ubuntu / Debian / CentOS / RHEL):

curl -fsSL https://raw.githubusercontent.com/ppcdn-org/ppmmxDocker/main/deploy.sh -o deploy.sh
chmod +x deploy.sh
./deploy.sh --license-code lic_xxx

Windows(需要先自己装好并启动 Docker Desktop):

Invoke-WebRequest -Uri https://raw.githubusercontent.com/ppcdn-org/ppmmxDocker/main/deploy.ps1 -OutFile deploy.ps1
.\deploy.ps1 -LicenseCode lic_xxx

全程只需要这一个 License Code 参数——节点类型在控制台创建时已经选过了,脚本会自动查回来,不用再填一次:

sequenceDiagram
    participant You as 你(云主机)
    participant Script as deploy.sh
    participant Center as ppcenter 控制面
    participant Node as ppmmx 容器

    You->>Script: ./deploy.sh --license-code lic_xxx
    Script->>Center: GET /v1/ppmmx/bootstrap?licenseCode=...
    Center-->>Script: 返回节点类型(standalone/origin/edge/record)
    Script->>Script: 自动装/检测 Docker、探测本机公网 IP、生成 .env
    Script->>Center: POST /v1/ppmmx/provision(换取 HTTPS 域名 + 自动 DNS)
    Script->>Node: docker compose up -d --build
    Node->>Center: WS 注册 + 之后每 0.5h 一次 LICENSE_REPORT
    Center-->>Node: LICENSE_ACK(首次通过后 license_status: pending → active,开始计费)

脚本顺带处理了两个容易踩坑的点:没装 Docker 会自动装(Linux);浏览器播放需要的 HTTPS 证书也是自动签发的——脚本凭 License Code 向 ppcenter 换一个专属域名并自动建好 DNS,不需要你手动买证书、配反代。


3. 部署验证:三步确认真的跑通了

3.1 控制台看节点状态

回到控制台的 ppmmx 节点 列表,这台节点的状态会按下面这条路径走:

stateDiagram-v2
    [*] --> pending: 控制台创建节点(未计费)
    pending --> active: 首次 LICENSE_REPORT 被接受\n(开始计费 $2.5/实例/天)
    active --> stale: 超过 2 小时未上报\n(自动停止计费)
    stale --> active: 重新上报成功(自愈,无需人工)
    active --> soft_deleted: 账户欠费(节点被下线)
    soft_deleted --> active: 充值后自动恢复

部署脚本跑完后,日志里看到 MMX control connected(没有 registration rejected),控制台这台节点的状态就应该变成"运行中"(active)——这是第一道确认信号。

3.2 用 ppobs 推流

  1. 在控制台 应用 标签页创建一个 App,拿到它的 appId 和 appSecret。
  2. 打开 ppobs(PPCDN 基于 OBS 定制的推流客户端),进入设置 → 直播。
  3. 服务 选 PPCDN,填入这个 App 的 appId / appSecret;入库协议默认 WHIP(实测经 Edge 入库约 108ms),弱网上行不稳时可切 SRT(约 386ms,差值来自入库协议而不是编码),存量 RTMP 设备可走 ERTMP;三种协议都能同播 HEVC + H264 多轨,不需要云端转码。
  4. 点 开始推流。
flowchart LR
    App["控制台 · 应用<br/>创建 App → appId + appSecret"] -->|"填入"| Obs["ppobs 设置 → 直播<br/>服务选 PPCDN"]
    Obs -->|"开始推流(WHIP / SRT)"| Node["你刚部署的节点<br/>standalone 或 origin"]

appSecret 等同于推流凭证,不要贴到公开页面或聊天记录里;ppobs 会用它向 ppcenter 自动换取当前最优节点的推流地址和鉴权 token,不需要手工拼地址。

3.3 控制台 Preview 预览播放

推流开始后,回到控制台的 推流记录 标签页、在线 子标签,能看到这条流出现在列表里,点一下 Preview:

flowchart LR
    Panel["控制台 · 推流记录 → 在线"] -->|"点击 Preview"| Sign["控制台按 appSecret<br/>签发临时播放链接"]
    Sign -->|"走正常拉流决策(HEVC 直连 Edge;H264 才可能 P2P)"| Player["弹出播放器(iframe)<br/>直接看到画面"]

能在这个弹窗里看到主播画面,才代表"推流 → 节点 → 播放"这条完整链路真正打通了——不是看到节点状态"运行中"就算完事,那只证明控制面连上了,不证明媒体能通。


4. 一张图看完整个 15 分钟

flowchart TD
    A["1. 部署准备<br/>按并发选 standalone 或 origin+edge(+record)"] --> B["2. 控制台创建节点<br/>拿到 License Code"]
    B --> C["3. 一键部署脚本<br/>deploy.sh / deploy.ps1 --license-code"]
    C --> D["4. 控制台确认节点状态<br/>pending → active(运行中)"]
    D --> E["5. ppobs 填 appId/appSecret 推流"]
    E --> F["6. 控制台 Preview 看到画面"]
    F --> G["全链路验证通过"]

5. 结尾与下集预告(逐字稿要点)

这一集走完了一次完整的自建部署:按预期并发(200 这条线)和是否要录像,决定部署 standalone 还是 origin + edge + record;出口带宽的真实值比机型标称的"1 Gbps"更值得相信。拿着控制台生成的 License Code,一条命令跑完 deploy.sh/deploy.ps1,节点就自动把类型、公网地址、HTTPS 证书都配好了。验证不能停在"控制台显示运行中"——还要用 ppobs 真推一路流,在控制台点开 Preview 看到画面,才算端到端跑通。

下一集,我们给这套跑起来的直播系统加上一块新能力:录像与回放——把直播流落成可按场次回放的 VOD。