「完整」不是「能推能看」,是六块都得有。 三条容量线里先撞哪条,取决于网卡多大。
14.1 讲了架构,这一节讲一个真系统要装哪几块。 14.2.2 换成现成的开源项目来对比。
一、六块拼图
一个能长期跑的直播系统,至少要六块:
模块 做什么 少了会怎样
接入 RTMP 1935、HTTP-FLV 8080 收推流,发播放 切片 HLS 的 m3u8 与 ts 兼容性兜底 录像 按流名建目录 回看与取证 鉴权 推流密钥、播放 token 防蹭流 状态 HTTP 接口报在线数 监控与调度 守护 进程退出自动拉起 夜里不宕
前两块是功能,后四块是「能不能长期跑」。
教材里的示例系统通常只做前两块, 所以拿示例直接上线,第一周就会遇到「被人白蹭流量」和「半夜挂了没人知道」。
这四块里最容易被忽略的是「状态」: 没有在线数接口,就没法做调度,也没法知道「到底几个人在看」。 而它恰恰是最便宜的——一个返回 JSON 的 HTTP 接口,二十行代码。
二、最小系统的三个端口
一个最小直播系统只需要三个端口,各管一件事:
端口 用途 能绑吗
1935 RTMP 推流与拉流 能 8080 HTTP-FLV 与状态接口 能 8000 HLS 静态目录 能
这三个端口在所有教程里都长这样,不是巧合——它们已经成了事实标准。 1935 是 RTMP 的默认端口,8080 是 HTTP 的备用端口,8000 是 Nginx 的常用端口。
「能绑」只说明本机没被占,不代表外面能连—— 云服务器还要放行安全组,这一条在第 11.3.1 节已经栽过一次。
还有一个容易忽略的点:HLS 的目录必须能被 Web 服务器直接读到。
所以切片目录通常直接放在 Nginx 的 html 目录下,
而不是随便找个地方——否则观众请求 m3u8 时就是 404。
三、三条容量线,先撞哪条
一台机器能扛多少路,取决于三条线里最低的那条:
网卡 CPU 限 内存限 带宽限 上限 卡在哪
100 Mbps 800 2048 50 50 带宽 1 Gbps 800 2048 500 500 带宽 10 Gbps 800 2048 5000 800 CPU
注意最后一列:三条线的交叉点会随网卡变。 100 Mbps 与 1 Gbps 时卡在带宽(50 与 500 路),到了 10 Gbps 就变成 CPU 先撞(800 路)。
所以「先撞哪条」不是固定的,取决于你的网卡有多大: 小水管时代花钱买带宽,大水管时代花钱买核。
这也解释了为什么直播比点播贵——点播可以缓存,直播不能。 同样一路流,点播一天只出一次,直播每个观众都要出一份。
四、录像要多少盘
录像容量一算就清楚,但算完通常会吓一跳:
时长 一路流 一百路流
1 小时 0.9 GB 90 GB 1 天 21.6 GB 2160 GB 30 天 648.0 GB 64800 GB
一路 2 Mbps 的流录一天是 21.6 GB,一百路就是 2160 GB。 而且这还是不算索引与冗余的裸容量。
所以「录像保留三十天」这个需求,在提之前最好先算一遍—— 它往往比服务器本身贵十倍。
真想省,有三条路: ① 降码率单独录一份(不要把推流那份原样存下来); ② 只录关键时段(比如只在有人观看时录); ③ 转成 H.265 存,同样画质能省三四成。 三条路的共同点是:先想清楚「录来干什么」,再决定录什么。
五、动手 Demo:完整的流媒体服务器系统——六块拼图与三条容量线
先真绑三个端口、真写一份 HLS 索引,看一个最小系统长什么样。 再把容量与存储按真实参数算一遍。
import os, socket
# 1. 三个端口各管一件事,真绑一遍
for name, port in (("RTMP", 1935), ("HTTP", 8080), ("HLS", 8000)):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
s.bind(("0.0.0.0", port))
s.listen(4)
print(name, port, "能绑")
except OSError as e:
print(name, port, "绑不上", e)
finally:
s.close()
# 2. 真写一份 HLS 索引,三片各 2 秒
os.makedirs("hls/livestream", exist_ok=True)
with open("hls/livestream/index.m3u8", "w") as f:
f.write("#EXTM3U\n#EXT-X-VERSION:3\n")
f.write("#EXT-X-TARGETDURATION:2\n")
for i in range(3):
f.write("#EXTINF:2.000,\nseg%d.ts\n" % i)
f.write("#EXT-X-ENDLIST\n")
# 3. 三条容量线,取最小值
for nic, mbps in (("100 Mbps", 100), ("1 Gbps", 1000), ("10 Gbps", 10000)):
by_cpu = int(8 / 0.01)
by_mem = int(8192 / 4)
by_bw = int(mbps / 2.0)
print(nic, "上限", min(by_cpu, by_mem, by_bw))
实跑输出:
--------------------------------------------------------------------
完整的流媒体服务器系统——六块拼图与三条容量线
--------------------------------------------------------------------
**① 「完整」不是「能推能看」,是六块都得有**
模块 做什么 少了会怎样
--------------------------------------------------------
接入 RTMP 1935、HTTP-FLV 8080 收推流,发播放
切片 HLS 的 m3u8 与 ts 兼容性兜底
录像 按流名建目录 回看与取证
鉴权 推流密钥、播放 token 防蹭流
状态 HTTP 接口报在线数 监控与调度
守护 进程退出自动拉起 夜里不宕
**前两块是功能,后四块是「能不能长期跑」。**
**教材里的示例系统通常只做前两块,**
**所以拿示例直接上线,第一周就会遇到「被人白蹭流量」和「半夜挂了没人知道」。**
**② 真起一个最小系统**
**三个端口分别对应接入、状态、切片目录。这里真绑一遍,再真写一份索引。**
端口 用途 能绑吗
-------------------------------------------
1935 RTMP 推流与拉流 能
8080 HTTP-FLV 与状态接口 能
8000 HLS 静态目录 能
**索引文件写了 143 字节,三片,每片 2 秒,一共 6 秒的内容。**
**「能绑」只说明本机没被占,不代表外面能连——**
**云服务器还要放行安全组,这一条在第 11.3.1 节已经栽过一次。**
**③ 三条容量线,先撞哪条**
网卡 CPU 限 内存限 带宽限 上限 卡在哪
-----------------------------------------------------------------
100 Mbps 800 2048 50 50 带宽
1 Gbps 800 2048 500 500 带宽
10 Gbps 800 2048 5000 800 CPU
**注意最后一列:三条线的交叉点会随网卡变。**
**100 Mbps 与 1 Gbps 时卡在带宽(50 与 500 路),到了 10 Gbps 就变成 CPU 先撞(800 路)。**
**所以「先撞哪条」不是固定的,取决于你的网卡有多大:**
**小水管时代花钱买带宽,大水管时代花钱买核。**
**这也解释了为什么直播比点播贵——点播可以缓存,直播不能。**
**同样一路流,点播一天只出一次,直播每个观众都要出一份。**
**④ 录像要多少盘,一算就清楚**
时长 一路流 一百路流
------------------------------------
1 小时 0.9 GB 90 GB
1 天 21.6 GB 2160 GB
30 天 648.0 GB 64800 GB
**一路 2 Mbps 的流录一天是 21.6 GB,一百路就是 2160 GB。**
**而且这还是不算索引与冗余的裸容量。**
**所以「录像保留三十天」这个需求,在提之前最好先算一遍——**
**它往往比服务器本身贵十倍。**
1935、8080、8000 三个端口都能绑上,说明本机没被别的服务占着。 索引写了 143 字节,三片各 2 秒,一共 6 秒的内容。 容量那条线:100 Mbps 与 1 Gbps 都卡在带宽(50 与 500 路), 到了 10 Gbps 才轮到 CPU(800 路)——因为带宽限一下涨到了 5000。 三条线永远是取最小值,而最小值会随网卡变化。 所以扩容前先看「现在卡在哪」,再决定花钱买什么。
30 秒实验
- 把 HLS 目录放到别的盘、不做软链,猜播放会怎样——请求 m3u8 返回 404,因为 Web 服务器读不到那个目录。
- 把 1935 改成 1936,猜推流端要改什么——推流地址里的端口,漏改就一直连不上。
- 一百路流保留三十天又不做降码率,猜要多少盘——64.8 TB 裸容量,做冗余还要翻倍。
常见误区
- 「能推能看就是完整系统」——少了鉴权、状态、守护就上不了线。
- 「容量就是 CPU 决定的」——带宽往往先撞,看网卡多大。
- 「录像占不了多少空间」——一路一天 21.6 GB,一百路就是两 TB。
自测三问(点开对答案)
1. 最小直播系统的三个端口分别干什么? —— **1935 收 RTMP、8080 发 HTTP-FLV 与状态、8000 放 HLS 文件**。 2. 三条容量线怎么取? —— **取最小值**,而且最小值会随网卡大小变化。 3. 一路 2 Mbps 录一天要多少空间? —— **21.6 GB**,一百路就是 2160 GB。- ☐ (本节完,下一节 14.2.2 开源的流媒体服务器项目应用)