3. Nginx基础:安装、启动、停止与重载,配置文件结构

Nginx 这东西,说白了就是推流系统的看门大爷。你推流能不能稳,用户能不能流畅看,一半的功夫都在它身上。我刚开始接触流媒体时,总觉得 Nginx 就是个反向代理,后来线上出过一次事故才明白——配置写不对,推流一秒都撑不住。

这一章,咱们把 Nginx 的安装、启停、重载,还有那三个核心配置块(http、server、location)彻底捋清楚。嗯,都是基本功,但基本功不牢,后面全是坑。

3.1 安装 Nginx:三种方式,我推荐第二种

安装 Nginx 其实不复杂,但不同环境有不同讲究。我个人习惯用包管理器装,省心。但如果你要定制模块(比如推流用的 nginx-rtmp-module),那就得走编译安装。

安装方式 命令 / 步骤 适用场景
apt(Ubuntu/Debian) sudo apt update && sudo apt install nginx 快速体验、开发环境
yum(CentOS/RHEL) sudo yum install epel-release && sudo yum install nginx 生产环境(稳定)
源码编译 ./configure --with-http_ssl_module --add-module=... && make && make install 需要自定义模块(如 RTMP)
我的建议: 生产环境用 yum 或 apt 装官方源版本,别用第三方源。我曾经见过有人用了个野鸡源,结果 Nginx 版本和 OpenSSL 不兼容,SSL 握手全挂,排查了一整晚。

3.2 启动、停止与重载:别再用 kill -9 了

Nginx 的进程管理,核心就三个动作:启动、停止、重载。但很多人一上来就 kill -9,这其实很粗暴。Nginx 有自己的信号机制,优雅得多。

3.2.1 启动

# 直接启动
sudo nginx

# 或者用 systemd(推荐)
sudo systemctl start nginx

# 设置开机自启
sudo systemctl enable nginx

3.2.2 停止

# 快速停止(不推荐)
sudo nginx -s stop

# 优雅停止(等当前请求处理完再停)
sudo nginx -s quit

# 或者用 systemd
sudo systemctl stop nginx
注意: nginx -s stop 是暴力终止,正在处理的连接会直接断掉。推流场景下,观众会瞬间黑屏。我建议用 nginx -s quit,它会等 worker 进程处理完当前请求再退出,对用户影响最小。

3.2.3 重载配置

改完配置文件,不用重启 Nginx,重载就行。这是我最常用的操作。

# 检查配置语法(这一步千万别省)
sudo nginx -t

# 重载配置
sudo nginx -s reload

# 或者用 systemd
sudo systemctl reload nginx

为什么会先检查语法?因为配置写错了,重载会失败,Nginx 会继续用旧配置运行。但如果你直接重启,配置错了服务就起不来了。嗯,我在项目里吃过这个亏——改完配置直接重启,结果网站挂了 10 分钟。

3.3 配置文件结构:http、server、location 三件套

Nginx 的配置文件默认在 /etc/nginx/nginx.conf。它的结构是树形的,核心就三个块:http、server、location。你想想看,这就像一栋楼:http 是整个楼,server 是每一层,location 是每个房间。

核心逻辑:

  • http 块:全局配置,影响所有虚拟主机。比如超时时间、日志格式、Gzip 压缩。
  • server 块:定义一个虚拟主机。监听哪个端口、哪个域名,都在这里配。
  • location 块:匹配 URI 路径。比如 /live 走推流,/static 走静态文件。

3.3.1 一个典型的配置文件长这样

# 全局配置
user  nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

# http 块 —— 全局 HTTP 配置
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    sendfile      on;
    keepalive_timeout  65;

    # server 块 —— 第一个虚拟主机
    server {
        listen       80;
        server_name  example.com;

        # location 块 —— 根路径
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }

        # location 块 —— 推流路径
        location /live {
            # 这里后面会配 RTMP 模块
            proxy_pass http://127.0.0.1:1935;
        }
    }

    # server 块 —— 第二个虚拟主机
    server {
        listen       443 ssl;
        server_name  example.com;

        ssl_certificate     /etc/ssl/certs/example.crt;
        ssl_certificate_key /etc/ssl/private/example.key;

        location / {
            root   /usr/share/nginx/html;
        }
    }
}

3.3.2 三个块的关系,我用一张图说清楚

Nginx 配置层级结构 http 块(全局 HTTP 配置) server 块 1 listen 80; server_name example.com; location / root /usr/share/nginx/html; index index.html; location /live proxy_pass http://127.0.0.1:1935; server 块 2 listen 443 ssl; server_name example.com; location / root /usr/share/nginx/html; SSL 证书配置 http 块包含多个 server 块,每个 server 块包含多个 location 块,形成树形层级

3.4 配置文件的加载顺序与优先级

Nginx 在处理请求时,会按一定顺序匹配 server 和 location。很多人搞不清优先级,结果配了半天发现没生效。我总结了一个口诀:精确优先,正则次之,前缀最后。

3.4.1 server 匹配规则

  • 先匹配 listen 端口和 IP。
  • 再匹配 server_name:精确匹配 > 通配符开头(*.example.com)> 通配符结尾(www.*)> 正则表达式(~^www\d+\.example\.com$)。
  • 如果都没匹配上,用默认 server(第一个或 default_server 标记的那个)。

3.4.2 location 匹配规则

修饰符 示例 匹配方式 优先级
= location = /live 精确匹配 最高
^~ location ^~ /static/ 前缀匹配,不检查正则 次高
~ / ~* location ~ \.mp4$ 正则匹配(区分/不区分大小写) 中等
无修饰符 location / 普通前缀匹配 最低
避坑指南: 我曾经在配置推流时,把 location /live 和 location ~ /live 混在一起用,结果正则匹配抢了精确匹配的活,推流地址一直 404。后来我统一用 location = /live 才解决。记住:推流路径尽量用精确匹配,别给正则留机会。

3.5 实战:写一个最小可用的推流配置

光说不练假把式。咱们写一个最简单的 Nginx 配置,为后面推流做准备。这个配置只做一件事:监听 80 端口,把 /live 路径的请求转发到本地的 RTMP 服务(1935 端口)。

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile      on;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }

        # 推流转发
        location /live {
            proxy_pass http://127.0.0.1:1935;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }

        # 禁止访问 . 开头的隐藏文件
        location ~ /\. {
            deny all;
        }
    }
}
注意: 这个配置里 proxy_pass 后面没有斜杠。如果有斜杠(比如 http://127.0.0.1:1935/),Nginx 会替换掉匹配的 location 路径。没有斜杠,则会把完整 URI 传过去。推流场景下,一般不加斜杠,保持 URI 原样。

3.6 验证配置与常见错误

每次改完配置,记得跑一遍 nginx -t。这步花不了 5 秒钟,但能救你一命。我见过太多人改完配置直接重启,结果 Nginx 起不来,线上全挂。

3.6.1 常见错误及解决

错误信息 原因 解决方法
[emerg] bind() to 0.0.0.0:80 failed 端口被占用(通常是 Apache 或其他 Nginx) sudo lsof -i :80 查占用进程,kill 或改端口
[emerg] unknown directive "xxxx" 拼写错误或模块未安装 检查指令名,确认对应模块已编译
[emerg] "server" directive is not allowed here server 块放到了 http 块外面 把 server 块移到 http 块内部
403 Forbidden 目录权限不足或缺少 index 文件 检查目录权限(755)和文件存在性

3.6.2 验证步骤

  1. 检查语法:sudo nginx -t
  2. 查看进程:ps aux | grep nginx(应该看到 master 和多个 worker)
  3. 测试端口:curl -I http://localhost(返回 200 或 302 说明正常)
  4. 查看日志:tail -f /var/log/nginx/error.log(实时监控错误)

本章小结:

  • 安装 Nginx 推荐用包管理器,定制模块才走编译。
  • 启停用 nginx -s quit 和 nginx -s reload,别用 kill -9。
  • 配置文件是树形结构:http 包 server,server 包 location。
  • location 匹配优先级:精确匹配 > 前缀匹配(^~)> 正则匹配 > 普通前缀。
  • 每次改配置先 nginx -t,再 nginx -s reload。