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

CentOS 8 把 nginx 放进了 AppStream,dnf install nginx 直接能装。 装完还要会看 systemd 配置,因为句柄上限在那里设。

📝 本节和前面几节的关系

10.2.3 是 Ubuntu 路线,这一节换到 CentOS。 命令不同,但两件事完全一样:确认模块在不在、确认句柄够不够。

一、仓库变了,命令跟着变

CentOS 8 把软件分成两个仓库:BaseOS 与 AppStream。 nginx 在 AppStream 里,所以 dnf install -y nginx 直接能装。

但仓库里的版本偏旧。 要新版本得手动加一个 nginx.repo 指向官方源。 这是「同一个软件在三家发行版上三种装法」的典型例子。

还有一个现实问题:CentOS 8 已经停止维护。 现在新项目基本换成 Rocky 或 Alma,命令完全一样。 所以这一节学的东西不会白学。

二、systemd 配置里藏着句柄上限

装完之后它是被 systemd 管着的, 所以「怎么起、怎么停、最多开多少文件」全在 unit 文件里。

三处最该看: ① Type=forking:nginx 自己会转后台,systemd 得知道。 类型写错,systemd 会以为启动失败。 ② ExecStartPre:启动前先 nginx -t 检查配置。 配置写错就不会启动,这一句省掉很多「起不来看日志」的时间。 ③ LimitNOFILE:这就是文件句柄上限。 它在 systemd 里设,不在 nginx.conf 里设。

第 ③ 条最容易漏: worker_connections 写在 nginx.conf 里, 但如果 systemd 那边把句柄限成 1024,配多大都白配。 两处都要改,缺一不可。

三、reload 与 restart 不是一回事

systemctl reload nginx 发的是 HUP 信号: master 读完新配置,起新 worker,老 worker 处理完手上请求再退。 连接不断。

systemctl restart nginx 是停再起: 所有连接立刻断。 直播业务上这一下就是「全部观众重新连一次」。

所以规矩很简单: 改配置用 reload,只有改端口、改模块这种必须重启的才用 restart。 而且改完先 nginx -t 试一下,语法错了 reload 会失败但老进程还在——这一点比 restart 安全得多。

四、动手 Demo:CentOS 下装 Nginx——装完还要会看 systemd 配置

真解析一份 nginx 的 systemd unit 文件, 把「启动方式、配置检查、句柄上限」三处挑出来。

def parse_unit(text):
    out, sec = {}, ""
    for line in text.splitlines():
        s = line.strip()
        if not s or s.startswith("#"):
            continue
        if s.startswith("[") and s.endswith("]"):
            sec = s[1:-1]
            out.setdefault(sec, [])
            continue
        if "=" in s:
            k, v = s.split("=", 1)
            out.setdefault(sec, []).append((k.strip(), v.strip()))
    return out

u = parse_unit(UNIT_TEXT)
for sec in ("Unit", "Service", "Install"):
    print("[%s]" % sec)
    for k, v in u.get(sec, []):
        print("  %-14s %s" % (k, v))

svc = dict(u.get("Service", []))
print("启动类型:", svc.get("Type"))
print("句柄上限:", svc.get("LimitNOFILE"))
print("启动前检查:", svc.get("ExecStartPre"))

实跑输出:

--------------------------------------------------------------------
CentOS 下装 Nginx——装完还要会看 systemd 配置
--------------------------------------------------------------------
**① CentOS 8 的变化:把 nginx 挪到了 AppStream**

  **CentOS 8 把软件分成 BaseOS 与 AppStream 两个仓库。**
  **nginx 在 AppStream 里,所以 `dnf install nginx` 直接就能装。**
  **但仓库里的版本偏旧,要新版本得加官方仓库:**

    dnf install -y nginx
    # 想更新版本,就手动加一个 nginx.repo 指向 nginx.org 的仓库

  **顺带记住一件事:CentOS 8 已经停止维护,**
  **现在的新项目基本都换成了 Rocky 或 Alma,命令完全一样。**

**② 真解析一份 systemd 配置**

  **装完之后它是被 systemd 管着的,**
  **所以「怎么起、怎么停、最多开多少文件」全在这个文件里。**

  **Unit**
    Description    nginx - high performance web server
    After          network.target remote-fs.target nss-lookup.target
    Documentation  http://nginx.org/en/docs/

  **Service**
    Type           forking
    PIDFile        /run/nginx.pid
    ExecStartPre   /usr/sbin/nginx -t -c /etc/nginx/nginx.conf
    ExecStart      /usr/sbin/nginx -c /etc/nginx/nginx.conf
    ExecReload     /bin/kill -s HUP $MAINPID
    ExecStop       /bin/kill -s QUIT $MAINPID
    PrivateTmp     true
    LimitNOFILE    65535

  **Install**
    WantedBy       multi-user.target

  **这段里有三处值得记:**

  **① `Type=forking`**:**nginx 自己会转后台,systemd 得知道这一点。**
  **类型写错,systemd 会以为启动失败。**
  **② `ExecStartPre`**:**启动前先 `nginx -t` 检查配置。**
  **配置写错就不会启动,这一句能省很多「起不来看日志」的时间。**
  **③ `LimitNOFILE=65535`**:**这就是刚才说的那个句柄上限。**
  **它在这儿设,不在 nginx.conf 里设。**

  **第 ③ 条是最容易漏的:**
  **`worker_connections` 写在 nginx.conf 里,**
  **但如果 systemd 那边把句柄限成 1024,配多大都白配。**
  **两处都要改,缺一不可。**

**③ 常用操作就四条**

    systemctl start nginx     # 启动
    systemctl reload nginx    # 改完配置平滑重载
    systemctl status nginx    # 看状态
    systemctl enable nginx    # 开机自启

  **`reload` 和 `restart` 不是一回事:**
  **`reload` 发 HUP 信号,老 worker 处理完手上请求再退,不断连接;**
  **`restart` 直接停再起,正在传的流会断。**
  **直播业务上永远优先用 `reload`。**

Type=forking 说明它是「自己转后台」的那一类,不是常驻前台。 ExecStartPre 里那条 nginx -t,就是「配置错了不许起」。 LimitNOFILE 65535 才是句柄上限的真身,不在 nginx.conf 里。 两处都要改,只改一处就是「配了不生效」。

30 秒实验

  1. 把 Type 改成 simple,想想会怎样——systemd 会以为进程立刻退出了,反复重启。
  2. 把 LimitNOFILE 删掉,猜上限变成多少——回落到系统默认,通常 1024。
  3. 把 ExecStartPre 删掉,想想风险——配置写错也能启动,然后在第一个请求时才发现。

常见误区

  1. 「CentOS 与 Ubuntu 装法一样」——包管理器与仓库结构都不同。
  2. 「句柄上限在 nginx.conf 里改」——systemd 那边不改就白搭。
  3. 「reload 和 restart 差不多」——reload 不断连接,restart 全断。
自测三问(点开对答案) 1. CentOS 8 的 nginx 在哪个仓库? —— **AppStream**,所以 `dnf install nginx` 直接能装。 2. 句柄上限在哪个文件里设? —— **systemd 的 unit 文件里,`LimitNOFILE` 那一行。** 3. 改完配置该用哪个命令? —— **`systemctl reload nginx`**,不断连接。

相关笔记