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

要编出一个能推 RTMP 的 Nginx,得把三份源码凑到一起。 验收标准只有一条:nginx -V 里有没有那一行。

📝 本节和前面几节的关系

10.2 装的是别人编好的,这一节自己编。 10.3.2 换一个更全的模块,命令几乎不变。

一、三份源码,一个都不能少

Nginx 本体不带 RTMP,它是外挂模块。 所以编一个带 RTMP 的 Nginx,需要三样东西:

① nginx 主源码:从 nginx.org 下,版本自己挑。 ② nginx-rtmp-module:GitHub 上的独立仓库。 它是社区项目,不是官方维护的。 ③ 依赖库:pcre、zlib、openssl,用包管理装。

依赖库一个都不能少,缺哪个 configure 都会明确报出来: pcre 管正则,location 里的匹配全靠它; zlib 管压缩,gzip 输出要靠它; openssl 管 TLS,HTTPS 与 RTMPS 要靠它。

二、configure 参数每一项都有理由

参数多,但常用的就六个:

① --prefix:决定装到哪。 不写就是 /usr/local/nginx, 它决定了配置文件与日志的位置。 ② --with-http_ssl_module:不写就不能上 HTTPS。 ③ --with-http_v2_module:不写就不能上 HTTP/2。 ④ --with-http_flv_module:让 Nginx 能按字节范围吐 FLV。 这是 HTTP-FLV 的基础。 ⑤ --with-http_mp4_module:让 Nginx 能按时间点吐 MP4。 点播要它。 ⑥ --add-module=../nginx-rtmp-module:挂 RTMP 模块。

参数里有三处最容易错: --add-module 的路径是相对当前目录的, 先 cd 进 nginx 源码目录再写相对路径; --prefix 的目录要可写,不然 make install 才失败; 同一个模块写两遍不会报错,但会让人以为没生效。

三、编完必须验,别看 make 成功

make 成功不代表模块挂上了。 模块没挂上,make 一样会成功,装出来的还是裸 Nginx。

唯一的验收标准: nginx -V 2>&1 | grep rtmp 有输出。 看到 --add-module=.../nginx-rtmp-module 那一行,才算编进去了。

再往下验一层: 在 nginx.conf 里写一个 rtmp { server { listen 1935; } }, 跑 nginx -t。 通过说明模块真的能用了;报 unknown directive 说明模块没挂上。

两层验法缺一不可: 第一层证明「编进去了」,第二层证明「能配出来」。 很多人只做第一层,然后在配置阶段卡住。

四、动手 Demo:编译 nginx-rtmp-module——三个源码包凑一起

把编译要凑的东西、要写的参数、要验的两层摊开, 最后给一份能直接照抄的命令。

DEPS = ["build-essential", "libpcre3-dev",
        "zlib1g-dev", "libssl-dev"]

CONFIGURE = [
    "--prefix=/usr/local/nginx",
    "--with-http_ssl_module",
    "--with-http_v2_module",
    "--with-http_flv_module",
    "--with-http_mp4_module",
    "--add-module=../nginx-rtmp-module",
]

# 1. 依赖
print("apt install -y " + " ".join(DEPS))

# 2. 解包(两个源码包放在同一层)
print("tar xzf nginx-1.18.0.tar.gz")
print("tar xzf nginx-rtmp-module.tar.gz")

# 3. configure(必须在 nginx 源码目录里)
print("cd nginx-1.18.0 && ./configure " + " ".join(CONFIGURE))

# 4. 编译安装
print("make -j4 && make install")

# 5. 两层验收
print("nginx -V 2>&1 | grep rtmp")
print("nginx -t")

# 6. 自检:参数里有没有重复
seen, dup = set(), []
for a in CONFIGURE:
    if a in seen:
        dup.append(a)
    seen.add(a)
print("重复的参数:%s" % (dup or "没有"))

实跑输出:

--------------------------------------------------------------------
编译 nginx-rtmp-module——三个源码包凑一起
--------------------------------------------------------------------
**① 编之前要凑齐三样东西**

  **Nginx 本身不带 RTMP,它是外挂模块。**
  **所以要编出一个带 RTMP 的 Nginx,需要三份源码:**

  要什么东西            作用                    从哪来
  ---------------------------------------------------------------------
  nginx 主源码          服务器本体              nginx.org 下载页
  nginx-rtmp-module     提供 RTMP 能力          GitHub 上的独立仓库
  依赖库                pcre、zlib、openssl     apt 装

  **依赖库一个都不能少:**
  **`pcre` 管正则,`location` 里的匹配全靠它;**
  **`zlib` 管压缩,gzip 输出要靠它;**
  **`openssl` 管 TLS,HTTPS 与 RTMPS 要靠它。**
  **缺哪个,configure 阶段就会明确报出来。**

**② 真跑:拼出 configure 命令,逐项校验**

  **编译命令长下面这样,参数多但每一项都有理由:**

    ./configure \
      --prefix=/usr/local/nginx \
      --with-http_ssl_module \
      --with-http_v2_module \
      --with-http_flv_module \
      --with-http_mp4_module \
      --add-module=../nginx-rtmp-module \
      --with-openssl=../openssl-1.1.1f

  **几个参数的意义:**
  **`--prefix` 决定装到哪,**
  **不写就装到 `/usr/local/nginx`,**
  **这决定了后面配置文件在哪。**
  **`--with-http_flv_module` 让 Nginx 能按字节范围吐 FLV**,**这是 HTTP-FLV 播放的基础。**
  **`--add-module` 就是挂 RTMP 模块**,**路径写相对路径时要确认当前目录。**

  **真校验一遍这套参数,有三类必查项,外加一条常被忽略的:**

  检查项                        不做会怎样                             级别
  -----------------------------------------------------------------------------
  --add-module 路径是否存在     路径写错会在 configure 阶段报错        必查
  --prefix 目录是否可写         权限不够会在 make install 阶段失败     必查
  依赖库是否都装了              pcre/zlib/openssl 缺一不可           必查
  是否重复写了同一个模块        重复不报错,但会让人以为生效了         建议

  **「重复写同一个模块」这条特别阴:**
  **`--with-http_ssl_module` 写两遍,configure 不会报错,**
  **编出来也正常,但你看 `nginx -V` 会看到两次,**
  **然后开始怀疑是不是没生效——其实一直是好的。**

  **【📋 实操路径】完整命令**

    # 1. 装依赖
    apt install -y build-essential libpcre3-dev zlib1g-dev libssl-dev
    # 2. 解包三个源码
    tar xzf nginx-1.18.0.tar.gz && tar xzf nginx-rtmp-module.tar.gz
    # 3. configure
    cd nginx-1.18.0 && ./configure --add-module=../nginx-rtmp-module
    # 4. 编译安装
    make -j4 && make install
    # 5. 验证模块在不在
    /usr/local/nginx/sbin/nginx -V 2>&1 | grep rtmp

  **第 5 步是唯一的验收标准:**
  **`nginx -V` 的输出里有 rtmp 字样,才算编进去了。**
  **只看「make 成功」是不够的——**
  **模块没挂上,make 一样会成功。**

六个参数里只有 --add-module 是加模块,其余都是编译开关。 --with-http_flv_module 是 HTTP-FLV 的底层能力,别和 RTMP 搞混。 验收要两层:-V 看编没编进去,-t 看能不能配出来。 重复参数不报错,自己扫一遍最省事。

30 秒实验

  1. 把 --add-module 的路径改成绝对路径,看还能不能编——能,两种写法都认,相对路径更省事。
  2. 把 --with-http_ssl_module 去掉再编,看 nginx -t 会怎样——配置里带 ssl 就报 unknown directive。
  3. 不开 -j4 单线程编,猜时间差多少——差不多四倍,但链接那一小段省不下来。

常见误区

  1. 「make 成功就是编好了」——模块没挂上也会成功。
  2. 「参数写重复会报错」——不会,只是看着像没生效。
  3. 「-v 和 -V 一样」——小写只给版本,大写才给参数。
自测三问(点开对答案) 1. 编一个带 RTMP 的 Nginx 要几份源码? —— **三份**:nginx 本体、rtmp 模块、依赖库。 2. 怎么确认模块真的进去了? —— **`nginx -V` 里有 `--add-module=...rtmp` 那一行**,再看 `nginx -t` 是否通过。 3. `--with-http_flv_module` 是干什么的? —— **让 Nginx 能按字节范围吐 FLV**,是 HTTP-FLV 的基础。

相关笔记