Nginx 核心配置详解
2026/3/20大约 12 分钟
Nginx 核心配置详解
配置文件结构
整体结构概览
Nginx 配置文件采用层级结构,由指令(Directive)和块(Block)组成:
# 全局块 - 影响 Nginx 整体运行
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# events 块 - 影响 Nginx 与用户的网络连接
events {
worker_connections 1024;
use epoll;
}
# http 块 - HTTP 服务器相关配置
http {
# http 全局块
include /etc/nginx/mime.types;
default_type application/octet-stream;
# server 块 - 虚拟主机配置
server {
# server 全局块
listen 80;
server_name example.com;
# location 块 - URL 匹配配置
location / {
root /var/www/html;
index index.html;
}
location /api {
proxy_pass http://backend;
}
}
# 可以有多个 server 块
server {
listen 80;
server_name another.com;
# ...
}
}
# stream 块 - TCP/UDP 代理配置(可选)
stream {
server {
listen 3306;
proxy_pass mysql_cluster;
}
}
配置层级关系
nginx.conf
│
├── 全局块(main)
│ ├── user
│ ├── worker_processes
│ ├── error_log
│ └── pid
│
├── events 块
│ ├── worker_connections
│ ├── use
│ └── multi_accept
│
├── http 块
│ ├── http 全局设置
│ │ ├── include
│ │ ├── log_format
│ │ ├── sendfile
│ │ └── gzip
│ │
│ ├── upstream 块(负载均衡)
│ │ └── server 定义
│ │
│ └── server 块(虚拟主机)
│ ├── listen
│ ├── server_name
│ ├── root
│ │
│ └── location 块(URL 路由)
│ ├── proxy_pass
│ ├── fastcgi_pass
│ └── 其他指令
│
└── stream 块(TCP/UDP)
└── server 块
全局块配置
用户和进程
# 运行 Nginx 的用户和用户组
user nginx nginx;
# Worker 进程数
# auto: 自动检测 CPU 核心数
# 建议: 设置为 CPU 核心数或 auto
worker_processes auto;
# 绑定 Worker 进程到指定 CPU
# 4核 CPU 示例:每个 Worker 绑定一个核心
worker_cpu_affinity 0001 0010 0100 1000;
# 或自动绑定
worker_cpu_affinity auto;
# Worker 进程优先级(-20 到 20,值越小优先级越高)
worker_priority -10;
# 单个 Worker 进程最大打开文件数
worker_rlimit_nofile 65535;
# Master 进程 PID 文件路径
pid /run/nginx.pid;
# 以守护进程方式运行(默认 on)
daemon on;
# 是否以 master/worker 方式工作(默认 on)
master_process on;
错误日志配置
# 错误日志配置
# 语法: error_log 路径 级别;
# 级别: debug | info | notice | warn | error | crit | alert | emerg
# 生产环境建议使用 warn 或 error
error_log /var/log/nginx/error.log warn;
# 调试时使用 debug(需要编译时开启 --with-debug)
error_log /var/log/nginx/error.log debug;
# 关闭错误日志(不推荐)
error_log /dev/null;
# 可以配置多个错误日志
error_log /var/log/nginx/error.log warn;
error_log syslog:server=192.168.1.100 info;
环境变量
# 设置环境变量
env MALLOC_OPTIONS;
env PERL5LIB=/data/site/modules;
env OPENSSL_ALLOW_PROXY_CERTS=1;
# 在配置中引用环境变量
# 使用 $变量名 或 ${变量名}
set $my_var $SOME_ENV_VAR;
events 块配置
events 块配置影响 Nginx 服务器与用户的网络连接:
events {
# 单个 Worker 进程的最大并发连接数
# 最大连接数 = worker_processes × worker_connections
worker_connections 65535;
# 事件驱动模型
# Linux: epoll(推荐)
# FreeBSD: kqueue
# Solaris: /dev/poll
# Windows: select
use epoll;
# 是否允许同时接受多个网络连接
# on: 一次接受所有新连接
# off: 一次只接受一个新连接
multi_accept on;
# 是否开启 accept 互斥锁
# 用于解决惊群问题(新版本已优化,建议关闭)
accept_mutex off;
# accept 互斥锁等待时间
accept_mutex_delay 500ms;
# 调试连接(需要编译时开启 --with-debug)
debug_connection 192.168.1.0/24;
debug_connection localhost;
}
worker_connections 计算说明:
| 场景 | 计算公式 | 说明 |
|---|---|---|
| HTTP 服务器 | worker_processes × worker_connections | 每个请求占用一个连接 |
| 反向代理 | worker_processes × worker_connections / 2 | 每个请求占用两个连接(客户端+后端) |
| 长连接代理 | worker_processes × worker_connections / 4 | 考虑 keepalive 连接 |
http 块配置
MIME 类型
http {
# 引入 MIME 类型映射文件
include /etc/nginx/mime.types;
# 默认 MIME 类型
# 当无法识别文件类型时使用
default_type application/octet-stream;
# 自定义 MIME 类型
types {
text/html html htm shtml;
text/css css;
text/xml xml;
application/javascript js;
application/json json;
image/gif gif;
image/jpeg jpeg jpg;
image/png png;
image/webp webp;
font/woff woff;
font/woff2 woff2;
application/vnd.ms-fontobject eot;
}
}
日志配置
http {
# 定义日志格式
# main: 格式名称
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# JSON 格式日志(便于日志分析)
log_format json_log escape=json '{'
'"time":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"request":"$request",'
'"status":"$status",'
'"body_bytes_sent":"$body_bytes_sent",'
'"request_time":"$request_time",'
'"upstream_response_time":"$upstream_response_time",'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"http_x_forwarded_for":"$http_x_forwarded_for"'
'}';
# 带请求追踪的日志格式
log_format trace '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time" '
'request_id="$request_id"';
# 访问日志
access_log /var/log/nginx/access.log main;
# 按条件记录日志
map $status $loggable {
~^[23] 0; # 2xx 3xx 不记录
default 1; # 其他状态码记录
}
access_log /var/log/nginx/error_access.log main if=$loggable;
# 关闭访问日志
access_log off;
# 开启日志缓冲(提高性能)
access_log /var/log/nginx/access.log main buffer=32k flush=5s;
# 开启日志压缩
access_log /var/log/nginx/access.log.gz main gzip=9 buffer=32k;
}
常用日志变量:
| 变量 | 说明 |
|---|---|
$remote_addr | 客户端 IP 地址 |
$remote_user | 认证用户名 |
$time_local | 本地时间 |
$time_iso8601 | ISO 8601 格式时间 |
$request | 完整请求行 |
$status | 响应状态码 |
$body_bytes_sent | 发送给客户端的字节数(不含响应头) |
$bytes_sent | 发送给客户端的总字节数 |
$http_referer | Referer 头 |
$http_user_agent | User-Agent 头 |
$http_x_forwarded_for | X-Forwarded-For 头 |
$request_time | 请求处理时间(秒) |
$upstream_response_time | 后端响应时间 |
$upstream_connect_time | 与后端建立连接的时间 |
$request_id | 唯一请求 ID(1.11.0+) |
$connection | 连接序号 |
$connection_requests | 当前连接的请求数 |
文件传输优化
http {
# 开启高效文件传输
# 使用 sendfile 系统调用,零拷贝传输
sendfile on;
# 配合 sendfile 使用
# 在一个数据包中发送 HTTP 响应头和文件开头
tcp_nopush on;
# 禁用 Nagle 算法
# 适合实时性要求高的应用
tcp_nodelay on;
# 开启异步 I/O(配合 AIO 线程池)
aio on;
# 或使用线程池
aio threads;
# 直接 I/O(绕过文件系统缓存)
# 适合大文件传输
directio 4m;
directio_alignment 512;
# 文件描述符缓存
open_file_cache max=65535 inactive=60s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
}
sendfile 工作原理:
传统方式: sendfile 方式:
用户空间 ←→ 内核空间 内核空间直接传输
磁盘 → 内核缓冲区 磁盘 → 内核缓冲区
↓ ↓
用户缓冲区 Socket 缓冲区(零拷贝)
↓ ↓
Socket 缓冲区 网络
↓
网络
连接管理
http {
# 客户端连接超时(等待客户端发送请求)
client_header_timeout 60s;
# 客户端请求体超时
client_body_timeout 60s;
# 发送响应超时
send_timeout 60s;
# Keep-Alive 超时
keepalive_timeout 75s;
# 单个 Keep-Alive 连接最大请求数
keepalive_requests 1000;
# 关闭不响应的客户端连接
reset_timedout_connection on;
# 延迟关闭(处理完数据后再关闭)
lingering_close on;
lingering_time 30s;
lingering_timeout 5s;
}
请求体处理
http {
# 客户端请求体最大大小
# 超过会返回 413 Request Entity Too Large
client_max_body_size 100m;
# 请求体缓冲区大小
client_body_buffer_size 128k;
# 请求体临时文件目录
client_body_temp_path /var/cache/nginx/client_temp 1 2;
# 请求体存储方式
# off: 存储在内存或临时文件
# on: 总是存储在临时文件
# clean: 请求结束后删除临时文件
client_body_in_file_only off;
# 是否将请求体读入单个缓冲区
client_body_in_single_buffer on;
# 请求头缓冲区大小
client_header_buffer_size 1k;
# 大请求头缓冲区
large_client_header_buffers 4 8k;
}
Gzip 压缩
http {
# 开启 gzip 压缩
gzip on;
# 压缩级别(1-9,默认 1)
# 级别越高压缩率越高,但 CPU 消耗也越大
gzip_comp_level 5;
# 最小压缩长度(小于此值不压缩)
gzip_min_length 1024;
# 压缩缓冲区
gzip_buffers 16 8k;
# HTTP 版本
gzip_http_version 1.1;
# 压缩的 MIME 类型
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml
application/xml+rss
application/x-javascript
image/svg+xml;
# 是否在响应头添加 Vary: Accept-Encoding
gzip_vary on;
# 代理请求是否压缩
# off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any
gzip_proxied any;
# 禁用 gzip 的 User-Agent(IE6 不支持)
gzip_disable "MSIE [1-6]\.";
# 预压缩文件(需要 ngx_http_gzip_static_module)
gzip_static on;
}
server 块配置
监听指令
server {
# 基本监听
listen 80;
# 监听所有接口
listen *:80;
# 监听指定 IP
listen 192.168.1.100:80;
# IPv6 监听
listen [::]:80;
# 同时监听 IPv4 和 IPv6
listen 80;
listen [::]:80;
# SSL 监听
listen 443 ssl;
listen [::]:443 ssl;
# HTTP/2
listen 443 ssl http2;
# 默认服务器
listen 80 default_server;
# Unix Socket 监听
listen unix:/var/run/nginx.sock;
# 其他参数
listen 80 backlog=4096; # 连接队列大小
listen 80 rcvbuf=8k; # 接收缓冲区
listen 80 sndbuf=16k; # 发送缓冲区
listen 80 deferred; # 延迟接受(Linux)
listen 80 reuseport; # 端口复用(提高性能)
listen 80 so_keepalive=on; # TCP keepalive
}
server_name 指令
server {
# 精确匹配
server_name example.com;
# 多个域名
server_name example.com www.example.com;
# 通配符(只能在首尾)
server_name *.example.com; # 匹配 a.example.com
server_name example.*; # 匹配 example.com example.org
# 正则表达式(以 ~ 开头)
server_name ~^www\d+\.example\.com$;
server_name ~^(?<subdomain>.+)\.example\.com$;
# 捕获组使用
server_name ~^(?<user>.+)\.example\.com$;
location / {
root /data/sites/$user;
}
# 匹配所有(作为默认服务器)
server_name _;
server_name "";
# 匹配 IP 直接访问
server_name 192.168.1.100;
}
server_name 匹配优先级:
- 精确匹配(如
example.com) - 以
*开头的通配符(如*.example.com) - 以
*结尾的通配符(如example.*) - 正则表达式(按配置文件中的顺序)
- default_server
根目录和索引
server {
# 网站根目录
root /var/www/html;
# 默认首页文件
index index.html index.htm index.php;
# 也可以在 location 中设置
location / {
root /var/www/html;
index index.html;
}
location /app {
# alias 与 root 的区别:
# root: 请求 /app/file.html 访问 /data/app/file.html
# alias: 请求 /app/file.html 访问 /data/file.html
alias /data;
index index.html;
}
}
root vs alias 对比:
| 指令 | 请求 URI | 实际路径 |
|---|---|---|
root /var/www; | /images/logo.png | /var/www/images/logo.png |
alias /var/www/; | /images/logo.png | /var/www/logo.png |
location 块配置
匹配规则
# location 语法
# location [ = | ~ | ~* | ^~ ] uri { ... }
server {
# 1. 精确匹配(优先级最高)
location = / {
# 只匹配 /
}
location = /login {
# 只匹配 /login
}
# 2. 前缀匹配(^~ 阻止正则匹配)
location ^~ /static/ {
# 匹配以 /static/ 开头的 URI
# 不再检查正则
}
# 3. 正则匹配(区分大小写)
location ~ \.php$ {
# 匹配以 .php 结尾的 URI
}
# 4. 正则匹配(不区分大小写)
location ~* \.(jpg|jpeg|png|gif)$ {
# 匹配图片文件
}
# 5. 普通前缀匹配(优先级最低)
location / {
# 匹配所有请求(作为默认)
}
location /documents/ {
# 匹配以 /documents/ 开头的 URI
}
}
location 匹配优先级:
1. = 精确匹配
↓ (找到则停止)
2. ^~ 前缀匹配
↓ (找到则停止,不检查正则)
3. ~ 或 ~* 正则匹配
↓ (按配置顺序,第一个匹配则停止)
4. 普通前缀匹配
↓ (最长前缀匹配)
location 匹配示例
server {
listen 80;
server_name example.com;
# 精确匹配首页
location = / {
return 200 "Homepage\n";
}
# /api 精确匹配
location = /api {
return 200 "API Root\n";
}
# /api/ 前缀匹配
location /api/ {
return 200 "API Routes\n";
}
# 静态资源(阻止正则)
location ^~ /static/ {
root /var/www;
expires 30d;
}
# PHP 文件
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# 图片文件(不区分大小写)
location ~* \.(jpg|jpeg|png|gif|ico|webp)$ {
root /var/www/images;
expires 7d;
add_header Cache-Control "public";
}
# 默认处理
location / {
try_files $uri $uri/ /index.html;
}
}
内部 location
server {
# 命名 location(只能内部跳转)
location @fallback {
proxy_pass http://backend;
}
location / {
try_files $uri $uri/ @fallback;
}
# 内部 location
location /internal/ {
internal; # 只能内部请求访问
alias /data/internal/;
}
# 错误页面跳转到内部 location
error_page 404 = @notfound;
location @notfound {
return 200 "Page not found\n";
}
}
变量详解
内置变量
Nginx 提供了大量内置变量:
# 请求相关
$request # 完整请求行
$request_method # 请求方法(GET、POST 等)
$request_uri # 原始 URI(包含查询参数)
$uri # 当前 URI(不含查询参数,可能被重写)
$document_uri # 同 $uri
$args # 查询字符串
$query_string # 同 $args
$is_args # 如果有查询参数则为 "?",否则为空
$scheme # 协议(http 或 https)
$request_filename # 当前请求的文件路径
$document_root # 当前请求的根目录
$realpath_root # 真实根目录路径
# 客户端相关
$remote_addr # 客户端 IP
$remote_port # 客户端端口
$remote_user # 认证用户名
$http_cookie # Cookie 头
$http_user_agent # User-Agent 头
$http_referer # Referer 头
$http_host # Host 头
$http_x_forwarded_for # X-Forwarded-For 头
$http_xxx # 获取任意请求头(xxx 为头名称,转小写,- 转 _)
# 服务器相关
$server_name # 匹配的 server_name
$server_addr # 服务器 IP
$server_port # 服务器端口
$server_protocol # 协议版本(HTTP/1.0 或 HTTP/1.1)
$hostname # 主机名
$nginx_version # Nginx 版本
$pid # Worker 进程 PID
# 连接相关
$connection # 连接序号
$connection_requests # 当前连接的请求数
$request_id # 唯一请求 ID(16 位十六进制)
# 时间相关
$time_local # 本地时间
$time_iso8601 # ISO 8601 格式时间
$msec # 毫秒时间戳
$request_time # 请求处理时间(秒)
# 响应相关
$status # 响应状态码
$body_bytes_sent # 发送的响应体大小
$bytes_sent # 发送的总字节数
$sent_http_xxx # 获取响应头(如 $sent_http_content_type)
# 其他
$request_body # 请求体
$request_body_file # 请求体临时文件
$content_length # Content-Length 头
$content_type # Content-Type 头
$limit_rate # 限速值
$binary_remote_addr # 二进制格式的客户端 IP
自定义变量
server {
# set 指令设置变量
set $my_var "hello";
# 根据条件设置变量
set $proxy_host "";
if ($host ~* ^api\.) {
set $proxy_host "api-backend";
}
# map 指令批量映射(在 http 块中)
# 根据 $uri 设置 $new_uri
map $uri $new_uri {
default $uri;
/old-page /new-page;
~^/blog/(\d+)$ /article/$1;
}
# geo 指令根据 IP 设置变量
geo $geo {
default unknown;
127.0.0.1 local;
192.168.0.0/16 internal;
10.0.0.0/8 internal;
}
location / {
return 200 "Geo: $geo\n";
}
}
map 指令详解
http {
# 基本映射
map $request_method $is_post {
default 0;
POST 1;
}
# 正则映射
map $uri $api_version {
default v1;
~^/api/v2/ v2;
~^/api/v3/ v3;
}
# 组合变量
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# 条件日志
map $status $loggable {
~^[23] 0;
default 1;
}
# IP 白名单
map $remote_addr $ip_whitelist {
default 0;
192.168.1.100 1;
192.168.1.101 1;
10.0.0.0/8 1;
}
server {
# 使用 map 变量
if ($ip_whitelist = 0) {
return 403;
}
access_log /var/log/nginx/access.log main if=$loggable;
}
}
条件判断
if 指令
server {
# 变量判断
if ($request_method = POST) {
return 405;
}
# 变量存在判断
if ($arg_debug) {
set $debug 1;
}
# 正则匹配(区分大小写)
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /ie/$1 break;
}
# 正则匹配(不区分大小写)
if ($http_user_agent ~* "mobile|android|iphone") {
set $mobile 1;
}
# 取反
if ($request_uri !~ "^/api/") {
set $not_api 1;
}
# 文件存在判断
if (-f $request_filename) {
# 文件存在
}
if (!-f $request_filename) {
# 文件不存在
}
# 目录存在判断
if (-d $request_filename) {
# 目录存在
}
# 文件或目录存在
if (-e $request_filename) {
# 存在
}
# 文件可执行
if (-x $request_filename) {
# 可执行
}
}
if 指令的陷阱
Nginx 的 if 指令在 location 中使用时可能会有意想不到的行为,应尽量避免在 location 中使用复杂的 if 判断。推荐使用 map + try_files 来替代。
条件判断最佳实践
http {
# 使用 map 替代多个 if
map $http_user_agent $is_bot {
default 0;
~*googlebot 1;
~*bingbot 1;
~*slurp 1;
}
map $request_method $is_allowed_method {
default 0;
GET 1;
POST 1;
PUT 1;
DELETE 1;
}
server {
# 简单的条件判断
if ($is_bot) {
set $limit_rate 1k;
}
# 方法限制
if ($is_allowed_method = 0) {
return 405;
}
location / {
# 使用 try_files 替代 if
try_files $uri $uri/ /index.html;
}
}
}
配置示例
完整配置模板
# /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;
events {
worker_connections 65535;
use epoll;
multi_accept on;
}
http {
# 基础配置
include /etc/nginx/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" "$http_x_forwarded_for" '
'rt=$request_time';
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 1000;
client_header_timeout 60;
client_body_timeout 60;
send_timeout 60;
# 请求限制
client_max_body_size 100m;
client_body_buffer_size 128k;
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
# Gzip 压缩
gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml application/json
application/javascript application/xml
application/xml+rss image/svg+xml;
gzip_vary on;
# 文件缓存
open_file_cache max=65535 inactive=60s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
# 隐藏版本号
server_tokens off;
# 引入站点配置
include /etc/nginx/conf.d/*.conf;
}
站点配置模板
# /etc/nginx/conf.d/example.conf
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
# 强制 HTTPS 跳转
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
# SSL 证书
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# 网站根目录
root /var/www/example;
index index.html index.htm;
# 访问日志
access_log /var/log/nginx/example.access.log main;
error_log /var/log/nginx/example.error.log;
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# 默认处理
location / {
try_files $uri $uri/ /index.html;
}
# API 代理
location /api/ {
proxy_pass http://127.0.0.1:8080/;
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;
}
# 静态资源
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# 错误页面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
}
总结
本章详细介绍了 Nginx 配置文件的各个组成部分:
- 配置结构:全局块、events 块、http 块、server 块、location 块
- 全局配置:进程管理、错误日志、环境变量
- events 配置:连接数、事件模型、accept_mutex
- http 配置:MIME 类型、日志、压缩、超时、文件传输
- server 配置:listen、server_name、root、alias
- location 配置:匹配规则、优先级、内部 location
- 变量系统:内置变量、自定义变量、map 指令
- 条件判断:if 指令及其最佳实践