nginx核心配置总结,并实现nginx多虚拟主机

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 配置由指令指令块构成,其解析过程遵循严格的语法规则和优先级逻辑,核心规范如下:

  1. 指令格式:每条指令以分号 ; 结尾,指令与参数之间用空格分隔,例如 listen 80;
  2. 指令块结构:以大括号 {} 包裹,支持嵌套层级(全局 → events → http → server → location),层级越内层优先级越高。
  3. 引用机制:include 语句用于引入外部配置文件,支持通配符(如 include /etc/nginx/conf.d/*.conf;),可拆分复杂配置提升可维护性。
  4. 注释规则:以井号 # 开头,注释内容不会被解析执行,可用于标注配置用途。
  5. 变量体系:以美元符 $ 开头,分为内置变量(如 $uri 请求路径、$host 主机名)和自定义变量(通过 set $var value; 定义),变量值在请求处理时动态生成。
  6. 正则支持:部分指令参数支持正则表达式(如 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 的最大并发连接数受三层限制,需协同配置才能发挥最优性能:

  1. 系统级限制 :通过 ulimit -n 查看,默认通常为 1024,高并发场景需修改 /etc/security/limits.conf 永久提升(如 * soft nofile 65535* hard nofile 65535)。
  2. Nginx 进程级限制worker_rlimit_nofile 需设置为不低于系统级限制,否则文件描述符不足会导致 too many open files 错误。
  3. 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 绑定与文件描述符优化
  1. 查看 CPU 核心数与当前文件描述符限制:

    bash 复制代码
    cat /proc/cpuinfo | grep processor | wc -l  # 查看 CPU 核心数
    ulimit -n  # 查看当前进程文件描述符限制
  2. 配置 CPU 绑定与资源限制:

    nginx 复制代码
    worker_processes auto;  # 自动匹配 CPU 核心数
    worker_cpu_affinity auto;  # 自动绑定 Worker 到 CPU 核心(Nginx 1.9.10+ 支持)
    worker_rlimit_nofile 65535;  # 单 Worker 最大文件描述符
  3. 永久修改系统文件描述符限制:

    bash 复制代码
    echo "* soft nofile 65535" >> /etc/security/limits.conf
    echo "* hard nofile 65535" >> /etc/security/limits.conf
  4. 验证配置:

    bash 复制代码
    systemctl 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 模块支持三种核心负载均衡策略,适配不同场景:

  1. round-robin(默认):轮询分发请求,适用于后端服务器性能一致的场景。
  2. least_conn:将请求转发到当前连接数最少的后端服务器,适用于长连接服务(如 MySQL、Redis)。
  3. 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 压缩率更高的算法,适用于文本、图片等资源,以下是安装步骤:

  1. 安装依赖工具链:

    bash 复制代码
    sudo apt install build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev -y
  2. 获取 Nginx 版本和源码:

    bash 复制代码
    nginx_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
  3. 下载 Brotli 模块源码:

    bash 复制代码
    git clone --recursive https://github.com/google/ngx_brotli.git
    cd ngx_brotli && git submodule update --init && cd ..
  4. 编译动态模块:

    bash 复制代码
    cd nginx-${nginx_version}
    # 查看原有编译参数并添加模块参数
    ./configure $(nginx -V 2>&1 | awk -F ': ' '{print $2}') --with-compat --add-dynamic-module=../ngx_brotli
    make modules  # 仅编译模块,不安装
  5. 安装模块文件:

    bash 复制代码
    sudo 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/
  6. 加载模块并配置:

    • 创建模块加载配置文件 /etc/nginx/modules-enabled/50-mod-http-brotli.conf

      nginx 复制代码
      load_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 配置:

      nginx 复制代码
      http {
          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 字节不压缩
      }
  7. 验证生效:

    bash 复制代码
    sudo nginx -t && sudo systemctl reload nginx
    # 测试压缩效果
    curl -I -H 'Accept-Encoding: br' http://服务器IP | grep -i content-encoding

三、虚拟主机配置(Server 段)

虚拟主机(Virtual Host)允许一台服务器运行多个网站,Nginx 支持基于端口基于 IP基于域名 三种配置方式,核心通过 listenserver_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 三种虚拟主机配置实践

环境准备
  1. 创建网站根目录和测试页面:

    bash 复制代码
    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
  2. 删除默认配置(避免冲突):

    bash 复制代码
    rm -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 的场景。

  1. 绑定多个 IP 到网卡(临时生效,重启失效):

    bash 复制代码
    ip addr add 10.0.0.123/24 dev ens33
    ip addr add 10.0.0.124/24 dev ens33
  2. 配置虚拟主机:

    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 匹配的核心流程:

  1. 首先查找所有 = 修饰符的精确匹配,匹配成功则立即执行对应规则,终止后续匹配。
  2. 若无精确匹配,查找 ^~ 修饰符的前缀匹配,匹配成功则终止后续匹配(跳过正则匹配)。
  3. 若无 ^~ 匹配,按配置顺序依次检查 ~/~* 正则匹配,第一个匹配成功的规则生效。
  4. 若无正则匹配,查找普通前缀匹配(无修饰符),匹配最长前缀的规则生效。
  5. 若所有规则均不匹配,返回 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 核心区别(路径映射原理)

rootalias 均用于指定文件路径,但映射逻辑完全不同,是配置中的高频易错点,核心区别如下:

指令 映射原理 路径拼接规则 示例
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 路径与实际文件路径不一致的场景(如隐藏真实目录结构)。
实操对比测试
  1. 准备测试文件:

    bash 复制代码
    mkdir -p /var/www/images
    echo "Alias Test" > /var/www/images/1.jpg
  2. 配置对比:

    nginx 复制代码
    # root 配置(路径拼接)
    location /img_root/ {
        root /var/www/images;  # 无结尾 /
        index 1.jpg;
    }
    
    # alias 配置(路径替换)
    location /img_alias/ {
        alias /var/www/images/;  # 必须加结尾 /
        index 1.jpg;
    }
  3. 测试结果:

    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 黑白名单)

通过 allowdeny 指令限制客户端 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-ControlExpires 实现浏览器缓存,减少重复请求,核心原理是:告知浏览器静态文件的缓存时长,在缓存有效期内无需再次请求服务器,直接使用本地缓存。

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 命令

平滑重载原理

  1. Master 进程接收 reload 信号后,重新读取并解析配置文件,构建新的语法树。
  2. Master 进程 fork 新的 Worker 进程,新进程加载新配置并开始接收和处理新连接。
  3. 旧 Worker 进程继续处理已建立的存量连接,不再接收新请求。
  4. 旧 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 至负载均衡、数据库代理、邮件服务等场景。

相关推荐
FIT2CLOUD飞致云2 小时前
操作教程丨通过1Panel快速安装Zabbix,搭建企业级监控系统
运维·服务器·开源·zabbix·监控·1panel
Ghost Face...3 小时前
Docker实战:从安装到多容器编排指南
运维·docker·容器
amao99883 小时前
数据库--dataset design
数据库
此生只爱蛋3 小时前
【Linux】正/反向代理
linux·运维·服务器
qq_5470261793 小时前
Linux 基础
linux·运维·arm开发
山沐与山3 小时前
【数据库】PostgreSQL架构与索引深度剖析
数据库·postgresql·架构
废春啊3 小时前
前端工程化
运维·服务器·前端
我只会发热4 小时前
Ubuntu 20.04.6 根目录扩容(图文详解)
linux·运维·ubuntu
爱潜水的小L4 小时前
自学嵌入式day34,ipc进程间通信
linux·运维·服务器