配置文件结构与语法
下面我们深入到 Nginx 的配置核心——配置文件的结构、语法和变量系统。这一部分是你驾驭 Nginx 的“语法手册”。
一、分层结构:从全局到局部
Nginx 的配置文件采用块指令嵌套的树形结构,理解从外到内的层次是阅读和编写配置的基础。
# 1. 全局块 (main context)
... # 影响服务器整体运行的指令
events { # 2. events 块
... # 控制连接处理方式
}
http { # 3. http 块
... # HTTP 模块的全局配置
server { # 4. server 块 (虚拟主机)
...
location / { # 5. location 块 (URI 匹配)
...
}
if (条件) { # 6. if 块 (慎用)
...
}
}
}
- 全局块(main):最外层,包含
user、worker_processes、error_log、pid等。这些指令不隶属于任何模块块。 - events 块:专门配置连接处理,最关键的指令是
worker_connections。 - http 块:所有 HTTP 核心功能的总容器,可包含多个
server块。这里配置upstream、access_log格式、gzip、proxy_cache等公用功能。 - server 块:定义一个虚拟主机,基于监听端口和域名区分。
- location 块:根据请求 URI 匹配特定路径,执行最终的处理逻辑。
- if 块:放置在
server或location内部,用于条件判断。但它的工作模型与声明式配置不同,容易引发“诡异”行为,非必要不使用,优先用try_files、return、rewrite或map替代。
二、指令与上下文
1. 指令语法
每行一个指令,以分号结尾。格式为:
指令名 参数1 参数2 ...;
例如:
worker_connections 1024; # 简单指令
listen 80 default_server; # 带多个值
proxy_set_header Host $host; # 可引用变量
块指令用大括号包裹,内部可包含多条指令,如 server { ... }。
2. 上下文
每个指令都有其合法上下文,即它只能出现在特定的块中。这是最易出错的地方,必须掌握规则:
| 上下文 | 特点与常见指令 |
|---|---|
| main | user, worker_processes, error_log, pid, include |
| events | 仅能出现在 events{} 中,如 worker_connections, use, multi_accept |
| http | server, upstream, map, access_log, gzip 等 |
| server | listen, server_name, root, index, try_files,以及 location, if |
| location | 大部分具体处理指令:proxy_pass, fastcgi_pass, rewrite, return, add_header,也可嵌套 location 或 if |
| if | 只能出现在 server 和 location 中,可使用 set, return, rewrite,但不能包含 try_files, proxy_pass 等(可能导致意外) |
典型错误示例:在 location 里写 worker_connections 或者把 server 块直接放在 events 后面——这些都会导致 nginx -t 测试失败。合理的使用方式是心中始终有一张“指令-上下文”映射表,不清楚时查阅官方文档。
三、include 机制与配置拆分
include 能将公共配置分片,便于维护。
1. 基本用法
include /etc/nginx/mime.types; # 包含单个文件
include /etc/nginx/conf.d/*.conf; # 包含目录下所有 .conf 文件
include /etc/nginx/sites-enabled/*; # 包含目录下所有文件(通常是符号链接)
被 include 的文件内容会原地展开,遵守同样的上下文规则。所以你不能在 http 外部 include 一个包含 server 块的配置文件。
2. sites-available / sites-enabled 模式
这是 Debian/Ubuntu 系列发行版推荐的管理方式,也在许多自定义部署中被采用。
- 目录结构:
/etc/nginx/sites-available/:存放所有站点配置,无论启用与否。/etc/nginx/sites-enabled/:存放指向sites-available中文件的符号链接,只有被链接的站点才生效。
- 主配置引入:
在
/etc/nginx/nginx.conf的http块末尾会有一行:nginxinclude /etc/nginx/sites-enabled/*; - 操作方式:bash
# 创建一个可用站点配置 vim /etc/nginx/sites-available/example.conf # 启用该站点 ln -s /etc/nginx/sites-available/example.conf /etc/nginx/sites-enabled/ # 禁用只需删除符号链接 rm /etc/nginx/sites-enabled/example.conf # 重载配置 nginx -s reload
这种模式使站点管理非常清晰,且不会因为移动文件而丢失配置,非常适合多站点环境。
四、Nginx 变量体系
变量是 Nginx 灵活性的灵魂,它们贯穿于日志记录、URL 重写、请求头传递等各个方面。
1. 内置变量(可直接使用)
| 变量名 | 含义与注意事项 |
|---|---|
$uri | 当前请求的 URI,经过解码,且可能被 rewrite 改变过,不包含参数 |
$request_uri | 原始请求 URI,未经解码,且永远不变,包含参数(如 /page?foo=bar) |
$host | 请求头中的 Host 字段,若无则为虚拟主机名;最适合做主机判断 |
$http_host | 原始请求头中的 Host,其值格式完全遵照客户端发送的内容 |
$remote_addr | 客户端 IP 地址 |
$proxy_add_x_forwarded_for | 记录请求经过的代理链路,追加客户端 IP,防止覆盖 |
$args | URL 中的参数字符串(不含问号) |
$query_string | 同 $args |
$scheme | 请求协议(http 或 https) |
$request_method | 请求方法(GET、POST 等) |
$server_name | 当前匹配的 server_name 值 |
$document_root | 当前请求的 root 指令的最终值 |
$uri | 注意:若 URL 重写发生,$uri 会变成重写后的路径 |
对比 $uri 与 $request_uri 的经典差异:
- 请求:
/user/login?next=/admin $uri可能是/user/login(经过 rewrite 可能变成/app.php)$request_uri永远是/user/login?next=/admin
2. 自定义变量
set指令
在server、location、if块内向变量动态赋值。nginxset $mobile_label "desktop"; if ($http_user_agent ~* "(Android|iPhone)") { set $mobile_label "mobile"; }
变量值对后续的所有操作立即可见。map指令
在http块中创建静态映射表,根据一个变量的值生成另一个变量,效率远高于if。nginxmap $host $backend { default backend_default; api.example.com backend_api; admin.example.com backend_admin; }
之后可直接使用$backend变量,例如proxy_pass http://$backend;。
3. 变量的实际应用
- 日志定制
定义详细的访问日志格式,排查问题必备。nginxlog_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; - URL 改写(rewrite)
根据条件做出重定向或内部跳转。nginxrewrite ^/old-path/(.*)$ /new-path/$1 permanent; # 使用变量 $1 捕获分组 if ($scheme = http) { rewrite ^ https://$host$request_uri? permanent; # 强制 HTTPS } - 反向代理头传递
将客户端真实信息透传给后端。nginxlocation / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://backend; } - 动态路由
例如根据 Cookie 或地区匹配合适的后端:nginxmap $cookie_region $upstream { default us_backend; EU eu_backend; ASIA asia_backend; }
掌握配置文件的分层结构、指令上下文规则、include 拆分模式以及变量系统,你就已经具备了读懂任意 Nginx 配置并按照需求自由组合的能力。后面的日志、优化、安全等功能,都是在这一骨架之上添加血肉。
参考文献
相关文章
安全基础
Nginx 作为流量的总入口,安全配置是防线第一关。以下从六个基础维度加固你的服务,既实用又立竿见影。
核心模块与常见指令详解
深入 Nginx 的指令层,是配置落地的关键。下面按功能模块拆解,每个指令都说明含义、语法、典型示例,并点出极易踩坑的地方。
Nginx 核心概念
Nginx 是一款高性能的 HTTP 和反向代理服务器。学习路径见 运维导读。它的强大并发能力与灵活的扩展性根植于少数几个核心设计。理解这些底层原理,后续的配置、调优和排障都会变得通透。
常见故障排查思路
故障排查的关键是快速定位,而非盲目重试。下面按最常见的五种现象归类,每一种都给出清晰的排查路径和解决思路。
性能调优基础
性能调优的目标是:用有限的资源,支撑更高的并发、更快的响应、更稳的服务。下面按优化维度,逐一拆解原理和配置要诀。
访问日志与错误日志
日志是 Nginx 排错的“第一现场”。一个优秀的日志策略既能完整保留请求上下文,又不会撑爆磁盘。下面从格式定制、存储轮转、错误分级三个维度详细讲解。
Series
nginx
2 / 7