Nginx 核心配置文件总结
Nginx 是一款高性能的 HTTP 和反向代理服务器,以高并发、低内存消耗的特性被广泛应用于互联网架构中。掌握 Nginx 配置是运维和开发人员的必备技能,本文将从配置文件结构 、核心配置详解 、虚拟主机实践 、Location 匹配规则等维度,结合 Ubuntu 24.04 系统环境,全方位讲解 Nginx 配置的原理与实操。
一、Nginx 配置文件基础
1.1 配置文件目录结构(例Ubuntu 24.04 apt 安装)
使用 apt 安装的 Nginx,配置文件默认存放在 /etc/nginx 目录下,各文件/目录功能如下:
| 文件/目录 | 功能说明 |
|---|---|
nginx.conf |
Nginx 主配置文件,全局配置入口 |
conf.d/ |
子配置文件目录,主配置文件通过 include 引用,默认空 |
sites-available/ |
存放所有虚拟主机配置文件(未生效) |
sites-enabled/ |
存放生效的虚拟主机配置文件(通过软链接指向 sites-available) |
modules-available/ |
可用模块配置文件目录 |
modules-enabled/ |
生效模块配置文件目录(软链接指向 modules-available) |
snippets/ |
通用配置片段目录(如 SSL 配置、反向代理配置) |
mime.types |
文件扩展名与 MIME 类型的映射表 |
fastcgi_params/proxy_params |
FastCGI/反向代理的默认参数配置 |
koi-utf/koi-win/win-utf |
字符集编码转换映射文件 |
1.2 配置文件格式规范与解析原理
Nginx 配置由指令 和指令块构成,其解析过程遵循严格的语法规则和优先级逻辑,核心规范如下:
- 指令格式:每条指令以分号
;结尾,指令与参数之间用空格分隔,例如listen 80;。 - 指令块结构:以大括号
{}包裹,支持嵌套层级(全局 → events → http → server → location),层级越内层优先级越高。 - 引用机制:
include语句用于引入外部配置文件,支持通配符(如include /etc/nginx/conf.d/*.conf;),可拆分复杂配置提升可维护性。 - 注释规则:以井号
#开头,注释内容不会被解析执行,可用于标注配置用途。 - 变量体系:以美元符
$开头,分为内置变量(如$uri请求路径、$host主机名)和自定义变量(通过set $var value;定义),变量值在请求处理时动态生成。 - 正则支持:部分指令参数支持正则表达式(如
location匹配、rewrite重写),通过特定修饰符区分匹配规则。
配置解析原理 :Nginx 启动时会通过"词法分析→语法分析→语义分析"三步构建语法树(AST)。词法分析将配置文本拆分为关键字、参数等token;语法分析验证token序列合法性并构建层级结构;语义分析绑定模块处理函数并验证参数有效性,最终转化为内存中的配置结构体供进程调用。动态重载(nginx -s reload)时,Master进程会重新解析配置并启动新Worker进程,旧进程处理完存量连接后退出,实现无中断更新。
二、Nginx 核心配置段详解
Nginx 配置文件的完整结构分为 全局配置段 、events 配置段 、http 配置段 、server 配置段 、location 配置段 、stream 配置段 、mail 配置段七层,层级关系如下:
nginx
# 1. 全局配置段(影响整个 Nginx 服务)
user www-data;
worker_processes auto;
# 2. events 配置段(影响 Nginx 与内核的网络连接)
events {
worker_connections 768;
}
# 3. http 配置段(影响 HTTP/HTTPS 协议的所有请求)
http {
include mime.types;
default_type application/octet-stream;
# 4. server 配置段(虚拟主机配置,对应一个域名/IP/端口)
server {
listen 80;
server_name localhost;
# 5. location 配置段(URL 路径匹配规则)
location / {
root /var/www/html;
index index.html;
}
}
}
# 6. stream 配置段(处理 TCP/UDP 流量转发)
stream {
upstream tcp_backend {
server 192.168.1.10:8080;
}
server {
listen 8080;
proxy_pass tcp_backend;
}
}
# 7. mail 配置段(邮件代理服务配置)
mail {
server {
listen 25;
protocol smtp;
proxy_pass smtp_backend;
}
}
2.1 全局配置段(进程与资源基础)
全局配置段位于配置文件最外层,用于设置 Nginx 服务的基础运行参数,直接影响进程管理和资源分配,核心指令及原理如下:
| 指令 | 语法 | 功能说明与核心原理 |
|---|---|---|
user |
user [user] [group]; |
指定 Worker 进程的运行用户和组(默认 nobody nobody),通过权限隔离避免进程过度权限,提升安全性。 |
worker_processes |
worker_processes auto N; |
设置 Worker 进程数量,auto 自动匹配 CPU 核心数,N 为具体数值。原理:Nginx 采用 Master-Worker 多进程模型,Master 管理进程,Worker 处理请求,每个 Worker 为单线程,绑定一个 CPU 核心时性能最优。 |
worker_cpu_affinity |
worker_cpu_affinity cpumask...; |
将 Worker 进程绑定到指定 CPU 核心,如 0001 0010 0100 1000 对应 4 个核心绑定 4 个进程。原理:避免进程在核心间切换导致的 CPU 缓存失效(cache miss),减少调度开销,提升处理效率。 |
pid |
pid /path/to/pid.file; |
存储 Master 进程 PID 的文件路径(默认 /run/nginx.pid),用于进程管理(启动/停止/重载)时定位进程。 |
worker_priority |
worker_priority N; |
设置 Worker 进程优先级(nice 值),取值范围 -20~19,值越小优先级越高,可优先抢占 CPU 资源。 |
worker_rlimit_nofile |
worker_rlimit_nofile N; |
限制单个 Worker 进程可打开的最大文件描述符数量。原理:Linux 中一切皆文件(网络连接、日志文件等),每个连接占用一个文件描述符,此参数直接决定单进程最大连接能力。 |
daemon |
daemon on off; |
是否以守护进程模式运行,on 为后台运行(默认),off 为前台运行(用于调试或容器环境)。 |
master_process |
master_process on off; |
是否启用 Master-Worker 模式,on 为默认(生产环境),off 仅运行 Master 进程(开发调试用)。 |
核心原理:文件描述符与最大并发连接数
Nginx 的最大并发连接数受三层限制,需协同配置才能发挥最优性能:
- 系统级限制 :通过
ulimit -n查看,默认通常为 1024,高并发场景需修改/etc/security/limits.conf永久提升(如* soft nofile 65535、* hard nofile 65535)。 - Nginx 进程级限制 :
worker_rlimit_nofile需设置为不低于系统级限制,否则文件描述符不足会导致too many open files错误。 - Nginx 连接级限制 :
worker_connections为单个 Worker 进程的最大连接数,不能超过worker_rlimit_nofile。
并发连接数计算公式:
- 作为 Web 服务器(直接处理请求):最大并发数 = worker_processes × worker_connections
- 作为反向代理服务器(需与后端建立连接):最大并发数 = (worker_processes × worker_connections) / 2(每个请求占用客户端和后端两个连接)
例如:8 核 CPU(worker_processes=8)、worker_connections=65535 时,Web 服务器模式最大并发约 52 万,反向代理模式约 26 万。
实操:CPU 绑定与文件描述符优化
-
查看 CPU 核心数与当前文件描述符限制:
bashcat /proc/cpuinfo | grep processor | wc -l # 查看 CPU 核心数 ulimit -n # 查看当前进程文件描述符限制 -
配置 CPU 绑定与资源限制:
nginxworker_processes auto; # 自动匹配 CPU 核心数 worker_cpu_affinity auto; # 自动绑定 Worker 到 CPU 核心(Nginx 1.9.10+ 支持) worker_rlimit_nofile 65535; # 单 Worker 最大文件描述符 -
永久修改系统文件描述符限制:
bashecho "* soft nofile 65535" >> /etc/security/limits.conf echo "* hard nofile 65535" >> /etc/security/limits.conf -
验证配置:
bashsystemctl restart nginx ps axo pid,cmd,psr | grep nginx # psr 列显示进程绑定的 CPU 核心 nginx -t # 验证配置语法
2.2 events 配置段(网络连接优化)
events 配置段用于设置 Nginx 的事件驱动模型和网络连接参数,决定了 Nginx 处理并发连接的效率,核心指令及原理如下:
| 指令 | 语法 | 功能说明与核心原理 |
|---|---|---|
worker_connections |
worker_connections N; |
单个 Worker 进程支持的最大并发连接数(默认 768),需小于 worker_rlimit_nofile 和系统限制,是并发能力的直接配置项。 |
multi_accept |
multi_accept on off; |
on 表示 Worker 进程一次接收所有新连接(默认 off),减少系统调用次数,提升高并发场景下的连接接收效率。 |
accept_mutex |
accept_mutex on off; |
开启连接互斥锁(默认 on),避免多个 Worker 进程同时争抢同一连接导致的"惊群效应",平衡进程负载。 |
use |
use method; |
指定事件驱动模型,可选 select/poll/epoll/kqueue。原理:epoll 是 Linux 2.6+ 内核的高效模型,支持海量连接的异步通知,无连接数限制,性能远优于 select/poll(需线性扫描连接),Nginx 会自动选择最优模型,显式配置更稳妥。 |
accept_mutex_delay |
accept_mutex_delay Nms; |
当 accept_mutex 开启时,设置 Worker 进程尝试获取互斥锁的延迟时间(默认 500ms),避免进程频繁尝试导致的资源消耗。 |
核心原理:I/O 多路复用模型
Nginx 基于 I/O 多路复用模型实现高并发,核心逻辑是:单个 Worker 进程通过事件模型(如 epoll)同时监听多个连接,仅当连接状态就绪(如客户端发送数据、后端返回响应)时才进行读写操作,无需为每个连接创建线程,减少线程调度和内存开销。这种模型使 Nginx 能以极少的内存占用(每 Worker 进程约 2-4MB)支撑数万甚至数十万并发连接。
2.3 http 配置段(HTTP/HTTPS 核心配置)
http 配置段是 Nginx 处理 Web 请求的核心,用于设置 HTTP 协议的全局参数,包括 MIME 类型、日志、压缩、缓存等,核心指令及原理如下:
| 指令 | 语法 | 功能说明与核心原理 |
|---|---|---|
sendfile |
sendfile on off; |
启用零拷贝技术(默认 off),原理:数据直接从内核缓冲区发送到网络,无需经过用户空间(Nginx 进程),减少两次内存拷贝(内核→用户→内核)和上下文切换,极大提升静态文件传输效率。 |
tcp_nopush |
tcp_nopush on off; |
配合 sendfile on 使用(默认 off),数据包满载后再发送,减少网络报文数量,提升传输效率,适用于大文件传输。 |
tcp_nodelay |
tcp_nodelay on off; |
针对长连接启用(默认 on),立即发送小数据包,禁用 Nagle 算法(避免延迟合并),降低交互性场景(如聊天、支付)的延迟,与 tcp_nopush 可同时启用(分别优化大/小包传输)。 |
keepalive_timeout |
keepalive_timeout timeout [header_timeout]; |
HTTP 长连接超时时间(默认 75s),长连接可避免频繁建立 TCP 连接的开销(三次握手/四次挥手),提升重复请求效率,header_timeout 用于设置响应头 Keep-Alive: timeout=value。 |
keepalive_requests |
keepalive_requests N; |
单个长连接允许处理的最大请求数(默认 100),超过后关闭连接,避免长连接占用资源过久。 |
charset |
charset utf-8 off; |
设置响应头的字符集(如 utf-8),告知客户端如何解析响应内容,避免乱码。 |
server_tokens |
server_tokens on off build; |
是否在响应头显示 Nginx 版本信息(默认 on),off 可隐藏版本号,减少黑客针对性攻击风险。 |
gzip |
gzip on off; |
启用 Gzip 压缩(默认 off),原理:对文本类资源(HTML、CSS、JS)进行压缩后传输,减少带宽占用和加载时间,压缩率通常可达 70% 以上。 |
gzip_comp_level |
gzip_comp_level 1-9; |
Gzip 压缩级别(1 最快,9 压缩率最高),推荐 3-5(平衡速度与压缩率),级别越高 CPU 消耗越大。 |
gzip_types |
gzip_types mime-type...; |
指定需要压缩的 MIME 类型(默认仅 text/html),建议添加 text/css application/javascript application/json image/svg+xml 等常见类型。 |
gzip_vary |
gzip_vary on off; |
启用时添加响应头 Vary: Accept-Encoding,告知缓存服务器区分压缩与未压缩版本,避免缓存错乱。 |
access_log |
access_log path [format]; |
配置访问日志路径和格式(默认 /var/log/nginx/access.log),记录请求时间、客户端 IP、请求方法、状态码等信息,用于流量分析和问题排查,access_log off; 可关闭日志(提升性能)。 |
error_log |
error_log path [level]; |
配置错误日志路径和级别(级别:debug/info/notice/warn/error/crit),级别越低日志越详细,默认 /var/log/nginx/error.log,用于定位配置错误、连接失败等问题。 |
client_max_body_size |
client_max_body_size size; |
限制客户端请求体最大尺寸(默认 1m),超过则返回 413 错误,用于防止大文件上传耗尽服务器资源。 |
实操 1:Gzip 压缩优化配置
nginx
http {
gzip on;
gzip_comp_level 4;
gzip_types text/html text/css application/javascript application/json image/svg+xml text/plain;
gzip_vary on;
gzip_min_length 20; # 小于 20 字节的文件不压缩(避免压缩开销大于收益)
gzip_buffers 16 8k; # 压缩缓冲区大小(16 个 8k 缓冲区)
}
实操 2:隐藏 Nginx 版本信息
nginx
http {
server_tokens off;
}
验证效果:
bash
curl -I http://服务器IP # 响应头 Server: nginx(无版本号)
2.4 stream 配置段(TCP/UDP 流量转发)
stream 模块用于处理 TCP/UDP 四层协议流量,适用于数据库代理、Redis 负载均衡、WebSocket 代理、游戏服务器流量分发等场景,无需解析应用层协议,转发效率高。
核心指令与原理
| 指令 | 语法 | 功能说明与核心原理 |
|---|---|---|
upstream |
upstream name { ... } |
定义后端服务器集群,支持轮询、最少连接、IP 哈希等负载均衡策略,用于流量分发。 |
proxy_pass |
proxy_pass upstream_name address; |
将客户端流量转发到指定上游集群或后端地址,是 stream 模块的核心转发指令。 |
listen |
listen address[:port] [udp]; |
监听指定 IP 和端口,添加 udp 关键字表示处理 UDP 流量(默认 TCP)。 |
proxy_timeout |
proxy_timeout Ns; |
客户端与 Nginx、Nginx 与后端服务器的连接超时时间(默认 10m),超时后关闭连接。 |
proxy_connect_timeout |
proxy_connect_timeout Ns; |
Nginx 与后端服务器建立连接的超时时间(默认 10s),避免连接超时阻塞。 |
ssl_preread |
ssl_preread on off; |
启用 TLS 预读(默认 off),支持对加密 TCP 流量(如 HTTPS、SSL 数据库连接)进行转发,无需解密即可获取 SNI 等信息。 |
负载均衡策略
stream 模块支持三种核心负载均衡策略,适配不同场景:
round-robin(默认):轮询分发请求,适用于后端服务器性能一致的场景。least_conn:将请求转发到当前连接数最少的后端服务器,适用于长连接服务(如 MySQL、Redis)。hash $remote_addr:按客户端 IP 哈希分配,确保同一客户端始终访问同一后端服务器,适用于需要会话保持的场景。
实操 1:MySQL TCP 代理配置
nginx
stream {
# 定义 MySQL 后端集群
upstream mysql_backend {
least_conn; # 最少连接策略
server 192.168.1.10:3306; # 主服务器
server 192.168.1.11:3306 backup; # 备用服务器(主服务器宕机时启用)
}
# MySQL 代理服务
server {
listen 3306; # 监听 3306 端口
proxy_pass mysql_backend;
proxy_connect_timeout 5s; # 连接超时 5 秒
proxy_timeout 300s; # 连接保持超时 5 分钟
}
}
实操 2:DNS UDP 代理配置
nginx
stream {
upstream dns_backend {
server 8.8.8.8:53; # Google DNS
server 8.8.4.4:53; # Google 备用 DNS
}
server {
listen 53 udp; # 监听 UDP 53 端口(DNS 协议)
proxy_pass dns_backend;
proxy_timeout 10s;
}
}
常见问题排查
- 报错
unknown directive "stream":Nginx 未编译 stream 模块,Ubuntu 可通过apt install nginx-full -y安装包含 stream 模块的版本,CentOS 需安装nginx-mod-stream。 - 连接失败:检查防火墙(firewalld/iptables)是否开放监听端口和后端端口,SELinux 可能限制端口访问,可通过
setenforce 0临时关闭验证。
2.5 mail 配置段(邮件代理服务)
mail 模块用于实现邮件代理和负载均衡,支持 SMTP、POP3、IMAP 三种邮件协议,可实现邮件服务器集群负载均衡、SSL 加密、访问控制等功能。
核心指令与原理
| 指令 | 语法 | 功能说明与核心原理 |
|---|---|---|
protocol |
protocol smtppop3 imap; |
指定邮件协议,每个 mail server 块仅支持一种协议。 |
proxy_pass |
proxy_pass upstream_name/address; |
将邮件流量转发到后端邮件服务器或集群。 |
listen |
listen port; |
监听邮件协议默认端口(SMTP 25/587,POP3 110/995,IMAP 143/993)。 |
ssl |
ssl on/off; |
启用 SSL 加密(默认 off),用于安全邮件传输(如 POP3S、IMAPS)。 |
ssl_certificate/ssl_certificate_key |
ssl_certificate /path/cert.pem; |
指定 SSL 证书和私钥路径,用于加密邮件传输。 |
auth_http |
auth_http url; |
指定 HTTP 认证服务器地址,用于邮件用户身份验证(如通过 Web 系统验证邮箱账号密码)。 |
实操:SMTP 邮件代理配置
nginx
mail {
# 定义 SMTP 后端集群
upstream smtp_backend {
server 192.168.1.20:25;
server 192.168.1.21:25 backup;
}
# SMTP 代理服务
server {
listen 25;
protocol smtp;
proxy_pass smtp_backend;
proxy_connect_timeout 10s;
proxy_timeout 60s;
# 启用 SSL(587 端口)
listen 587 ssl;
ssl_certificate /etc/nginx/ssl/mail.crt;
ssl_certificate_key /etc/nginx/ssl/mail.key;
}
# POP3 代理服务
server {
listen 110;
protocol pop3;
proxy_pass 192.168.1.20:110;
}
}
2.6 第三方模块配置(扩展 Nginx 功能)
Nginx 支持通过第三方模块扩展核心功能(如 Brotli 压缩、页面优化、安全防护等),需通过编译方式安装(Nginx 1.9.11+ 支持动态模块,无需重新编译整个 Nginx)。
核心原理与安装规则
- Nginx 模块分为静态模块(编译时集成到 Nginx 二进制文件)和动态模块(编译为
.so文件,通过load_module加载),动态模块更灵活,便于升级维护。 - 安装第三方模块时,需先获取当前 Nginx 的编译参数(
nginx -V),重新编译时需包含原有参数,避免覆盖已安装模块。 - 动态模块编译需添加
--with-compat参数,确保模块兼容性,编译后通过load_module指令加载即可生效。
实操:安装 Brotli 压缩模块(动态模块)
Brotli 是比 Gzip 压缩率更高的算法,适用于文本、图片等资源,以下是安装步骤:
-
安装依赖工具链:
bashsudo apt install build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev -y -
获取 Nginx 版本和源码:
bashnginx_version=$(nginx -v 2>&1 | awk -F/ '{print $2}') wget http://nginx.org/download/nginx-${nginx_version}.tar.gz tar zxvf nginx-${nginx_version}.tar.gz -
下载 Brotli 模块源码:
bashgit clone --recursive https://github.com/google/ngx_brotli.git cd ngx_brotli && git submodule update --init && cd .. -
编译动态模块:
bashcd nginx-${nginx_version} # 查看原有编译参数并添加模块参数 ./configure $(nginx -V 2>&1 | awk -F ': ' '{print $2}') --with-compat --add-dynamic-module=../ngx_brotli make modules # 仅编译模块,不安装 -
安装模块文件:
bashsudo cp objs/ngx_http_brotli_filter_module.so /usr/share/nginx/modules/ sudo cp objs/ngx_http_brotli_static_module.so /usr/share/nginx/modules/ -
加载模块并配置:
-
创建模块加载配置文件
/etc/nginx/modules-enabled/50-mod-http-brotli.conf:nginxload_module /usr/share/nginx/modules/ngx_http_brotli_filter_module.so; load_module /usr/share/nginx/modules/ngx_http_brotli_static_module.so; -
在 http 段添加 Brotli 配置:
nginxhttp { brotli on; brotli_comp_level 6; # 压缩级别 1-11,6 为平衡值 brotli_types text/plain text/css application/json application/javascript text/xml image/svg+xml; brotli_min_length 20; # 小于 20 字节不压缩 }
-
-
验证生效:
bashsudo nginx -t && sudo systemctl reload nginx # 测试压缩效果 curl -I -H 'Accept-Encoding: br' http://服务器IP | grep -i content-encoding
三、虚拟主机配置(Server 段)
虚拟主机(Virtual Host)允许一台服务器运行多个网站,Nginx 支持基于端口 、基于 IP 、基于域名 三种配置方式,核心通过 listen 和 server_name 指令区分。
3.1 虚拟主机核心指令与原理
| 指令 | 语法 | 功能说明与核心原理 |
|---|---|---|
listen |
listen address[:port] [default_server] [ssl]; |
指定虚拟主机监听的 IP 和端口,default_server 表示默认虚拟主机(匹配不到其他主机时使用),ssl 表示启用 HTTPS。 |
server_name |
server_name name...; |
指定虚拟主机的域名,支持多个域名(空格分隔)、通配符(*.example.com 匹配二级域名)、正则表达式(~^www\d+\.example\.com$ 匹配 www1.example.com 等)。原理:Nginx 通过解析请求头 Host 字段,匹配对应的 server_name 实现域名路由。 |
root |
root /path/to/webroot; |
指定网站根目录,Nginx 会将请求 URI 拼接在根目录后查找文件(如 root /var/www/html,请求 /index.html 对应 /var/www/html/index.html)。 |
index |
index file...; |
指定默认首页文件(如 index.html index.php),请求目录时按顺序查找存在的文件并返回。 |
error_page |
error_page code... [=response] uri; |
自定义错误页面,如 error_page 404 /404.html 表示 404 错误返回 /404.html,=response 可修改响应状态码(如 error_page 404 =200 /404.html)。 |
access_log/error_log |
同 http 段指令 | 可在 server 段单独配置日志,覆盖 http 段全局配置,实现单网站日志隔离。 |
3.2 三种虚拟主机配置实践
环境准备
-
创建网站根目录和测试页面:
bashmkdir -p /data/server/nginx/web{1..3} echo "Web1: 基于端口" > /data/server/nginx/web1/index.html echo "Web2: 基于 IP" > /data/server/nginx/web2/index.html echo "Web3: 基于域名" > /data/server/nginx/web3/index.html -
删除默认配置(避免冲突):
bashrm -f /etc/nginx/sites-enabled/default
方式 1:基于端口的虚拟主机
不同网站使用同一 IP、不同端口区分,适用于开发环境或内部服务。
nginx
#cat > /etc/nginx/conf.d/vhost.conf <<-eof
server {
listen 80;
server_name _; # 匹配任意域名/IP
root /data/server/nginx/web1;
index index.html;
}
server {
listen 81;
server_name _;
root /data/server/nginx/web2;
index index.html;
}
eof
验证效果:
bash
systemctl restart nginx
curl http://10.0.0.13:80 # 输出 Web1: 基于端口
curl http://10.0.0.13:81 # 输出 Web2: 基于 IP
实操显示:
bash
root@Ubuntu24-13:~# systemctl is-active nginx
active
root@Ubuntu24-13:~# mkdir -p /data/server/nginx/web{1..3}
echo "Web1: 基于端口" > /data/server/nginx/web1/index.html
echo "Web2: 基于 IP" > /data/server/nginx/web2/index.html
echo "Web3: 基于域名" > /data/server/nginx/web3/index.html
root@Ubuntu24-13:~#
root@Ubuntu24-13:~#
root@Ubuntu24-13:~# rm -f /etc/nginx/sites-enabled/default
root@Ubuntu24-13:~#
root@Ubuntu24-13:~#
root@Ubuntu24-13:~# cat > /etc/nginx/conf.d/vhost.conf <<-eof
server {
listen 80;
server_name _; # 匹配任意域名/IP
root /data/server/nginx/web1;
index index.html;
}
server {
listen 81;
server_name _;
root /data/server/nginx/web2;
index index.html;
}
eof
root@Ubuntu24-13:~# systemctl restart nginx
root@Ubuntu24-13:~# curl http://10.0.0.13:80
Web1: 基于端口
root@Ubuntu24-13:~# curl http://10.0.0.13:81
Web2: 基于 IP
方式 2:基于 IP 的虚拟主机
为服务器绑定多个 IP,不同 IP 对应不同网站,适用于需要独立 IP 的场景。
-
绑定多个 IP 到网卡(临时生效,重启失效):
baship addr add 10.0.0.123/24 dev ens33 ip addr add 10.0.0.124/24 dev ens33 -
配置虚拟主机:
nginx#cat > /etc/nginx/conf.d/vhost.conf <<-eof server { listen 10.0.0.123:80; root /data/server/nginx/web2; index index.html; }cat server { listen 10.0.0.124:80; root /data/server/nginx/web3; index index.html; } eof
验证效果:
bash
curl http://10.0.0.123 # 输出 Web2: 基于 IP
curl http://10.0.0.124 # 输出 Web3: 基于域名
实操显示:
bash
root@Ubuntu24-13:~# cat /etc/nginx/conf.d/vhost.conf
server {
listen 10.0.0.123:80;
root /data/server/nginx/web2;
index index.html;
}
server {
listen 10.0.0.124:80;
root /data/server/nginx/web3;
index index.html;
}
root@Ubuntu24-13:~# systemctl restart nginx
root@Ubuntu24-13:~# curl http://10.0.0.123
Web2: 基于 IP
root@Ubuntu24-13:~# curl http://10.0.0.124
Web3: 基于域名
方式 3:基于域名的虚拟主机
最常用的方式,同一 IP 和端口通过域名区分,适用于生产环境多网站部署。
nginx
server {
listen 80 default_server; # 默认虚拟主机
server_name www.a.com;
root /data/server/nginx/web1;
index index.html;
}
server {
listen 80;
server_name www.b.com;
root /data/server/nginx/web2;
index index.html;
}
验证效果(需配置本地 hosts 解析或 DNS 解析):
bash
# 本地 hosts 配置(Windows:C:\Windows\System32\drivers\etc\hosts;Linux:/etc/hosts)
echo "10.0.0.13 www.a.com www.b.com" >> /etc/hosts
curl http://www.a.com # 输出 Web1: 基于端口
curl http://www.b.com # 输出 Web2: 基于 IP
实操显示:
bash
root@Ubuntu24-13:~# vim /etc/nginx/conf.d/vhost.conf
root@Ubuntu24-13:~# cat /etc/nginx/conf.d/vhost.conf
server {
listen 80 default_server; # 默认虚拟主机
server_name www.a.com;
root /data/server/nginx/web1;
index index.html;
}
server {
listen 80;
server_name www.b.com;
root /data/server/nginx/web2;
index index.html;
}
root@Ubuntu24-13:~# systemctl restart nginx
root@Ubuntu24-13:~# curl http://www.a.com
curl: (6) Could not resolve host: www.a.com
root@Ubuntu24-13:~# echo "10.0.0.13 www.a.com www.b.com" >> /etc/hosts
root@Ubuntu24-13:~# curl http://www.a.com
Web1: 基于端口
root@Ubuntu24-13:~# curl http://www.b.com
Web2: 基于 IP
root@Ubuntu24-13:~#
四、Location 配置与 URL 匹配规则
Location 配置段用于匹配请求的 URL 路径,并执行对应的处理规则(如转发、静态文件返回、访问控制),是 Nginx 路由控制的核心。
4.1 Location 语法与匹配类型
Location 基本语法:
nginx
location [修饰符] uri {
# 处理指令
}
修饰符决定匹配规则的优先级(从高到低),不同修饰符对应不同匹配逻辑,核心类型如下:
| 修饰符 | 匹配规则 | 优先级 | 示例 |
|---|---|---|---|
= |
精确匹配 | 1(最高) | location = / 仅匹配 http://域名/,不匹配 /index.html 或 /test |
^~ |
前缀匹配(非正则) | 2 | location ^~ /static/ 匹配 /static/css/style.css,匹配后停止后续正则匹配 |
~ |
正则匹配(区分大小写) | 3 | location ~ \.php$ 匹配 .php 结尾的请求,不匹配 .PHP |
~* |
正则匹配(不区分大小写) | 3 | `location ~* .(jpg |
| 无修饰符 | 普通前缀匹配(支持正则) | 4(最低) | location /img 匹配 /img、/img123、/image 等路径 |
@ |
命名 location | - | 用于内部重定向(如 error_page 500 @error50x),不直接处理客户端请求 |
4.2 匹配优先级原理与流程
Nginx 处理 Location 匹配的核心流程:
- 首先查找所有
=修饰符的精确匹配,匹配成功则立即执行对应规则,终止后续匹配。 - 若无精确匹配,查找
^~修饰符的前缀匹配,匹配成功则终止后续匹配(跳过正则匹配)。 - 若无
^~匹配,按配置顺序依次检查~/~*正则匹配,第一个匹配成功的规则生效。 - 若无正则匹配,查找普通前缀匹配(无修饰符),匹配最长前缀的规则生效。
- 若所有规则均不匹配,返回 404 错误。
核心原理:Location 匹配优先级的设计逻辑是"精确匹配优先于模糊匹配,前缀匹配优先于正则匹配",确保路由规则的灵活性和确定性,避免匹配冲突。
优先级实战验证
配置示例:
nginx
server {
listen 80;
server_name localhost;
# 1. 精确匹配 /
location = / {
return 200 "精确匹配: /\n";
}
# 2. 前缀匹配 /static/,停止后续正则匹配
location ^~ /static/ {
return 200 "前缀匹配: /static/\n";
}
# 3. 正则匹配 .jpg/.png 结尾(区分大小写)
location ~ \.(jpg|png)$ {
return 200 "正则匹配: 图片文件\n";
}
# 4. 正则匹配 .html 结尾(不区分大小写)
location ~* \.html$ {
return 200 "正则匹配: HTML 文件\n";
}
# 5. 普通前缀匹配(默认规则)
location / {
return 200 "普通前缀匹配: /\n";
}
}
测试匹配结果:
| 请求 URL | 匹配规则 | 输出结果 |
|---|---|---|
http://localhost/ |
精确匹配 = |
精确匹配: / |
http://localhost/static/css/style.css |
前缀匹配 ^~ |
前缀匹配: /static/ |
http://localhost/test.jpg |
正则匹配 ~ |
正则匹配: 图片文件 |
http://localhost/TEST.HTML |
正则匹配 ~* |
正则匹配: HTML 文件 |
http://localhost/index.php |
普通前缀匹配 / |
普通前缀匹配: / |
4.3 root 与 alias 核心区别(路径映射原理)
root 和 alias 均用于指定文件路径,但映射逻辑完全不同,是配置中的高频易错点,核心区别如下:
| 指令 | 映射原理 | 路径拼接规则 | 示例 |
|---|---|---|---|
root |
路径拼接:root 目录 + location 路径 作为最终文件路径 |
最终路径 = root 配置值 + location URI | location /img/ { root /var/www; },请求 /img/1.jpg 对应 /var/www/img/1.jpg |
alias |
路径替换:直接将 location 路径 替换为 alias 目录,需以 / 结尾 |
最终路径 = alias 配置值 + location URI 去除匹配前缀 | location /img/ { alias /var/www/images/; },请求 /img/1.jpg 对应 /var/www/images/1.jpg |
关键注意事项
alias必须以/结尾,否则会导致路径拼接错误(如alias /var/www/images会匹配/img/1.jpg为/var/www/images1.jpg)。root适用于目录结构与 URL 路径一致的场景(如静态文件服务器),alias适用于 URL 路径与实际文件路径不一致的场景(如隐藏真实目录结构)。
实操对比测试
-
准备测试文件:
bashmkdir -p /var/www/images echo "Alias Test" > /var/www/images/1.jpg -
配置对比:
nginx# root 配置(路径拼接) location /img_root/ { root /var/www/images; # 无结尾 / index 1.jpg; } # alias 配置(路径替换) location /img_alias/ { alias /var/www/images/; # 必须加结尾 / index 1.jpg; } -
测试结果:
bash# root 配置:实际路径为 /var/www/images/img_root/1.jpg(不存在,返回 404) curl http://localhost/img_root/1.jpg # 404 Not Found # alias 配置:实际路径为 /var/www/images/1.jpg(存在,正常返回) curl http://localhost/img_alias/1.jpg # 输出 Alias Test
五、常用功能配置(含原理与实操)
5.1 自定义错误页面(错误处理机制)
Nginx 错误页面配置支持直接指向文件或内部重定向,核心原理是:当请求返回指定状态码时,Nginx 会根据 error_page 配置返回对应的页面或执行跳转,internal 指令可限制页面仅内部访问,禁止客户端直接请求。
nginx
server {
listen 80;
server_name localhost;
root /var/www/html;
# 方式 1:直接指向错误页面文件
error_page 404 /404.html;
location = /404.html {
internal; # 仅允许内部访问,禁止直接访问 http://localhost/404.html
}
# 方式 2:重定向到命名 location
error_page 500 502 503 504 @error50x;
location @error50x {
default_type text/html;
return 503 "<h1>Server Error</h1><p>Please try again later.</p>";
}
}
5.2 访问控制(IP 黑白名单)
通过 allow 和 deny 指令限制客户端 IP 访问,核心原理是:按配置顺序依次匹配 IP,匹配到 allow 则允许访问,匹配到 deny 则拒绝访问,未匹配到则默认拒绝(遵循"先匹配先生效"原则)。
nginx
location /admin/ {
# 白名单:允许 192.168.1.0/24 网段和 127.0.0.1 访问
allow 192.168.1.0/24;
allow 127.0.0.1;
# 黑名单:拒绝其他所有 IP(必须放在最后)
deny all;
}
5.3 静态文件缓存优化(浏览器缓存原理)
通过设置响应头 Cache-Control 和 Expires 实现浏览器缓存,减少重复请求,核心原理是:告知浏览器静态文件的缓存时长,在缓存有效期内无需再次请求服务器,直接使用本地缓存。
nginx
location ~* \.(jpg|png|gif|css|js)$ {
root /var/www/html;
# 设置缓存时长为 7 天
expires 7d;
# 缓存控制:公共缓存(可被代理服务器缓存),max-age 优先级高于 expires
add_header Cache-Control "public, max-age=604800";
# 关闭日志(减少 IO 开销)
access_log off;
}
六、配置验证与重载(无中断更新原理)
Nginx 配置修改后,需通过验证和重载确保配置正确且不中断服务,核心操作及原理如下:
6.1 配置语法验证
bash
nginx -t # 验证配置语法正确性
- 语法正确输出:
nginx: configuration file /etc/nginx/nginx.conf test is successful - 语法错误输出:会提示错误位置和原因(如缺少分号、指令拼写错误),需修复后再重载。
6.2 平滑重载配置
bash
systemctl reload nginx # 推荐方式(系统服务管理)
# 或
nginx -s reload # 直接调用 Nginx 命令
平滑重载原理:
- Master 进程接收 reload 信号后,重新读取并解析配置文件,构建新的语法树。
- Master 进程 fork 新的 Worker 进程,新进程加载新配置并开始接收和处理新连接。
- 旧 Worker 进程继续处理已建立的存量连接,不再接收新请求。
- 旧 Worker 进程处理完所有存量连接后,自动退出,实现配置无中断更新。
6.3 其他常用命令
- 启动 Nginx:
systemctl start nginx - 停止 Nginx:
systemctl stop nginx - 查看 Nginx 状态:
systemctl status nginx - 强制停止:
nginx -s stop(立即终止进程,可能导致连接中断) - 优雅停止:
nginx -s quit(处理完存量连接后停止)
七、总结
本文从 Nginx 配置文件结构讲解了全局配置 、events 配置 、http 配置 、stream 配置 、mail 配置 、虚拟主机 、Location 匹配等核心内容,补充了文件描述符、并发连接数、CPU 绑定、I/O 多路复用等底层原理,并结合实操案例帮助理解。
Nginx 配置的核心逻辑是"层级化配置+模块化扩展",通过合理调整进程数、连接数、事件模型等参数,可充分发挥服务器硬件性能;通过虚拟主机和 Location 规则,可灵活实现多网站部署和精准路由;通过第三方模块和 stream/mail 模块,可扩展 Nginx 至负载均衡、数据库代理、邮件服务等场景。