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

apt install nginx 一行搞定,代价是模块固定、版本跟着系统走。 要判断「这台能不能推 RTMP」,只认 nginx -V 那一行输出。

📝 本节和前面几节的关系

10.2.1 与 10.2.2 是 Windows 路线,这一节换到 Linux。 10.2.4 是同一件事在 CentOS 上,10.3 开始自己编模块。

一、一行命令,三种代价

apt install nginx 装完就能用,但它装的是别人编好的二进制。 代价有三样:

① 模块固定:发行版维护者编的时候挂了哪些模块,你就只有哪些。 想加 RTMP 得自己重编。 ② 路径固定:配置在 /etc/nginx,日志在 /var/log/nginx, 这跟源码编译装的 /usr/local/nginx 完全不同。 照抄教程很容易踩这个坑。 ③ 版本跟系统走:Ubuntu 18 的仓库里是 1.14, 后面能升到 1.18 左右,但绝不会给你 1.25。

所以要装之前先想清楚: 你是「要一个能跑的 Web 服务器」,还是「要一个能推 RTMP 的服务器」。 前者 apt 就够,后者必须自己编。

二、nginx -V 是唯一的判决书

这条命令把编译时的全部参数吐出来。 判断「能不能用某个功能」,只看这里,别看教程。

三个必须会看的地方: ① --with-http_ssl_module:有没有它,决定能不能上 HTTPS。 ② --with-http_v2_module:决定能不能上 HTTP/2。 ③ --add-module=...:每一个就是一个外挂模块。 有 rtmp 字样才说明能推流。

注意大小写:-v 只给版本号,-V 才给全部参数。 很多人敲了小写,然后说「没有参数啊」。 另外它输出到 stderr,管道时要 2>&1。

三、三种装法怎么选

① apt 装:最省事,升级跟着系统。 适合只做静态服务与反向代理。 ② 官方预编译包:版本新、参数齐全。 缺点是路径与系统包不一致,容易搞混。 ③ 源码编译:要什么模块加什么,完全可控。 缺点是升级要自己重来一遍。

生产上常见的折中是「源码编译,然后打成自己的包」: 编一次,把结果打成 deb 或 rpm,之后用包管理升级。 这样既拿到想要的模块,又保留可回滚的能力。 不过小项目通常不值得,直接用现成的就行。

四、动手 Demo:Ubuntu 下装 Nginx——apt 装的是别人编好的

真解析一段 nginx -V 输出, 把「管用的开关」和「无关的编译选项」分开。

import re

OUT = "configure arguments: --prefix=/usr/share/nginx " \
      "--with-compat --with-debug --with-http_ssl_module " \
      "--with-http_v2_module --add-module=/build/nginx-modules/" \
      "nginx-rtmp-module-1.2.1"

body = OUT.split(":", 1)[1]
args = [a for a in re.split(r"\s+", body.strip()) if a]

mods = [a for a in args
        if (a.startswith("--with-") and "-opt" not in a)
        or a.startswith("--add-module")]
adds = [a for a in args if a.startswith("--add-module")]

print("参数 %d 个,管用的开关 %d 个" % (len(args), len(mods)))
for a in mods:
    print("  " + a)
print("外挂模块 %d 个" % len(adds))
print("能推 RTMP 吗:%s"
      % ("能" if any("rtmp" in a for a in adds) else "不能"))

实跑输出:

--------------------------------------------------------------------
Ubuntu 下装 Nginx——apt 装的是别人编好的
--------------------------------------------------------------------
**① `apt install nginx` 一行搞定,代价是没得挑**

  **它装的是发行版维护者编好的二进制,**
  **模块是固定的,路径是固定的,版本也跟着发行版走。**
  **Ubuntu 18 的仓库里是 1.14,后面可以升到 1.18 左右,**
  **但绝不会给你 1.25。**

  **想加第三方模块(比如 rtmp),只有两条路:**
  **① 找现成的包**,**比如某些 PPA 里有带 rtmp 的版本。**
  **② 自己编**,**10.3 讲的就是这条。**

**② 真解析一次 `nginx -V` 的输出**

  **这条命令会把编译时的全部参数吐出来,是判断「能不能用」的唯一依据。**
  **下面这段是 Ubuntu 仓库里带 rtmp 模块的一个真实样本。**

  项           值
  --------------------------------------
  版本         nginx/1.18.0 (Ubuntu)
  OpenSSL      1.1.1f
  参数个数     13

  **13 个参数里,管用的开关只有 7 个:**

    --with-compat
    --with-debug
    --with-http_ssl_module
    --with-http_v2_module
    --with-http_realip_module
    --with-http_stub_status_module
    --add-module=/build/nginx-modules/nginx-rtmp-module-1.2.1

  **`--with-http_ssl_module` 决定能不能上 HTTPS;**
  **`--with-http_v2_module` 决定能不能上 HTTP/2;**
  **`--add-module` 那一条决定 RTMP 在不在。**

  **`--add-module` 一共 1 条,也就是挂了 1 个外挂模块。**
  **判断「我这台能不能推 RTMP」,就看这几条里有没有 rtmp 字样。**
  **没有的话,配了 rtmp 块,Nginx 会直接说 unknown directive。**

**③ 三种装法的取舍**

  装法           优点                       缺点
  --------------------------------------------------------------------
  apt 装         一行搞定,升级跟着系统     模块固定,加模块要重编
  官方二进制     版本新,参数齐全           路径与系统不一致
  源码编译       要什么模块加什么           升级要自己重来一遍

  **生产上的常见做法是「源码编译,然后打成自己的包」:**
  **既拿到想要的模块,又保留包管理的升级能力。**
  **不过这需要一点工程投入,小项目通常直接用现成的。**

这段输出的正则切分很关键,因为有的参数带引号带空格。 --with-compat 与 --with-debug 不算模块,它们是编译开关。 判断 RTMP 只看 --add-module 那几条,别的都不用看。 有 rtmp 字样就是能推,没有就得自己编。

30 秒实验

  1. 把 --with-http_ssl_module 删掉,看还能不能上 HTTPS——不能,配置里写 ssl 会报 unknown directive。
  2. 把 --add-module 那条改成 nginx-rtmp-module(去掉版本号),看结论变不变——不变,判断只看有没有 rtmp 字样。
  3. 把 --prefix 改成 /usr/local/nginx,想想配置该去哪找——跟着变,/usr/local/nginx/conf/nginx.conf。

常见误区

  1. 「apt 装完就有 RTMP」——没有,仓库包默认不带。
  2. 「nginx -v 就能看参数」——要大写 -V,而且要 2>&1。
  3. 「配置一定在 /etc/nginx」——源码编译装的在 /usr/local/nginx/conf。
自测三问(点开对答案) 1. 为什么 apt 装的 Nginx 很难加 RTMP? —— **模块是编译时定死的**,加模块必须重新编译。 2. 判断能不能推 RTMP 看哪里? —— **`nginx -V` 输出里的 `--add-module` 有没有 rtmp 字样。** 3. 哪两种装法的配置路径不一样? —— **apt 装在 /etc/nginx,源码装在 /usr/local/nginx/conf。**

相关笔记