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 秒实验
- 把
Type改成simple,想想会怎样——systemd 会以为进程立刻退出了,反复重启。 - 把
LimitNOFILE删掉,猜上限变成多少——回落到系统默认,通常 1024。 - 把
ExecStartPre删掉,想想风险——配置写错也能启动,然后在第一个请求时才发现。
常见误区
- 「CentOS 与 Ubuntu 装法一样」——包管理器与仓库结构都不同。
- 「句柄上限在 nginx.conf 里改」——systemd 那边不改就白搭。
- 「reload 和 restart 差不多」——reload 不断连接,restart 全断。
自测三问(点开对答案)
1. CentOS 8 的 nginx 在哪个仓库? —— **AppStream**,所以 `dnf install nginx` 直接能装。 2. 句柄上限在哪个文件里设? —— **systemd 的 unit 文件里,`LimitNOFILE` 那一行。** 3. 改完配置该用哪个命令? —— **`systemctl reload nginx`**,不断连接。- ☐ (本节完,下一节 10.3.1 Ubuntu 18 下编译 nginx-rtmp-module)