Chapter 02

配置文件结构

Nginx 的所有能力都由 nginx.conf 驱动。理解 context 层级、指令与块、include 拆分、变量与平滑重载,就掌握了配置这门语言的语法。

2.1 配置语言的三个基本单位

Nginx 配置由三种东西组成:指令块(block/context)注释

指令(Directive)
一条以分号结尾的语句,形如 指令名 参数;。例如 worker_processes auto;。分为"简单指令"(单行)和"块指令"(带 { })。
块 / 上下文(Block / Context)
{ } 包裹的一组指令,如 http { ... }。块可以嵌套,形成层级;内层继承外层的配置。
指令继承(Inheritance)
子块自动继承父块的指令值,除非子块自己重新声明覆盖。这让你能在 http 层设默认、在 server/location 层微调。
include
把另一个文件的内容原地插入当前位置,用于把庞大的配置拆成多个小文件。支持通配符 include conf.d/*.conf;
变量(Variable)
$ 开头的运行时值,如 $host$uri$remote_addr。可用于日志、if 判断、代理头传递等。
平滑重载(Graceful Reload)
Nginx 收到 reload 信号后,master 加载新配置、启动新 worker,旧 worker 处理完当前连接后退出,全程不断开正在服务的连接。

2.2 context 层级全景

配置文件由外到内是嵌套的上下文。记住这张"树",你就不会在错误的层级写错误的指令:

# nginx.conf 的骨架
# --- main context(文件最外层,无大括号)---
user  www-data;
worker_processes  auto;
error_log  /var/log/nginx/error.log warn;
pid  /run/nginx.pid;

events {                # --- events:连接处理层 ---
    worker_connections  1024;
    multi_accept  on;
}

http {                  # --- http:所有 HTTP 相关 ---
    include  mime.types;
    default_type  application/octet-stream;
    sendfile  on;
    keepalive_timeout  65;

    upstream backend {    # --- upstream:后端组 ---
        server 127.0.0.1:3000;
    }

    server {              # --- server:一个虚拟主机 ---
        listen  80;
        server_name  example.com;

        location / {       # --- location:一条 URL 规则 ---
            root  /var/www/html;
        }
    }
}
Context职责常见指令
main进程级全局设置user, worker_processes, error_log, pid
events连接处理机制worker_connections, use, multi_accept
httpHTTP 全局默认include, sendfile, gzip, log_format
upstream定义后端服务器组server, least_conn, keepalive
server一个虚拟主机listen, server_name, ssl_certificate
location匹配 URI 的处理规则root, alias, proxy_pass, try_files

2.3 main context:进程与全局

# worker 进程数:auto = CPU 核心数,最常用
worker_processes  auto;

# 每个 worker 能打开的文件描述符上限
worker_rlimit_nofile  65535;

# worker 运行的用户/组(降权,安全)
user  www-data;

# 全局错误日志与级别:debug|info|notice|warn|error|crit
error_log  /var/log/nginx/error.log  warn;

pid  /run/nginx.pid;
worker_processes 与 worker_connections 的乘积

理论最大并发连接 ≈ worker_processes × worker_connections。8 核 × 1024 = 8192。做反向代理时,一个客户端连接还要占一个到后端的连接,实际有效值要打对折。高并发场景把 worker_connections 提到 8192 甚至更高,同时确保 worker_rlimit_nofile 够大。

2.4 http context:定义默认行为

http {
    # 引入 MIME 类型映射(决定 Content-Type)
    include  /etc/nginx/mime.types;
    default_type  application/octet-stream;

    # 自定义日志格式
    log_format  main  '$remote_addr - $remote_user [$time_local] '
                      '"$request" $status $body_bytes_sent '
                      '"$http_referer" "$http_user_agent"';
    access_log  /var/log/nginx/access.log  main;

    # 静态文件零拷贝发送
    sendfile  on;
    tcp_nopush  on;
    keepalive_timeout  65;

    # 把站点配置拆到独立文件
    include  /etc/nginx/conf.d/*.conf;
    include  /etc/nginx/sites-enabled/*;
}

2.5 用 include 拆分配置

把所有站点都堆在一个 nginx.conf 里会变得难以维护。惯用做法是主配置只放全局设置,每个站点单独一个文件:

# /etc/nginx/conf.d/blog.conf —— 独立站点文件
server {
    listen  80;
    server_name  blog.example.com;
    root  /var/www/blog;

    # 复用公共片段:安全头、gzip 等
    include  /etc/nginx/snippets/security-headers.conf;

    location / {
        try_files  $uri $uri/ =404;
    }
}
include 的位置决定合法性

include 出现在哪个 context,被引入文件里的指令就必须在那个 context 合法。在 http 层 include 的文件应放 server{};在 server 层 include 的文件应放 location{} 或简单指令。放错层级会报 "directive is not allowed here"。

2.6 常用内置变量

变量含义
$host请求的主机名(Host 头,或 server_name)
$uri规范化后的当前 URI(不含查询串)
$request_uri原始完整请求 URI(含查询串)
$args查询字符串(问号后面的部分)
$remote_addr客户端 IP
$scheme协议:http 或 https
$request_method请求方法:GET/POST/...
$http_user_agent请求头 User-Agent(任意 $http_xxx
# 变量用于条件重定向:把所有非 www 跳到 www
server {
    listen  80;
    server_name  example.com;
    return  301  $scheme://www.example.com$request_uri;
}

2.7 reload 是怎么做到不断线的

当你执行 nginx -s reload,发生的事情如下:

整个过程新旧 worker 短暂并存,正在传输的请求不会被打断——这就是"平滑"。因此生产环境改配置几乎总是用 reload 而非 restart。

reload 也有极限

某些改动(如修改 worker_processes、切换事件模型)reload 不一定完全生效,需要 restart。此外若新配置绑定了一个已被占用的端口,reload 会失败。生产变更前务必 nginx -t

2.8 小结与下一步