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 秒实验
- 把
listen改成 1936,看它落在哪一栏——从「白写」变成「改过了」。 - 删掉
hls整块,猜切片还开不开——还开,enabled默认是 on。 - 故意把
daemon写成damon,猜 SRS 会怎样——不报错,当成新键忽略,daemon仍是默认的 off。
常见误区
- 「配置文件没写的都是关的」——多数是开的,要看默认值。
- 「写上去就一定生效」——键名拼错会被静默忽略。
- 「配置越长越完整」——写一堆等于默认值的行没有意义。
自测三问(点开对答案)
1. `http_server` 不写会怎样? —— **多数版本默认就开着 8080**,端口照样被占。 2. 键名拼错会报错吗? —— **不会**,SRS 把它当新键忽略掉。 3. 只有某个域名出问题,去查哪一层? —— **vhost 层**,全局层出问题是所有流都受影响。- ☐ (本节完,下一节 11.4.2 srs.conf)