🎬 第十一章 SRS搭建直播平台
📄 一句话概括

SRS 的配置只写「和默认不一样的」,其余靠代码里的默认值。 所以你看到的配置,不等于实际生效的配置。

📝 本节和前面几节的关系

11.3.2 用了 cluster 块,这一节讲整个配置是怎么组织的。 11.4.2 到 11.4.4 是三份具体配置的逐行拆解。

一、只写和默认不一样的

SRS 有几百个配置键,绝大多数带默认值。 一份能跑的配置往往只有几十行,剩下的全由默认值补齐。

这带来一个很实际的坑: 你看配置文件以为某项是关的,其实它默认是开的。 典型例子是 http_server:很多版本默认就开着 8080。 你没写,端口也占了,查端口占用时才发现是 SRS。

反过来也一样: 你写了但写的和默认一样,那几行等于白写,看着像配置过,其实没改任何东西。

二、真跑:写了十一个,只有六个起作用

拿一份写了十一项的配置,和下表的默认值逐项比: 结果只有六个真的改了默认值,五个写的和默认一模一样。

这说明两件事: ① 配置文件的长度不代表配置的复杂度; ② 排查「某项为什么不生效」时,第一步是确认它到底有没有被写进去。

还有一个更隐蔽的情况:键名拼错。 SRS 不会为此报错,它只是把这一行当成一个不认识的新键,默默忽略。 表现就是「我明明配了,怎么还是默认值」。

三、三层结构

认清层,配置就好找了:

① 全局层:listen、max_connections、daemon、日志。 这些和任何 vhost 无关。 ② 服务层:http_server、rtc_server、srt_server。 每种协议一个块,块里是这个协议自己的参数。 ③ vhost 层:hls、dvr、play、publish、cluster。 这些按虚拟主机隔离,不同 vhost 互不影响。

这三层可以直接用来定位问题: 「所有流都受影响」去全局层找,「只有某个域名有问题」去 vhost 层找。 这个判断能省掉一半的翻配置时间。

四、动手 Demo:配置文件组成——你写一半,生效的是全部

把一份最小配置解析成扁平表, 再和默认值逐项对照,看哪几行真的起了作用。

DEFAULTS = {
    "listen": "1935",
    "max_connections": "1000",
    "daemon": "off",
    "http_server.listen": "8080",
    "vhost.hls.enabled": "on",
    "vhost.hls.hls_fragment": "10",
    # ... 其余省略
}

mine = flatten(MIN_CONF)      # 点分路径 -> 值

for k in sorted(set(DEFAULTS) | set(mine)):
    if k not in mine:
        print(k, "没写", DEFAULTS[k], "用默认")
    elif k not in DEFAULTS:
        print(k, "写了", mine[k], "默认里没有")
    elif mine[k] == DEFAULTS[k]:
        print(k, "写了", mine[k], "一样,白写")
    else:
        print(k, "写了", mine[k], "改过了")

实跑输出:

--------------------------------------------------------------------
配置文件组成——你写一半,生效的是全部
--------------------------------------------------------------------
**① 配置文件只写「和默认不一样的」**

  **SRS 的配置有几百个键,但绝大多数有默认值。**
  **所以一份能跑的配置往往只有几十行,**
  **剩下的靠代码里的默认值补齐。**

  **这带来一个问题:**
  **你看配置文件以为某项是关的,其实它默认是开的。**
  **典型的例子是 `http_server`——很多版本默认就开着 8080,**
  **你没写,端口也占了。**
  **查端口占用时发现 8080 被 SRS 占了,就是这么来的。**

**② 真跑:把最小配置补齐成「实际生效值」**

  **下面这份配置只写了十几项,**
  **把它和默认值表合起来,才是 SRS 真正在用的那套。**

  键                         写了吗     生效值                           和默认比
  -------------------------------------------------------------------------------------
  daemon                     写了       on                               改过了
  http_server.dir            写了       ./objs/nginx/html                一样,白写
  http_server.enabled        没写       on                               用默认
  http_server.listen         写了       8080                             一样,白写
  listen                     写了       1935                             一样,白写
  max_connections            写了       1000                             一样,白写
  pid                        没写       ./objs/srs.pid                   用默认
  srs_log_level              没写       trace                            用默认
  srs_log_tank               写了       file                             改过了
  vhost.cluster.mode         没写       local                            用默认
  vhost.dvr.dvr_path         写了       ./objs/nginx/html/[app]/[s..     默认里没有
  vhost.dvr.enabled          写了       on                               改过了
  vhost.hls.enabled          写了       on                               一样,白写
  vhost.hls.hls_fragment     写了       5                                改过了
  vhost.hls.hls_window       写了       30                               改过了
  vhost.play.gop_cache       没写       on                               用默认
  vhost.publish.mr           没写       off                              用默认

  **17 个键里,配置里写了 11 个、没写 6 个。**

  **但写了的 11 个里,只有 6 个真的改了默认值,**
  **另外 5 个写的和默认一模一样——等于白写。**

  **这才是「写一半、生效全部」的真实比例:**
  **17 个键里,真正被这份配置改变的是 6 个。**
  **所以排查「某项为什么不生效」时,第一步永远是确认它到底有没有被写进去。**
  **写错了一个字母,SRS 不会报错,只是把它当成新键忽略了。**

**③ 结构本身就是三层**

  **① 全局层**:**`listen`、`max_connections`、`daemon`、日志。**
  **这些和任何 vhost 无关。**
  **② 服务层**:**`http_server`、`rtc_server`、`srt_server`。**
  **每种协议一个块。**
  **③ vhost 层**:**`hls`、`dvr`、`play`、`publish`、`cluster`。**
  **这些是按虚拟主机隔离的,不同 vhost 互不影响。**

  **认清这三层,配置就好找了:**
  **「所有流都受影响」的问题去全局层找,**
  **「只有某个域名有问题」的去 vhost 层找。**
  **这个判断能省掉一半的翻配置时间。**

十七个键里,写了十一个、没写六个。 写了的那十一个里,只有六个真的改了默认值。 另外五个写的和默认一模一样,看着配了,其实什么也没改。 dvr_path 这种默认表里没有的键,写它才是真有意义的。

30 秒实验

  1. 把 listen 改成 1936,看它落在哪一栏——从「白写」变成「改过了」。
  2. 删掉 hls 整块,猜切片还开不开——还开,enabled 默认是 on。
  3. 故意把 daemon 写成 damon,猜 SRS 会怎样——不报错,当成新键忽略,daemon 仍是默认的 off。

常见误区

  1. 「配置文件没写的都是关的」——多数是开的,要看默认值。
  2. 「写上去就一定生效」——键名拼错会被静默忽略。
  3. 「配置越长越完整」——写一堆等于默认值的行没有意义。
自测三问(点开对答案) 1. `http_server` 不写会怎样? —— **多数版本默认就开着 8080**,端口照样被占。 2. 键名拼错会报错吗? —— **不会**,SRS 把它当新键忽略掉。 3. 只有某个域名出问题,去查哪一层? —— **vhost 层**,全局层出问题是所有流都受影响。

相关笔记