Nginx 配置文件通用语法与最佳实践
Nginx 配置文件是 Nginx 能力的核心体现。它采用声明式、层次化(多级上下文)、事件驱动的结构,通过配置不同上下文中的指令(directive)来完成反向代理、负载均衡、安全控制、缓存等功能。
配置文件整体结构与上下文层级
典型的主配置文件通常为 /etc/nginx/nginx.conf(不同系统可能略有差异),整体结构示例如下:
# 全局配置块(main context)——影响整个 Nginx 实例
user nginx nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
# 事件块(events context)——连接处理相关配置
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
# HTTP 块(http context)——HTTP 协议相关配置
http {
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" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
# 服务器块(server context)——虚拟主机
server {
listen 80;
server_name example.com www.example.com;
# 位置块(location context)——URI 匹配与处理
location / {
root /var/www/html;
index index.html index.htm;
}
location /api/ {
proxy_pass http://backend_server;
}
}
}
# Stream 块(stream context)——TCP/UDP 四层代理
stream {
upstream backend {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
server {
listen 12345;
proxy_pass backend;
}
}常见上下文(Context)层级关系:
main:全局上下文,文件顶层,无大括号events:连接处理http:HTTP 服务配置server:虚拟主机location:URI 路径匹配与处理if、map等子指令
stream:TCP/UDP(四层代理)server、upstream
upstream:后端服务器组(可出现在http或stream中)
2. 核心语法规则总览
2.1 指令语法与参数
Nginx 配置由大量指令(directive)组成,每条指令的基本语法为:
directive_name param1 param2 ...;规范说明:
- 每条指令必须以分号
;结尾 - 指令名与参数之间使用一个或多个空格或 Tab 分隔
- 可以有一个或多个参数,参数之间以空格分隔
- 指令通常不区分大小写,但惯例使用小写
示例:
worker_processes 2;
access_log /var/log/nginx/access.log;错误示例(缺少分号):
worker_processes 2
error_log /var/log/nginx/error.log建议:编写或修改配置后,始终执行
nginx -t进行语法检查。
2.2 上下文(Context)与继承
上下文可以理解为“指令的作用域”,用大括号 {} 包裹,且可以嵌套:
# 1. 全局上下文(main,顶级,无大括号)
worker_processes auto;
# 2. 事件上下文
events {
worker_connections 1024;
}
# 3. HTTP 上下文
http {
# 4. server 上下文
server {
# 5. location 上下文
location /path {
proxy_pass http://backend;
}
}
}
# 6. stream 上下文
stream {
server {
listen 3306;
}
}上下文继承规则:
- 子上下文默认继承父上下文中可继承的指令值,如
http中定义的log_format、gzip设置可被server、location继承 - 子上下文可重写父上下文的配置,例如在某个
server中覆盖access_log、client_max_body_size - 部分指令只能出现在特定上下文中,写错位置会导致
nginx -t报错,例如worker_processes只能在main,location不能出现在events中
2.3 include 模块化配置
include 用于拆分配置文件,提升可维护性:
include /etc/nginx/mime.types;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;最佳实践:
- 按功能拆分:gzip、security、ssl、proxy 等
- 按业务拆分:每个虚拟主机一个
server配置文件 - 使用
sites-available+sites-enabled软链接模式控制启用/禁用站点
2.4 变量(Variables)
变量以 $ 开头,在请求处理过程中可动态取值,是实现灵活路由与日志记录的重要机制。
常用内置变量示例:
$remote_addr # 客户端 IP
$request_uri # 含查询参数的完整 URI
$uri # 去掉查询参数后的 URI
$status # 响应状态码
$host # 请求头 Host
$http_user_agent # User-Agent
$scheme # 协议(http / https)在配置中使用变量示例:
location / {
return 301 $scheme://www.example.com$request_uri;
}自定义变量示例(配合 set、if 等指令):
set $is_mobile 0;
if ($http_user_agent ~* '(Android|iPhone)') {
set $is_mobile 1;
}2.5 注释与可读性
Nginx 使用 # 进行单行注释,从 # 开始到行尾均为注释内容:
# 这是单行注释
user nginx;
server {
listen 80; # 监听 80 端口
}建议:在关键配置附近简要说明用途和修改原因,有助于多人协作与后期排查。
3. 核心上下文详解
3.1 全局上下文(main)
全局上下文位于配置文件顶层,无大括号,主要影响 Nginx 进程本身:
user nginx nginx;
worker_processes auto;
daemon on;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log warn;
worker_rlimit_nofile 65535;常用指令说明:
user:指定 worker 进程运行的用户和用户组worker_processes:工作进程数,常设为auto或 CPU 核心数daemon:是否以前台/守护进程模式运行error_log:错误日志路径及日志级别(debug | info | notice | warn | error | crit)pid:保存 master 进程 PID 的文件路径worker_rlimit_nofile:提升 worker 进程可打开的最大文件描述符数,需配合系统ulimit调整
3.2 events 上下文
events 与连接处理模型相关,对高并发性能影响较大:
events {
use epoll;
worker_connections 10240;
multi_accept on;
accept_mutex on;
accept_mutex_delay 500ms;
}关键指令:
use:事件驱动模型,Linux 下推荐epollworker_connections:单个 worker 最多并发连接数(理论最大连接数约为worker_processes * worker_connections)multi_accept:开启后一次accept尽可能多地接受新连接accept_mutex:多个 worker 争抢新连接时的互斥机制,一般保持on
3.3 http 上下文
http 是 Web 相关功能的“大容器”,包括日志、连接、缓存、压缩等:
http {
include mime.types;
default_type application/octet-stream;
charset utf-8;
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 buffer=32k flush=5s;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 100;
client_max_body_size 10m;
client_body_timeout 12;
client_header_timeout 12;
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
gzip on;
gzip_min_length 1000;
gzip_types text/plain text/css application/json application/javascript;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}常用指令要点:
- 日志相关
log_format:定义日志格式access_log:访问日志路径、使用的格式、缓冲策略
- 连接与传输
sendfile on:启用零拷贝,提升静态文件传输效率tcp_nopush、tcp_nodelay:配合sendfile调整包发送行为keepalive_timeout:长连接保持时间
- 客户端限制
client_max_body_size:限制上传体积client_body_timeout/client_header_timeout:超时时间
- 打开文件缓存
open_file_cache系列:减少频繁的 stat 系统调用
- 压缩
gzip、gzip_types:配置内容压缩
3.4 server 上下文
server 用于定义虚拟主机,一个 Nginx 实例可以有多个 server:
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html index.htm;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
allow 192.168.1.0/24;
deny all;
location / {
try_files $uri $uri/ /index.html;
}
}关键点:
listen:监听端口、协议(ssl、http2等)server_name:匹配域名,可支持通配符或正则root/index:站点根目录与默认首页error_page:自定义错误页面allow/deny:基于 IP 的访问控制(更复杂场景建议配合geo、map)
3.5 location 上下文
location 用于匹配 URI,并执行特定处理逻辑。
匹配优先级(从高到低):
=精确匹配^~前缀匹配(匹配成功后不再进行正则匹配)~/~*正则匹配(区分/不区分大小写)- 普通前缀匹配,如
location /(默认兜底)
示例:
location = /favicon.ico {
access_log off;
log_not_found off;
expires 365d;
}
location ^~ /static/ {
alias /var/www/static/;
expires 30d;
add_header Cache-Control "public";
}
location ~ \.(php|php5|php7)$ {
fastcgi_pass unix:/var/run/php-fpm.sock;
include fastcgi_params;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
add_header Cache-Control "public";
}
location / {
try_files $uri $uri/ /index.php?$query_string;
}常用指令:
alias:与root不同,alias替换整个路径前缀try_files:按顺序尝试文件是否存在,不存在则回退到最后一个参数(可为 URI 或 404)
3.6 upstream / stream 上下文
upstream(HTTP / Stream 负载均衡)
upstream backend {
least_conn;
server backend1.example.com:8080 weight=3;
server backend2.example.com:8080;
server backend3.example.com:8080 backup;
server backend4.example.com:8080 down;
}
server {
listen 80;
location /api/ {
proxy_pass http://backend;
}
}说明:
- 负载均衡算法:默认轮询(round-robin),可显式使用
least_conn(最少连接)或第三方模块扩展 weight:权重backup:备份服务器down:标记为不参与负载
提示:示例中的主动健康检查指令如
health_check并非开源版 Nginx 的标准指令,通常来自商业版或第三方模块,使用时需确认模块支持。
stream(TCP/UDP 四层代理)
stream {
upstream mysql_backend {
server 10.0.0.10:3306;
server 10.0.0.11:3306;
}
server {
listen 3306;
proxy_pass mysql_backend;
}
}4. 高级语法特性
4.1 if 条件判断(慎用)
if 是 Nginx 中最容易被误用的指令之一,错误使用可能导致逻辑混乱甚至意外的 500 错误。推荐优先使用 map、独立 location 等方式替代。
示例(仅用于说明语法):
location / {
if ($request_method = POST) {
return 405;
}
if ($http_user_agent ~* '(Android|iPhone)') {
set $is_mobile 1;
}
if ($is_mobile = 1) {
root /var/www/mobile;
}
}经验建议:
- 避免在
location内嵌套复杂多层if - 避免通过
if修改proxy_pass等关键指令,优先用map到变量再使用
4.2 map 映射变量
map 在 http 上下文中使用,用于将一个变量映射到另一个变量,适合处理复杂的分支逻辑:
map $http_user_agent $is_bad_bot {
default 0;
~*(bot|crawler|spider) 1;
~*(baidu|google|bing) 0;
}
server {
if ($is_bad_bot) {
return 403;
}
}适用场景:
- 按 UA、IP、Host 切分流量
- 按业务规则设定后端集群、日志级别等
4.3 limit_except 限制 HTTP 方法
在 location 中使用 limit_except 指定允许的 HTTP 方法,其余方法将按照内部配置拒绝:
location /api/ {
limit_except GET POST {
deny all;
}
}适合场景:
- 对只读接口限制为
GET - 对管理接口限制访问方法并结合 IP 白名单
4.4 geo 基于 IP 的变量
geo 可根据客户端 IP 赋予变量不同的值:
geo $client_region {
default unknown;
192.168.1.0/24 office;
10.0.0.0/8 internal;
include /etc/nginx/geo.conf;
}常用用途:
- 按地区分流(不同机房/国家)
- 按来源 IP 进行黑白名单控制
5. 配置文件组织与工程化实践
典型目录结构推荐如下:
/etc/nginx/
├── nginx.conf # 主配置文件(main + events + http 引用)
├── mime.types # MIME 类型映射
├── fastcgi_params
├── uwsgi_params
├── scgi_params
├── proxy_params
│
├── conf.d/ # 通用配置片段(全局生效)
│ ├── gzip.conf
│ ├── security.conf
│ └── ssl.conf
│
├── sites-available/ # 可用虚拟主机
│ ├── example.com.conf
│ └── app.example.com.conf
│
├── sites-enabled/ # 启用虚拟主机(符号链接)
│ ├── example.com.conf -> ../sites-available/example.com.conf
│ └── app.example.com.conf -> ../sites-available/app.example.com.conf
│
└── snippets/ # 可复用片段
├── security-headers.conf
├── cors.conf
└── rate-limiting.conf工程化建议:
- 将通用安全、gzip、缓存等配置提炼为
snippets或conf.d片段 - 站点级配置统一放在
sites-available,通过软链接控制启用 - 对生产环境与测试环境使用独立配置目录或独立主配置文件
6. 配置测试、调试与排错
6.1 测试配置语法
# 测试默认配置文件
nginx -t
# 指定配置文件路径
nginx -t -c /etc/nginx/nginx.conf输出包含:
syntax is ok:语法无误test is successful:文件引用等检查通过
6.2 平滑重载与日志
# 平滑重载(不中断现有连接)
nginx -s reload
# 重新打开日志文件(配合日志轮转)
nginx -s reopen开启调试日志:
error_log /var/log/nginx/error.log debug;6.3 简单调试 Location
通过自定义响应头快速查看变量值:
location /debug {
add_header X-Debug-Remote-Addr $remote_addr;
add_header X-Debug-Host $host;
add_header X-Debug-Uri $request_uri;
return 200 "OK";
}7. 性能优化相关配置建议
以下为常见的性能优化方向,需结合业务实际压测验证:
- 进程与连接数
worker_processes auto:让 Nginx 自动根据 CPU 核数选择 worker 数worker_connections:根据峰值连接数与内核 FD 限制调整
- 文件描述符
- 提高系统
ulimit -n与worker_rlimit_nofile
- 提高系统
- 网络层优化
- 在 Linux 内核中调整
somaxconn、tcp_max_syn_backlog等参数
- 在 Linux 内核中调整
- 静态资源优化
- 使用
sendfile on、长expires、合理的Cache-Control头
- 使用
- 压缩与缓存
- 针对文本类资源启用
gzip或brotli(如有模块) - 配置
proxy_cache、fastcgi_cache缓存动态内容
- 针对文本类资源启用
- 日志与 IO
- 为高并发接口调整
access_log缓冲大小或按需关闭
- 为高并发接口调整
8. 安全配置与访问控制
常见安全配置方向:
-
基础安全 header
将以下内容抽取为
snippets/security-headers.conf复用:nginxadd_header X-Frame-Options SAMEORIGIN; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; -
隐藏版本信息
nginxhttp { server_tokens off; } -
限制请求大小与速率
client_max_body_size:限制上传大小- 使用
limit_req_zone、limit_req实现基础限流(可抽成片段)
-
访问控制
在敏感接口或管理后台结合 IP 白名单:
nginxlocation /admin { allow 192.168.1.0/24; deny all; } -
HTTPS 配置
- 使用现代 TLS 配置和安全的 cipher 列表
- 强制 HTTP 重定向到 HTTPS
9. 常见错误与 FAQ
9.1 常见错误类型
- 缺少分号
- 现象:
nginx -t提示语法错误,多出现在上一行末尾
- 现象:
- 上下文错误
- 现象:指令放在不支持的上下文,报 “directive is not allowed here”
- 路径错误
- 相对路径往往相对于编译时
--prefix或运行时root指定目录
- 相对路径往往相对于编译时
- 权限问题
- Nginx 进程对证书、站点目录、日志目录无读写权限
- 端口冲突
listen的端口已被其他进程占用
9.2 FAQ 示例
-
Q:修改完配置后应该怎样上线?
A:先执行nginx -t确认配置无误,再执行nginx -s reload平滑重载。 -
Q:如何定位某个请求匹配到了哪个
location?
A:可以临时在候选location中加上不同的add_header标记或特定响应体,通过实际访问来验证匹配结果。 -
Q:多个
server中server_name相同会怎样?
A:通常按配置顺序匹配到第一个,除非显式配置default_server,因此应避免冲突或混淆。
掌握 Nginx 配置语法与常用模式后,可以从简单场景入手,逐步引入反向代理、缓存、限流、安全等高级特性,并在每次调整后使用 nginx -t 与压测工具验证行为与性能。