Article
第1章 Nginx 简介与核心概念
1.1 什么是 Nginx
| 概念名称 | 说明 | 注意事项 |
|---|---|---|
| Nginx | 高性能、轻量级的HTTP服务器和反向代理服务器,也可用于IMAP/POP3代理服务 | 读作 “engine x”,最初由 Igor Sysoev 开发,2004年首次发布 |
| 开源软件 | 遵循 BSD 许可证,源代码开放,可自由使用、修改和分发 | 社区活跃,有官方商业版 Nginx Plus 提供额外功能和支持 |
| 设计目标 | 高并发、低内存消耗、高稳定性 | 专为解决C10K问题(1万个并发连接)而设计,适用于高负载场景 |
| 核心功能 | HTTP 服务器、反向代理、负载均衡、静态内容服务、SSL/TLS 支持等 | 不原生支持动态内容处理(如PHP),需配合后端应用服务器(如PHP-FPM)使用 |
1.2 Nginx 的架构与工作原理
| 概念名称 | 说明 | 注意事项 |
|---|---|---|
| 事件驱动架构 | 基于异步非阻塞的事件处理机制,使用 epoll/kqueue 等高效 I/O 多路复用 | 单个进程可处理数万并发连接,资源消耗低 |
| Master-Worker 模型 | Master 进程管理 Worker 进程;Worker 进程处理实际请求 | Master 进程不处理请求,仅负责加载配置、启动 Worker、监控与重启 Worker |
| Master 进程 | 核心管理进程,运行在特权模式,负责读取配置、绑定端口、启动 Worker | 通常以 root 用户运行,避免端口绑定权限问题 |
| Worker 进程 | 实际处理请求的进程,每个 Worker 独立运行,互不干扰 | 数量可配置(worker_processes),建议设为 CPU 核心数 |
| 共享内存 | 多个 Worker 可通过共享内存区域共享数据(如缓存、状态) | 用于实现负载均衡状态共享、限速统计等功能 |
| 配置热加载 | 修改配置后可发送信号使 Master 重新加载配置,无需中断服务 | 使用 nginx -s reload,Master 会启动新 Worker 并优雅关闭旧 Worker |
1.3 Nginx 与 Apache 的对比
| 对比维度 | Nginx | Apache | 注意事项 |
|---|---|---|---|
| 架构模型 | 事件驱动、异步非阻塞 | 进程/线程驱动、同步阻塞(默认) | Nginx 更适合高并发静态资源服务;Apache 在动态内容处理上更成熟 |
| 性能表现 | 高并发下内存占用低,响应速度快 | 高并发时内存消耗较大,性能下降明显 | Nginx 在处理静态文件和反向代理场景下性能优势显著 |
| 配置语法 | 简洁、层级清晰 | 复杂,.htaccess 支持灵活但影响性能 | Nginx 不支持目录级配置文件(如 .htaccess),需集中配置 |
| 模块扩展 | 编译时静态加载或动态加载模块 | 支持运行时动态加载模块(DSO) | Nginx 动态模块需编译支持,灵活性略低 |
| 动态内容支持 | 需配合 FastCGI、uWSGI 等协议 | 原生支持 mod_php、mod_perl 等模块 | Apache 更适合纯 PHP 项目部署;Nginx + PHP-FPM 组合更高效 |
| 社区与生态 | 社区活跃,文档丰富,企业支持(Nginx Plus) | 历史悠久,模块极其丰富,广泛用于传统 Web 项目 | Apache 更适合需要复杂 .htaccess 控制的共享主机环境 |
1.4 Nginx 的应用场景
| 应用场景 | 说明 | 注意事项 |
|---|---|---|
| 静态资源服务器 | 高效提供 HTML、CSS、JS、图片等静态文件 | 配合 gzip 压缩、缓存策略可极大提升性能 |
| 反向代理 | 将客户端请求转发至后端服务器(如 Node.js、Tomcat、Django) | 可隐藏后端真实 IP,实现安全隔离 |
| 负载均衡 | 将请求分发到多个后端服务器,提升可用性与伸缩性 | 支持轮询、IP 哈希、最少连接等策略 |
| HTTPS 终端 | 统一处理 SSL/TLS 加密解密,减轻后端压力 | 可集中管理证书,简化后端部署 |
| API 网关 | 统一入口,实现路由、鉴权、限流、日志等功能 | 常用于微服务架构中 |
| 缓存服务器 | 缓存后端响应内容,减少后端负载 | 支持 proxy_cache 等指令实现页面或片段缓存 |
| 流媒体服务器 | 支持 RTMP 协议,用于视频直播与点播 | 需启用 nginx-rtmp-module 模块 |
| 安全防护 | 防止 DDoS、限制请求频率、防止盗链等 | 结合 limit_req、valid_referers 等指令使用 |
第2章 安装与基础配置
2.1 在 Linux 上安装 Nginx(源码/包管理器)
| 安装方式 | 说明 | 命令示例 | 注意事项 |
|---|---|---|---|
| 使用 YUM 安装 | 适用于 CentOS/RHEL 系统,简单快捷 | yum install -y nginx | 安装版本可能较旧,需配置 EPEL 源 |
| 使用 APT 安装 | 适用于 Ubuntu/Debian 系统 | apt update && apt install -y nginx | 推荐使用官方源以获取最新稳定版 |
| 源码编译安装 | 可自定义模块、路径、优化参数,灵活性高 | ./configure --prefix=/usr/local/nginx && make && make install | 需提前安装依赖(gcc、pcre、zlib、openssl);过程较复杂 |
| 添加官方源安装 | 获取最新稳定版 Nginx | 添加 nginx.org 的 APT/YUM 源后安装 | 推荐生产环境使用,确保安全更新 |
| 使用 Docker 安装 | 快速部署,环境隔离 | docker run -d -p 80:80 --name nginx nginx | 适合容器化部署,便于测试和 CI/CD |
2.2 目录结构与配置文件位置
| 文件/目录路径 | 用途说明 | 默认位置(包管理器安装) | 注意事项 |
|---|---|---|---|
| nginx.conf | 主配置文件,包含全局、events、http 等核心配置 | /etc/nginx/nginx.conf | 所有配置的入口,建议备份后再修改 |
| sites-available/ | 存放虚拟主机配置文件(可选) | /etc/nginx/sites-available/ | Debian/Ubuntu 特有,通过符号链接启用 |
| sites-enabled/ | 启用的虚拟主机配置(符号链接指向 sites-available) | /etc/nginx/sites-enabled/ | 避免重复包含,提高管理效率 |
| conf.d/ | 存放额外配置文件,通常被主配置 include | /etc/nginx/conf.d/ | 通用目录,可用于模块化配置 |
| html/ | 默认网站根目录 | /usr/share/nginx/html/ | 存放 index.html 等静态文件 |
| logs/ | 日志文件目录 | /var/log/nginx/ | 包含 access.log 和 error.log |
| sbin/nginx | Nginx 可执行文件 | /usr/sbin/nginx | 用于启动、停止、重载服务 |
2.3 启动、停止与重载 Nginx 服务
| 操作命令 | 说明 | 命令示例 | 注意事项 |
|---|---|---|---|
| 启动 Nginx | 启动 Nginx 服务 | nginx 或 systemctl start nginx | 首次启动前需确保配置正确 |
| 停止 Nginx(快速) | 发送 TERM 信号,立即终止所有进程 | nginx -s stop 或 systemctl stop nginx | 不等待现有连接完成,可能导致请求中断 |
| 停止 Nginx(优雅) | 发送 QUIT 信号,等待 Worker 处理完当前请求后退出 | nginx -s quit 或 systemctl stop nginx(优雅) | 推荐用于生产环境,避免服务中断 |
| 重载配置(平滑) | 重新加载配置文件,不中断服务 | nginx -s reload 或 systemctl reload nginx | Master 会启动新 Worker,旧 Worker 处理完请求后自动退出 |
| 重启服务 | 完全停止后再启动 | systemctl restart nginx | 会导致短暂服务中断,非必要不推荐 |
| 查看 Nginx 进程 | 检查 Nginx 是否运行 | ps aux | grep nginx | — |
2.4 验证配置文件语法
| 方法名称 | 说明 | 命令示例 | 注意事项 |
|---|---|---|---|
| nginx -t | 测试配置文件语法正确性,并显示配置文件路径 | nginx -t | 最常用方法,部署前必做 |
| nginx -T | 测试语法并输出完整配置内容 | nginx -T | 用于调试复杂 include 结构,输出可能很长 |
| 检查特定配置文件 | 指定非默认配置文件进行测试 | nginx -t -c /path/to/custom.conf | 适用于多实例或自定义路径部署 |
| 返回值判断 | 命令返回 0 表示成功,非 0 表示有错误 | if nginx -t; then echo "OK"; fi | 可用于脚本自动化部署 |
| 错误定位 | 输出会提示错误行号和原因 | nginx: [emerg] unexpected "}" in /etc/nginx/nginx.conf:15 | 根据提示快速定位并修复 |
第3章 Nginx 配置文件结构
3.1 配置文件整体结构(全局块、events、http、server、location)
| 配置块名称 | 说明 | 嵌套关系与示例 | 注意事项 |
|---|---|---|---|
| 全局块 | 最外层配置,影响 Nginx 整体行为 | worker_processes 1; error_log /var/log/nginx/error.log; | 包含进程数、用户、错误日志路径等指令 |
| events 块 | 定义事件处理模型和连接数限制 | events { worker_connections 1024; } | 通常只出现一次,决定并发处理能力 |
| http 块 | 包含所有 HTTP 相关配置,是 server 块的父块 | http { include mime.types; server { ... } } | 可包含多个 server 块,定义共享的代理、缓存、日志等设置 |
| server 块 | 定义虚拟主机,处理特定域名或 IP 的请求 | server { listen 80; server_name example.com; location / { ... } } | 可在 http 块中定义多个 server 块 |
| location 块 | 定义 URI 路由规则,匹配请求路径并执行相应配置 | location /static/ { root /var/www; } | 嵌套在 server 块内,可有多个,按优先级匹配 |
| upstream 块 | 定义后端服务器组,用于负载均衡 | upstream backend { server 192.168.1.10:8080; server 192.168.1.11:8080; } | 独立于 http 块,但通常定义在 http 块内 |
| if 块 | 条件判断,根据变量值执行不同配置 | if ($http_user_agent ~ Chrome) { rewrite ^ /chrome/ permanent; } | 尽量避免在 location 中滥用 if,可能引发意外行为 |
3.2 配置指令的语法格式
| 指令格式要素 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
| 指令名称 | 表示要执行的操作,如 listen、root、server_name | listen 80; | 必须小写,后跟参数 |
| 参数 | 指令的值或配置项,可为数字、字符串、路径等 | server_name example.com; | 多个参数用空格分隔 |
| 分号 | 每条指令必须以分号结尾 | index index.html index.htm; | 忘记分号会导致语法错误 |
| 块指令 | 以大括号 {} 包围一组指令,如 server、location | server { listen 80; server_name test.com; } | 大括号前后可换行,提高可读性 |
| 注释 | 以 # 开头,用于说明配置 | # This is a comment | 不能出现在行中,只能在行首或行尾 |
| 大小写敏感 | 指令名和参数通常大小写敏感 | root /var/www; 与 ROOT /VAR/WWW; 不同 | 路径和域名参数区分大小写 |
| 指令作用域 | 指令只能在特定上下文中使用 | listen 只能在 server 块中使用 | 超出作用域会报错 |
3.3 包含(include)机制
| 方法名称 | 说明 | 语法与示例 | 注意事项 |
|---|---|---|---|
| include | 将外部配置文件内容嵌入当前位置 | include /etc/nginx/conf.d/*.conf; include mime.types; | 常用于模块化管理配置,避免主文件过大 |
| 文件通配符 | 支持 * 匹配多个文件 | include /etc/nginx/sites-enabled/*.conf; | 按文件名顺序加载,注意命名规范 |
| 相对路径 | 相对于主配置文件路径 | include conf.d/my-site.conf; | 推荐使用绝对路径避免歧义 |
| 绝对路径 | 明确指定完整路径 | include /usr/local/nginx/conf/custom.conf; | 更安全,适合复杂部署 |
| 嵌套 include | 被包含文件中可继续 include 其他文件 | 文件 A include B,B include C | 可实现多层结构,但需警惕循环包含 |
| 错误处理 | 若文件不存在或语法错误,Nginx 启动失败 | nginx: [emerg] open() "/path/to/file.conf" failed | 确保路径正确,权限可读 |
3.4 变量与宏的使用基础
| 变量/宏名称 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
$host | 请求头中的 Host 字段值 | if ($host = example.com) { ... } | 优先使用 $http_host,兼容性更好 |
$request_uri | 完整原始请求 URI(含查询参数) | rewrite ^ /new$uri permanent; | 不解码,保留原始格式 |
$uri | 当前处理的 URI(解码后,不含参数) | location /test { set $uri /new; } | 可被 rewrite 修改 |
$args | 请求中的查询参数字符串 | if ($args ~ 'debug=1') { ... } | 如 a=1&b=2 |
$http_user_agent | 客户端浏览器标识 | if ($http_user_agent ~ Chrome) { ... } | 用于设备或浏览器判断 |
$remote_addr | 客户端 IP 地址 | set real_ip remote_addr; | 在反向代理中可能为代理 IP,需结合 X-Forwarded-For 使用 |
$scheme | 请求协议(http 或 https) | return 301 https://host request_uri; | 用于强制跳转 HTTPS |
$server_name | 当前 server 块匹配的 server_name 值 | access_log /var/log/nginx/$server_name-access.log; | 动态生成日志文件名 |
$request_method | 请求方法(GET、POST 等) | if ($request_method = POST) { ... } | 可用于接口限制 |
| 自定义变量 set | 使用 set 指令定义变量 | set $myvar "hello"; | 变量名以 $ 开头,值可为字符串、其他变量或表达式 |
| title: 负载均衡 Nginx | |||
| description: Nginx 负载均衡配置 | |||
| publishDate: 2026-07-15 | |||
| tags: |
- 负载均衡
- Java
第1章 Nginx 简介与核心概念
1.1 什么是 Nginx
| 概念名称 | 说明 | 注意事项 |
|---|---|---|
| Nginx | 高性能、轻量级的HTTP服务器和反向代理服务器,也可用于IMAP/POP3代理服务 | 读作 “engine x”,最初由 Igor Sysoev 开发,2004年首次发布 |
| 开源软件 | 遵循 BSD 许可证,源代码开放,可自由使用、修改和分发 | 社区活跃,有官方商业版 Nginx Plus 提供额外功能和支持 |
| 设计目标 | 高并发、低内存消耗、高稳定性 | 专为解决C10K问题(1万个并发连接)而设计,适用于高负载场景 |
| 核心功能 | HTTP 服务器、反向代理、负载均衡、静态内容服务、SSL/TLS 支持等 | 不原生支持动态内容处理(如PHP),需配合后端应用服务器(如PHP-FPM)使用 |
1.2 Nginx 的架构与工作原理
| 概念名称 | 说明 | 注意事项 |
|---|---|---|
| 事件驱动架构 | 基于异步非阻塞的事件处理机制,使用 epoll/kqueue 等高效 I/O 多路复用 | 单个进程可处理数万并发连接,资源消耗低 |
| Master-Worker 模型 | Master 进程管理 Worker 进程;Worker 进程处理实际请求 | Master 进程不处理请求,仅负责加载配置、启动 Worker、监控与重启 Worker |
| Master 进程 | 核心管理进程,运行在特权模式,负责读取配置、绑定端口、启动 Worker | 通常以 root 用户运行,避免端口绑定权限问题 |
| Worker 进程 | 实际处理请求的进程,每个 Worker 独立运行,互不干扰 | 数量可配置(worker_processes),建议设为 CPU 核心数 |
| 共享内存 | 多个 Worker 可通过共享内存区域共享数据(如缓存、状态) | 用于实现负载均衡状态共享、限速统计等功能 |
| 配置热加载 | 修改配置后可发送信号使 Master 重新加载配置,无需中断服务 | 使用 nginx -s reload,Master 会启动新 Worker 并优雅关闭旧 Worker |
1.3 Nginx 与 Apache 的对比
| 对比维度 | Nginx | Apache | 注意事项 |
|---|---|---|---|
| 架构模型 | 事件驱动、异步非阻塞 | 进程/线程驱动、同步阻塞(默认) | Nginx 更适合高并发静态资源服务;Apache 在动态内容处理上更成熟 |
| 性能表现 | 高并发下内存占用低,响应速度快 | 高并发时内存消耗较大,性能下降明显 | Nginx 在处理静态文件和反向代理场景下性能优势显著 |
| 配置语法 | 简洁、层级清晰 | 复杂,.htaccess 支持灵活但影响性能 | Nginx 不支持目录级配置文件(如 .htaccess),需集中配置 |
| 模块扩展 | 编译时静态加载或动态加载模块 | 支持运行时动态加载模块(DSO) | Nginx 动态模块需编译支持,灵活性略低 |
| 动态内容支持 | 需配合 FastCGI、uWSGI 等协议 | 原生支持 mod_php、mod_perl 等模块 | Apache 更适合纯 PHP 项目部署;Nginx + PHP-FPM 组合更高效 |
| 社区与生态 | 社区活跃,文档丰富,企业支持(Nginx Plus) | 历史悠久,模块极其丰富,广泛用于传统 Web 项目 | Apache 更适合需要复杂 .htaccess 控制的共享主机环境 |
1.4 Nginx 的应用场景
| 应用场景 | 说明 | 注意事项 |
|---|---|---|
| 静态资源服务器 | 高效提供 HTML、CSS、JS、图片等静态文件 | 配合 gzip 压缩、缓存策略可极大提升性能 |
| 反向代理 | 将客户端请求转发至后端服务器(如 Node.js、Tomcat、Django) | 可隐藏后端真实 IP,实现安全隔离 |
| 负载均衡 | 将请求分发到多个后端服务器,提升可用性与伸缩性 | 支持轮询、IP 哈希、最少连接等策略 |
| HTTPS 终端 | 统一处理 SSL/TLS 加密解密,减轻后端压力 | 可集中管理证书,简化后端部署 |
| API 网关 | 统一入口,实现路由、鉴权、限流、日志等功能 | 常用于微服务架构中 |
| 缓存服务器 | 缓存后端响应内容,减少后端负载 | 支持 proxy_cache 等指令实现页面或片段缓存 |
| 流媒体服务器 | 支持 RTMP 协议,用于视频直播与点播 | 需启用 nginx-rtmp-module 模块 |
| 安全防护 | 防止 DDoS、限制请求频率、防止盗链等 | 结合 limit_req、valid_referers 等指令使用 |
第2章 安装与基础配置
2.1 在 Linux 上安装 Nginx(源码/包管理器)
| 安装方式 | 说明 | 命令示例 | 注意事项 |
|---|---|---|---|
| 使用 YUM 安装 | 适用于 CentOS/RHEL 系统,简单快捷 | yum install -y nginx | 安装版本可能较旧,需配置 EPEL 源 |
| 使用 APT 安装 | 适用于 Ubuntu/Debian 系统 | apt update && apt install -y nginx | 推荐使用官方源以获取最新稳定版 |
| 源码编译安装 | 可自定义模块、路径、优化参数,灵活性高 | ./configure --prefix=/usr/local/nginx && make && make install | 需提前安装依赖(gcc、pcre、zlib、openssl);过程较复杂 |
| 添加官方源安装 | 获取最新稳定版 Nginx | 添加 nginx.org 的 APT/YUM 源后安装 | 推荐生产环境使用,确保安全更新 |
| 使用 Docker 安装 | 快速部署,环境隔离 | docker run -d -p 80:80 --name nginx nginx | 适合容器化部署,便于测试和 CI/CD |
2.2 目录结构与配置文件位置
| 文件/目录路径 | 用途说明 | 默认位置(包管理器安装) | 注意事项 |
|---|---|---|---|
| nginx.conf | 主配置文件,包含全局、events、http 等核心配置 | /etc/nginx/nginx.conf | 所有配置的入口,建议备份后再修改 |
| sites-available/ | 存放虚拟主机配置文件(可选) | /etc/nginx/sites-available/ | Debian/Ubuntu 特有,通过符号链接启用 |
| sites-enabled/ | 启用的虚拟主机配置(符号链接指向 sites-available) | /etc/nginx/sites-enabled/ | 避免重复包含,提高管理效率 |
| conf.d/ | 存放额外配置文件,通常被主配置 include | /etc/nginx/conf.d/ | 通用目录,可用于模块化配置 |
| html/ | 默认网站根目录 | /usr/share/nginx/html/ | 存放 index.html 等静态文件 |
| logs/ | 日志文件目录 | /var/log/nginx/ | 包含 access.log 和 error.log |
| sbin/nginx | Nginx 可执行文件 | /usr/sbin/nginx | 用于启动、停止、重载服务 |
2.3 启动、停止与重载 Nginx 服务
| 操作命令 | 说明 | 命令示例 | 注意事项 |
|---|---|---|---|
| 启动 Nginx | 启动 Nginx 服务 | nginx 或 systemctl start nginx | 首次启动前需确保配置正确 |
| 停止 Nginx(快速) | 发送 TERM 信号,立即终止所有进程 | nginx -s stop 或 systemctl stop nginx | 不等待现有连接完成,可能导致请求中断 |
| 停止 Nginx(优雅) | 发送 QUIT 信号,等待 Worker 处理完当前请求后退出 | nginx -s quit 或 systemctl stop nginx(优雅) | 推荐用于生产环境,避免服务中断 |
| 重载配置(平滑) | 重新加载配置文件,不中断服务 | nginx -s reload 或 systemctl reload nginx | Master 会启动新 Worker,旧 Worker 处理完请求后自动退出 |
| 重启服务 | 完全停止后再启动 | systemctl restart nginx | 会导致短暂服务中断,非必要不推荐 |
| 查看 Nginx 进程 | 检查 Nginx 是否运行 | ps aux | grep nginx | — |
2.4 验证配置文件语法
| 方法名称 | 说明 | 命令示例 | 注意事项 |
|---|---|---|---|
| nginx -t | 测试配置文件语法正确性,并显示配置文件路径 | nginx -t | 最常用方法,部署前必做 |
| nginx -T | 测试语法并输出完整配置内容 | nginx -T | 用于调试复杂 include 结构,输出可能很长 |
| 检查特定配置文件 | 指定非默认配置文件进行测试 | nginx -t -c /path/to/custom.conf | 适用于多实例或自定义路径部署 |
| 返回值判断 | 命令返回 0 表示成功,非 0 表示有错误 | if nginx -t; then echo "OK"; fi | 可用于脚本自动化部署 |
| 错误定位 | 输出会提示错误行号和原因 | nginx: [emerg] unexpected "}" in /etc/nginx/nginx.conf:15 | 根据提示快速定位并修复 |
第3章 Nginx 配置文件结构
3.1 配置文件整体结构(全局块、events、http、server、location)
| 配置块名称 | 说明 | 嵌套关系与示例 | 注意事项 |
|---|---|---|---|
| 全局块 | 最外层配置,影响 Nginx 整体行为 | worker_processes 1; error_log /var/log/nginx/error.log; | 包含进程数、用户、错误日志路径等指令 |
| events 块 | 定义事件处理模型和连接数限制 | events { worker_connections 1024; } | 通常只出现一次,决定并发处理能力 |
| http 块 | 包含所有 HTTP 相关配置,是 server 块的父块 | http { include mime.types; server { ... } } | 可包含多个 server 块,定义共享的代理、缓存、日志等设置 |
| server 块 | 定义虚拟主机,处理特定域名或 IP 的请求 | server { listen 80; server_name example.com; location / { ... } } | 可在 http 块中定义多个 server 块 |
| location 块 | 定义 URI 路由规则,匹配请求路径并执行相应配置 | location /static/ { root /var/www; } | 嵌套在 server 块内,可有多个,按优先级匹配 |
| upstream 块 | 定义后端服务器组,用于负载均衡 | upstream backend { server 192.168.1.10:8080; server 192.168.1.11:8080; } | 独立于 http 块,但通常定义在 http 块内 |
| if 块 | 条件判断,根据变量值执行不同配置 | if ($http_user_agent ~ Chrome) { rewrite ^ /chrome/ permanent; } | 尽量避免在 location 中滥用 if,可能引发意外行为 |
3.2 配置指令的语法格式
| 指令格式要素 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
| 指令名称 | 表示要执行的操作,如 listen、root、server_name | listen 80; | 必须小写,后跟参数 |
| 参数 | 指令的值或配置项,可为数字、字符串、路径等 | server_name example.com; | 多个参数用空格分隔 |
| 分号 | 每条指令必须以分号结尾 | index index.html index.htm; | 忘记分号会导致语法错误 |
| 块指令 | 以大括号 {} 包围一组指令,如 server、location | server { listen 80; server_name test.com; } | 大括号前后可换行,提高可读性 |
| 注释 | 以 # 开头,用于说明配置 | # This is a comment | 不能出现在行中,只能在行首或行尾 |
| 大小写敏感 | 指令名和参数通常大小写敏感 | root /var/www; 与 ROOT /VAR/WWW; 不同 | 路径和域名参数区分大小写 |
| 指令作用域 | 指令只能在特定上下文中使用 | listen 只能在 server 块中使用 | 超出作用域会报错 |
3.3 包含(include)机制
| 方法名称 | 说明 | 语法与示例 | 注意事项 |
|---|---|---|---|
| include | 将外部配置文件内容嵌入当前位置 | include /etc/nginx/conf.d/*.conf; include mime.types; | 常用于模块化管理配置,避免主文件过大 |
| 文件通配符 | 支持 * 匹配多个文件 | include /etc/nginx/sites-enabled/*.conf; | 按文件名顺序加载,注意命名规范 |
| 相对路径 | 相对于主配置文件路径 | include conf.d/my-site.conf; | 推荐使用绝对路径避免歧义 |
| 绝对路径 | 明确指定完整路径 | include /usr/local/nginx/conf/custom.conf; | 更安全,适合复杂部署 |
| 嵌套 include | 被包含文件中可继续 include 其他文件 | 文件 A include B,B include C | 可实现多层结构,但需警惕循环包含 |
| 错误处理 | 若文件不存在或语法错误,Nginx 启动失败 | nginx: [emerg] open() "/path/to/file.conf" failed | 确保路径正确,权限可读 |
3.4 变量与宏的使用基础
| 变量/宏名称 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
$host | 请求头中的 Host 字段值 | if ($host = example.com) { ... } | 优先使用 $http_host,兼容性更好 |
$request_uri | 完整原始请求 URI(含查询参数) | rewrite ^ /new$uri permanent; | 不解码,保留原始格式 |
$uri | 当前处理的 URI(解码后,不含参数) | location /test { set $uri /new; } | 可被 rewrite 修改 |
$args | 请求中的查询参数字符串 | if ($args ~ 'debug=1') { ... } | 如 a=1&b=2 |
$http_user_agent | 客户端浏览器标识 | if ($http_user_agent ~ Chrome) { ... } | 用于设备或浏览器判断 |
$remote_addr | 客户端 IP 地址 | set real_ip remote_addr; | 在反向代理中可能为代理 IP,需结合 X-Forwarded-For 使用 |
$scheme | 请求协议(http 或 https) | return 301 https://host request_uri; | 用于强制跳转 HTTPS |
$server_name | 当前 server 块匹配的 server_name 值 | access_log /var/log/nginx/$server_name-access.log; | 动态生成日志文件名 |
$request_method | 请求方法(GET、POST 等) | if ($request_method = POST) { ... } | 可用于接口限制 |
| 自定义变量 set | 使用 set 指令定义变量 | set $myvar "hello"; | 变量名以 $ 开头,值可为字符串、其他变量或表达式 |
1.1 什么是 Nginx
| 概念名称 | 说明 | 注意事项 |
|---|---|---|
| Nginx | 高性能、轻量级的HTTP服务器和反向代理服务器,也可用于IMAP/POP3代理服务 | 读作 “engine x”,最初由 Igor Sysoev 开发,2004年首次发布 |
| 开源软件 | 遵循 BSD 许可证,源代码开放,可自由使用、修改和分发 | 社区活跃,有官方商业版 Nginx Plus 提供额外功能和支持 |
| 设计目标 | 高并发、低内存消耗、高稳定性 | 专为解决C10K问题(1万个并发连接)而设计,适用于高负载场景 |
| 核心功能 | HTTP 服务器、反向代理、负载均衡、静态内容服务、SSL/TLS 支持等 | 不原生支持动态内容处理(如PHP),需配合后端应用服务器(如PHP-FPM)使用 |
1.2 Nginx 的架构与工作原理
| 概念名称 | 说明 | 注意事项 |
|---|---|---|
| 事件驱动架构 | 基于异步非阻塞的事件处理机制,使用 epoll/kqueue 等高效 I/O 多路复用 | 单个进程可处理数万并发连接,资源消耗低 |
| Master-Worker 模型 | Master 进程管理 Worker 进程;Worker 进程处理实际请求 | Master 进程不处理请求,仅负责加载配置、启动 Worker、监控与重启 Worker |
| Master 进程 | 核心管理进程,运行在特权模式,负责读取配置、绑定端口、启动 Worker | 通常以 root 用户运行,避免端口绑定权限问题 |
| Worker 进程 | 实际处理请求的进程,每个 Worker 独立运行,互不干扰 | 数量可配置(worker_processes),建议设为 CPU 核心数 |
| 共享内存 | 多个 Worker 可通过共享内存区域共享数据(如缓存、状态) | 用于实现负载均衡状态共享、限速统计等功能 |
| 配置热加载 | 修改配置后可发送信号使 Master 重新加载配置,无需中断服务 | 使用 nginx -s reload,Master 会启动新 Worker 并优雅关闭旧 Worker |
1.3 Nginx 与 Apache 的对比
| 对比维度 | Nginx | Apache | 注意事项 |
|---|---|---|---|
| 架构模型 | 事件驱动、异步非阻塞 | 进程/线程驱动、同步阻塞(默认) | Nginx 更适合高并发静态资源服务;Apache 在动态内容处理上更成熟 |
| 性能表现 | 高并发下内存占用低,响应速度快 | 高并发时内存消耗较大,性能下降明显 | Nginx 在处理静态文件和反向代理场景下性能优势显著 |
| 配置语法 | 简洁、层级清晰 | 复杂,.htaccess 支持灵活但影响性能 | Nginx 不支持目录级配置文件(如 .htaccess),需集中配置 |
| 模块扩展 | 编译时静态加载或动态加载模块 | 支持运行时动态加载模块(DSO) | Nginx 动态模块需编译支持,灵活性略低 |
| 动态内容支持 | 需配合 FastCGI、uWSGI 等协议 | 原生支持 mod_php、mod_perl 等模块 | Apache 更适合纯 PHP 项目部署;Nginx + PHP-FPM 组合更高效 |
| 社区与生态 | 社区活跃,文档丰富,企业支持(Nginx Plus) | 历史悠久,模块极其丰富,广泛用于传统 Web 项目 | Apache 更适合需要复杂 .htaccess 控制的共享主机环境 |
1.4 Nginx 的应用场景
| 应用场景 | 说明 | 注意事项 |
|---|---|---|
| 静态资源服务器 | 高效提供 HTML、CSS、JS、图片等静态文件 | 配合 gzip 压缩、缓存策略可极大提升性能 |
| 反向代理 | 将客户端请求转发至后端服务器(如 Node.js、Tomcat、Django) | 可隐藏后端真实 IP,实现安全隔离 |
| 负载均衡 | 将请求分发到多个后端服务器,提升可用性与伸缩性 | 支持轮询、IP 哈希、最少连接等策略 |
| HTTPS 终端 | 统一处理 SSL/TLS 加密解密,减轻后端压力 | 可集中管理证书,简化后端部署 |
| API 网关 | 统一入口,实现路由、鉴权、限流、日志等功能 | 常用于微服务架构中 |
| 缓存服务器 | 缓存后端响应内容,减少后端负载 | 支持 proxy_cache 等指令实现页面或片段缓存 |
| 流媒体服务器 | 支持 RTMP 协议,用于视频直播与点播 | 需启用 nginx-rtmp-module 模块 |
| 安全防护 | 防止 DDoS、限制请求频率、防止盗链等 | 结合 limit_req、valid_referers 等指令使用 |
第2章 安装与基础配置
2.1 在 Linux 上安装 Nginx(源码/包管理器)
| 安装方式 | 说明 | 命令示例 | 注意事项 |
|---|---|---|---|
| 使用 YUM 安装 | 适用于 CentOS/RHEL 系统,简单快捷 | yum install -y nginx | 安装版本可能较旧,需配置 EPEL 源 |
| 使用 APT 安装 | 适用于 Ubuntu/Debian 系统 | apt update && apt install -y nginx | 推荐使用官方源以获取最新稳定版 |
| 源码编译安装 | 可自定义模块、路径、优化参数,灵活性高 | ./configure --prefix=/usr/local/nginx && make && make install | 需提前安装依赖(gcc、pcre、zlib、openssl);过程较复杂 |
| 添加官方源安装 | 获取最新稳定版 Nginx | 添加 nginx.org 的 APT/YUM 源后安装 | 推荐生产环境使用,确保安全更新 |
| 使用 Docker 安装 | 快速部署,环境隔离 | docker run -d -p 80:80 --name nginx nginx | 适合容器化部署,便于测试和 CI/CD |
2.2 目录结构与配置文件位置
| 文件/目录路径 | 用途说明 | 默认位置(包管理器安装) | 注意事项 |
|---|---|---|---|
| nginx.conf | 主配置文件,包含全局、events、http 等核心配置 | /etc/nginx/nginx.conf | 所有配置的入口,建议备份后再修改 |
| sites-available/ | 存放虚拟主机配置文件(可选) | /etc/nginx/sites-available/ | Debian/Ubuntu 特有,通过符号链接启用 |
| sites-enabled/ | 启用的虚拟主机配置(符号链接指向 sites-available) | /etc/nginx/sites-enabled/ | 避免重复包含,提高管理效率 |
| conf.d/ | 存放额外配置文件,通常被主配置 include | /etc/nginx/conf.d/ | 通用目录,可用于模块化配置 |
| html/ | 默认网站根目录 | /usr/share/nginx/html/ | 存放 index.html 等静态文件 |
| logs/ | 日志文件目录 | /var/log/nginx/ | 包含 access.log 和 error.log |
| sbin/nginx | Nginx 可执行文件 | /usr/sbin/nginx | 用于启动、停止、重载服务 |
2.3 启动、停止与重载 Nginx 服务
| 操作命令 | 说明 | 命令示例 | 注意事项 |
|---|---|---|---|
| 启动 Nginx | 启动 Nginx 服务 | nginx 或 systemctl start nginx | 首次启动前需确保配置正确 |
| 停止 Nginx(快速) | 发送 TERM 信号,立即终止所有进程 | nginx -s stop 或 systemctl stop nginx | 不等待现有连接完成,可能导致请求中断 |
| 停止 Nginx(优雅) | 发送 QUIT 信号,等待 Worker 处理完当前请求后退出 | nginx -s quit 或 systemctl stop nginx(优雅) | 推荐用于生产环境,避免服务中断 |
| 重载配置(平滑) | 重新加载配置文件,不中断服务 | nginx -s reload 或 systemctl reload nginx | Master 会启动新 Worker,旧 Worker 处理完请求后自动退出 |
| 重启服务 | 完全停止后再启动 | systemctl restart nginx | 会导致短暂服务中断,非必要不推荐 |
| 查看 Nginx 进程 | 检查 Nginx 是否运行 | ps aux | grep nginx | — |
2.4 验证配置文件语法
| 方法名称 | 说明 | 命令示例 | 注意事项 |
|---|---|---|---|
| nginx -t | 测试配置文件语法正确性,并显示配置文件路径 | nginx -t | 最常用方法,部署前必做 |
| nginx -T | 测试语法并输出完整配置内容 | nginx -T | 用于调试复杂 include 结构,输出可能很长 |
| 检查特定配置文件 | 指定非默认配置文件进行测试 | nginx -t -c /path/to/custom.conf | 适用于多实例或自定义路径部署 |
| 返回值判断 | 命令返回 0 表示成功,非 0 表示有错误 | if nginx -t; then echo "OK"; fi | 可用于脚本自动化部署 |
| 错误定位 | 输出会提示错误行号和原因 | nginx: [emerg] unexpected "}" in /etc/nginx/nginx.conf:15 | 根据提示快速定位并修复 |
第3章 Nginx 配置文件结构
3.1 配置文件整体结构(全局块、events、http、server、location)
| 配置块名称 | 说明 | 嵌套关系与示例 | 注意事项 |
|---|---|---|---|
| 全局块 | 最外层配置,影响 Nginx 整体行为 | worker_processes 1; error_log /var/log/nginx/error.log; | 包含进程数、用户、错误日志路径等指令 |
| events 块 | 定义事件处理模型和连接数限制 | events { worker_connections 1024; } | 通常只出现一次,决定并发处理能力 |
| http 块 | 包含所有 HTTP 相关配置,是 server 块的父块 | http { include mime.types; server { ... } } | 可包含多个 server 块,定义共享的代理、缓存、日志等设置 |
| server 块 | 定义虚拟主机,处理特定域名或 IP 的请求 | server { listen 80; server_name example.com; location / { ... } } | 可在 http 块中定义多个 server 块 |
| location 块 | 定义 URI 路由规则,匹配请求路径并执行相应配置 | location /static/ { root /var/www; } | 嵌套在 server 块内,可有多个,按优先级匹配 |
| upstream 块 | 定义后端服务器组,用于负载均衡 | upstream backend { server 192.168.1.10:8080; server 192.168.1.11:8080; } | 独立于 http 块,但通常定义在 http 块内 |
| if 块 | 条件判断,根据变量值执行不同配置 | if ($http_user_agent ~ Chrome) { rewrite ^ /chrome/ permanent; } | 尽量避免在 location 中滥用 if,可能引发意外行为 |
3.2 配置指令的语法格式
| 指令格式要素 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
| 指令名称 | 表示要执行的操作,如 listen、root、server_name | listen 80; | 必须小写,后跟参数 |
| 参数 | 指令的值或配置项,可为数字、字符串、路径等 | server_name example.com; | 多个参数用空格分隔 |
| 分号 | 每条指令必须以分号结尾 | index index.html index.htm; | 忘记分号会导致语法错误 |
| 块指令 | 以大括号 {} 包围一组指令,如 server、location | server { listen 80; server_name test.com; } | 大括号前后可换行,提高可读性 |
| 注释 | 以 # 开头,用于说明配置 | # This is a comment | 不能出现在行中,只能在行首或行尾 |
| 大小写敏感 | 指令名和参数通常大小写敏感 | root /var/www; 与 ROOT /VAR/WWW; 不同 | 路径和域名参数区分大小写 |
| 指令作用域 | 指令只能在特定上下文中使用 | listen 只能在 server 块中使用 | 超出作用域会报错 |
3.3 包含(include)机制
| 方法名称 | 说明 | 语法与示例 | 注意事项 |
|---|---|---|---|
| include | 将外部配置文件内容嵌入当前位置 | include /etc/nginx/conf.d/*.conf; include mime.types; | 常用于模块化管理配置,避免主文件过大 |
| 文件通配符 | 支持 * 匹配多个文件 | include /etc/nginx/sites-enabled/*.conf; | 按文件名顺序加载,注意命名规范 |
| 相对路径 | 相对于主配置文件路径 | include conf.d/my-site.conf; | 推荐使用绝对路径避免歧义 |
| 绝对路径 | 明确指定完整路径 | include /usr/local/nginx/conf/custom.conf; | 更安全,适合复杂部署 |
| 嵌套 include | 被包含文件中可继续 include 其他文件 | 文件 A include B,B include C | 可实现多层结构,但需警惕循环包含 |
| 错误处理 | 若文件不存在或语法错误,Nginx 启动失败 | nginx: [emerg] open() "/path/to/file.conf" failed | 确保路径正确,权限可读 |
3.4 变量与宏的使用基础
| 变量/宏名称 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
$host | 请求头中的 Host 字段值 | if ($host = example.com) { ... } | 优先使用 $http_host,兼容性更好 |
$request_uri | 完整原始请求 URI(含查询参数) | rewrite ^ /new$uri permanent; | 不解码,保留原始格式 |
$uri | 当前处理的 URI(解码后,不含参数) | location /test { set $uri /new; } | 可被 rewrite 修改 |
$args | 请求中的查询参数字符串 | if ($args ~ 'debug=1') { ... } | 如 a=1&b=2 |
$http_user_agent | 客户端浏览器标识 | if ($http_user_agent ~ Chrome) { ... } | 用于设备或浏览器判断 |
$remote_addr | 客户端 IP 地址 | set real_ip remote_addr; | 在反向代理中可能为代理 IP,需结合 X-Forwarded-For 使用 |
$scheme | 请求协议(http 或 https) | return 301 https://host request_uri; | 用于强制跳转 HTTPS |
$server_name | 当前 server 块匹配的 server_name 值 | access_log /var/log/nginx/$server_name-access.log; | 动态生成日志文件名 |
$request_method | 请求方法(GET、POST 等) | if ($request_method = POST) { ... } | 可用于接口限制 |
| 自定义变量 set | 使用 set 指令定义变量 | set $myvar "hello"; | 变量名以 $ 开头,值可为字符串、其他变量或表达式 |
第4章 HTTP 基础服务配置
4.1 静态资源服务(root 与 alias)
| 指令名称 | 语法 | 用途说明 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| root | root /path/to/root; | 定义根目录,请求 URI 附加到 root 路径后形成完整文件路径 | location /static/ { root /var/www; } # 请求 /static/a.js → /var/www/static/a.js | root 可在 http、server、location 块中使用 |
| alias | alias /path/to/directory; | 为 location 定义别名路径,替换匹配的 URI 部分 | location /files/ { alias /data/uploads/; } # 请求 /files/readme.txt → /data/uploads/readme.txt | alias 只能在 location 块中使用,且 location 不能使用正则时路径需以 / 结尾 |
| index | index file1 file2 ...; | 定义默认索引文件,当请求目录时自动查找 | index index.html index.htm; | 通常与 root 配合使用 |
| try_files | try_files file1 ... uri; | 按顺序检查文件是否存在,存在则返回,否则返回最后一个参数指定的 URI | try_files $uri $uri/ /index.html; | 常用于单页应用(SPA)路由 fallback |
4.2 端口与主机名绑定(listen、server_name)
| 指令名称 | 语法 | 用途说明 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| listen | listen address:port [options]; | 指定 server 块监听的 IP 和端口 | listen 80; listen 192.168.1.1:8080; listen [::]:80; | 可重复出现,支持 IPv4、IPv6、UNIX 套接字 |
| listen (ssl) | listen 443 ssl; | 启用 HTTPS 监听 | listen 443 ssl http2; | 必须配合 ssl_certificate 和 ssl_certificate_key 使用 |
| server_name | server_name name1 name2 ...; | 定义虚拟主机域名,匹配请求的 Host 头 | server_name example.com www.example.com; | 支持通配符(*.example.com)、正则(~^www\d+\.com$) |
| default_server | listen 80 default_server; | 将该 server 设为默认服务器,处理未匹配的请求 | server { listen 80 default_server; return 444; } | 通常用于拒绝非法请求或返回 404 |
| server_name _; | server_name _; | 匹配任意 Host,常用于默认 server | server_name _; | 下划线是常用通配符,也可用其他无效域名 |
4.3 URI 路由匹配(location 指令)
| 匹配模式 | 语法格式 | 用途说明 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 前缀匹配 | location /uri/ { ... } | 匹配以指定前缀开头的 URI | location /static/ { ... } | 最长前缀匹配,多个匹配时取最长 |
| 精确匹配 | location = /uri { ... } | 仅匹配完全相同的 URI | location = /login { ... } | 优先级最高 |
| 正则匹配(区分大小写) | location ~ regex { ... } | 使用正则表达式匹配 URI,区分大小写 | location ~ \.php$ { ... } | ~ 后跟正则,支持 PCRE |
| 正则匹配(不区分大小写) | location ~* regex { ... } | 使用正则表达式匹配 URI,不区分大小写 | `location ~* .(jpg | png)$ { … }` |
| 前缀匹配(禁止正则) | location ^~ /uri { ... } | 前缀匹配且禁止后续正则匹配 | location ^~ /images/ { ... } | 若匹配成功,不再检查正则 location |
| 继承 | — | 内层 location 可继承外层配置 | location / { location ~ \.php$ { ... } } | 内层可覆盖外层指令 |
| 优先级顺序 | — | = > ^~ > ~ 和 ~* > 前缀匹配(最长) | — | 理解优先级对路由控制至关重要 |
4.4 默认页面与错误页面配置(index、error_page)
| 指令名称 | 语法 | 用途说明 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| index | index file1 file2 ...; | 定义目录索引文件,按顺序查找 | index index.html index.php; | 若文件不存在,返回 404 |
| error_page | error_page code ... uri; | 定义错误码的响应页面或跳转地址 | error_page 404 /404.html; error_page 500 502 /50x.html; | 可指定本地 URI 或代理到 upstream |
| error_page (代理) | error_page 404 = @fallback; | 将错误交由 named location 处理 | location @fallback { proxy_pass http://backend; } | 使用 @name 定义命名 location |
| recursive_error_pages | recursive_error_pages on/off; | 是否允许 error_page 递归处理 | recursive_error_pages on; | 默认 off,开启需谨慎 |
| 特殊错误处理 | — | 可自定义 403、404、500 等页面 | error_page 403 /forbidden.html; | 静态错误页建议放在独立 location 保护 |
4.5 日志配置(access_log、error_log)
| 指令名称 | 语法 | 用途说明 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| access_log | access_log path [format] [buffer=size]; | 定义访问日志路径、格式和缓冲区大小 | access_log /var/log/nginx/access.log main; | 可在 http、server、location 块中设置,内层覆盖外层 |
| access_log off | access_log off; | 关闭访问日志 | location /health { access_log off; ... } | 减少 I/O,适合健康检查等高频请求 |
| log_format | log_format name format; | 自定义日志格式 | log_format custom '$remote_addr - $http_user_agent'; | 需在 http 块中定义,供 access_log 引用 |
| error_log | error_log file [level]; | 定义错误日志路径和记录级别 | error_log /var/log/nginx/error.log warn; | 级别:debug、info、notice、warn、error、crit、alert、emerg |
| 内建格式 | — | combined 是默认访问日志格式 | $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" | 可通过变量扩展 |
| 缓冲写入 | access_log /path.log main buffer=16k; | 启用缓冲,减少磁盘 I/O | buffer=size 可提升性能 | 崩溃时可能丢失缓冲日志 |
第5章 反向代理与负载均衡
5.1 反向代理基本配置(proxy_pass)
| 配置项/指令 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
| proxy_pass | 将请求转发到指定的后端服务器或 upstream 组 | location /api/ { proxy_pass http://127.0.0.1:8080; } | URI 处理:若 proxy_pass 无 URI,location 匹配部分会附加到目标地址;若有 URI,则替换匹配部分 |
| URI 处理规则 | 控制请求路径如何传递给后端 | location /app/ { proxy_pass http://backend; } → /app/page → http://backend/app/page | 路径替换需特别注意斜杠 / 的处理,避免多出或缺失 |
| — | — | location /app/ { proxy_pass http://backend/api/; } → /app/page → http://backend/api/page | — |
| 动态 proxy_pass | 使用变量实现动态代理目标 | proxy_pass http://$host:8080; | 需解析 DNS,可能影响性能 |
| named location 转发 | 使用 @ 命名 location 实现内部跳转 | error_page 404 = @fallback; location @fallback { proxy_pass http://backup; } | 用于错误处理或内部重定向 |
5.2 负载均衡策略(round-robin、weight、ip_hash、least_conn)
| 策略名称 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
| round-robin | 默认策略,按顺序轮流分发请求 | upstream backend { server 192.168.1.10; server 192.168.1.11; } | 无需配置,自动轮询 |
| weight | 根据权重分配请求,权重越高,处理请求越多 | server 192.168.1.10 weight=3; server 192.168.1.11 weight=1; | 适用于服务器性能不均的场景 |
| ip_hash | 基于客户端 IP 哈希,确保同一 IP 始终访问同一后端 | upstream backend { ip_hash; server 192.168.1.10; server 192.168.1.11; } | 可实现会话保持,但不适用于大量用户集中访问(如 NAT 环境) |
| least_conn | 将请求分发给当前连接数最少的服务器 | upstream backend { least_conn; server 192.168.1.10; server 192.168.1.11; } | 适合长连接或连接处理时间差异大的场景 |
| hash | 自定义哈希键(如 $request_uri)实现一致性哈希 | hash $request_uri consistent; | 适用于缓存场景,减少后端缓存碎片 |
| least_time | (商业版)选择响应时间最短且活跃连接最少的服务器 | least_time header; | 仅 Nginx Plus 支持 |
5.3 upstream 模块详解
| 配置项/指令 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
| upstream 块 | 定义后端服务器组,用于反向代理和负载均衡 | upstream backend { server 192.168.1.10:8080; server 192.168.1.11:8080; } | 必须在 http 块中定义 |
| server 指令(upstream) | 定义单个后端服务器,可设置权重、最大连接、失败尝试等 | server 192.168.1.10 max_fails=3 fail_timeout=30s; | max_fails 和 fail_timeout 用于健康检查 |
| backup | 标记为备用服务器,仅当主服务器不可用时启用 | server 192.168.1.12 backup; | 用于高可用架构 |
| down | 标记服务器为不可用,不参与负载均衡 | server 192.168.1.13 down; | 用于维护或临时下线 |
| keepalive | 为 upstream 配置长连接池,减少 TCP 握手开销 | upstream backend { keepalive 32; } | 需配合 proxy_http_version 1.1; 和 proxy_set_header Connection ""; 使用 |
| zone | (商业版)将 upstream 定义为共享内存区,支持动态更新 | upstream backend { zone backend 64k; } | 仅 Nginx Plus 支持动态添加/移除后端 |
5.4 代理头部设置(proxy_set_header)
| 头部名称 | 推荐设置 | 作用说明 | 示例 |
|---|---|---|---|
| Host | $host 或 $http_host | 传递原始 Host 头,便于后端识别 | proxy_set_header Host $host; |
| X-Real-IP | $remote_addr | 传递客户端真实 IP 地址 | proxy_set_header X-Real-IP $remote_addr; |
| X-Forwarded-For | $proxy_add_x_forwarded_for | 追加客户端 IP 到请求链,保留代理路径 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
| X-Forwarded-Proto | $scheme | 告知后端原始请求协议(http/https) | proxy_set_header X-Forwarded-Proto $scheme; |
| X-Forwarded-Host | $host | 传递原始 Host,用于生成绝对链接 | proxy_set_header X-Forwarded-Host $host; |
| Connection | ""(空字符串) | 清除 Connection 头,避免传递 close,支持长连接 | proxy_set_header Connection ""; |
| Upgrade / Connection | 用于 WebSocket 代理 | proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; | 必须同时设置 Upgrade 和 Connection 头 |
5.5 连接缓冲与超时控制(proxy_connect_timeout 等)
| 指令名称 | 默认值 | 说明 | 示例 | 注意事项 |
|---|---|---|---|---|
| proxy_connect_timeout | 60s | 与后端服务器建立连接的超时时间 | proxy_connect_timeout 5s; | 应小于客户端超时时间 |
| proxy_send_timeout | 60s | 向后端服务器发送请求的超时时间(两次写操作间) | proxy_send_timeout 10s; | 适用于大请求体或慢速网络 |
| proxy_read_timeout | 60s | 从后端服务器读取响应的超时时间(两次读操作间) | proxy_read_timeout 30s; | 应大于后端应用处理时间 |
| proxy_buffering | on | 是否启用响应缓冲 | proxy_buffering off; | 关闭缓冲适用于流式响应(如视频、大文件下载) |
| proxy_buffer_size | 4k/8k | 存储后端响应头的缓冲区大小 | proxy_buffer_size 16k; | 应足够大以容纳大 Cookie 或头信息 |
| proxy_buffers | 8 4k/8k | 存储后端响应体的缓冲区数量和大小 | proxy_buffers 16 16k; | 根据响应体大小调整 |
| proxy_busy_buffers_size | 8k/16k | 忙碌时可使用的缓冲区大小 | proxy_busy_buffers_size 32k; | 通常为 proxy_buffer_size 的 2-3 倍 |
| proxy_max_temp_file_size | 1024m | 临时文件最大大小(当缓冲区不足时) | proxy_max_temp_file_size 2048m; | 设置为 0 可禁用临时文件 |
第6章 HTTPS 与安全配置
6.1 SSL/TLS 基本概念
| 概念名称 | 说明 | 关联 Nginx 配置 |
|---|---|---|
| SSL/TLS | 安全套接层/传输层安全协议,用于加密 HTTP 通信 | 启用 HTTPS 所必需 |
| 公钥/私钥 | 非对称加密机制,公钥加密,私钥解密 | ssl_certificate 指向证书(含公钥),ssl_certificate_key 指向私钥文件 |
| 数字证书 | 由 CA 签发,包含公钥和域名信息,用于身份验证 | PEM 格式文件,通常由 Let’s Encrypt 等 CA 提供 |
| CA (证书颁发机构) | 权威机构,签发和验证数字证书 | 浏览器内置信任列表,如 DigiCert、Let’s Encrypt |
| 加密套件 (Cipher Suite) | 定义加密算法组合(密钥交换、加密、摘要) | ssl_ciphers 指令配置 |
| 协议版本 | TLS 1.2、TLS 1.3 为当前推荐版本 | ssl_protocols TLSv1.2 TLSv1.3; |
| SNI (服务器名称指示) | 允许一个 IP 托管多个 HTTPS 站点,客户端在握手时发送 Host 名 | Nginx 自动支持,需 server_name 正确配置 |
6.2 配置 HTTPS(listen ssl、ssl_certificate 等)
| 指令名称 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
| listen | 启用 HTTPS 监听 | listen 443 ssl http2; | ssl 和 http2 参数启用 TLS 和 HTTP/2 |
| ssl_certificate | 指定 SSL 证书文件路径 | ssl_certificate /etc/ssl/certs/example.com.crt; | PEM 格式,可包含中间证书 |
| ssl_certificate_key | 指定 SSL 私钥文件路径 | ssl_certificate_key /etc/ssl/private/example.com.key; | 私钥文件应严格保护,权限设为 600 |
| ssl_protocols | 指定支持的 TLS 协议版本 | ssl_protocols TLSv1.2 TLSv1.3; | 禁用 TLS 1.0/1.1 提升安全性 |
| ssl_ciphers | 指定加密套件优先级 | ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:...; | 使用现代强加密套件,优先 ECDHE 密钥交换 |
| ssl_prefer_server_ciphers | 优先使用服务器端定义的加密套件 | ssl_prefer_server_ciphers on; | 防止客户端选择弱加密 |
| ssl_session_cache | 配置 SSL 会话缓存,提升性能 | ssl_session_cache shared:SSL:10m; | shared 缓存在 worker 间共享,提高复用率 |
| ssl_session_timeout | SSL 会话超时时间 | ssl_session_timeout 10m; | 减少重复握手 |
6.3 强制 HTTP 跳转 HTTPS
| 方法 | 配置示例 | 说明 | 注意事项 |
|---|---|---|---|
| return 301 | server { listen 80; server_name example.com; return 301 https://$host$request_uri; } | 简洁高效,推荐方式 | $request_uri 保留完整 URI 和参数 |
| rewrite | server { listen 80; rewrite ^ https://$host$request_uri? permanent; } | 功能等效,但语法稍复杂 | permanent 等价于 301 |
| if 判断 | if ($scheme = http) { return 301 https://$host$request_uri; } | 不推荐,if 在 location 中有陷阱 | 仅在 server 块顶层使用相对安全 |
| HSTS + 跳转 | 结合 6.4 节 HSTS 配置,实现长期安全跳转 | 浏览器首次访问后将自动跳转 | 需确保 HTTPS 配置正确,避免锁死 |
6.4 安全头设置(HSTS、CSP)
| 安全头名称 | 作用说明 | 示例 | 注意事项 |
|---|---|---|---|
| Strict-Transport-Security (HSTS) | 告诉浏览器后续请求必须使用 HTTPS,防止降级攻击 | add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; | max-age 为秒数,includeSubDomains 作用于子域名,always 确保错误页也发送 |
| Content-Security-Policy (CSP) | 控制资源加载来源,防止 XSS 和数据注入 | add_header Content-Security-Policy "default-src 'self'; img-src *; script-src 'self' 'unsafe-inline'"; | 策略复杂,需根据应用调整,建议先用 Content-Security-Policy-Report-Only 测试 |
| X-Frame-Options | 防止点击劫持,控制页面是否可被嵌入 iframe | add_header X-Frame-Options DENY; | DENY 或 SAMEORIGIN |
| X-Content-Type-Options | 阻止浏览器 MIME 类型嗅探,防止类型混淆攻击 | add_header X-Content-Type-Options nosniff; | 始终设置为 nosniff |
| Referrer-Policy | 控制 Referer 头的发送行为,保护隐私 | add_header Referrer-Policy "no-referrer-when-downgrade"; | 可选 strict-origin-when-cross-origin 等更严格策略 |
6.5 防止常见攻击(防止盗链、限制请求速率)
| 防护措施 | 配置示例 | 作用说明 | 注意事项 |
|---|---|---|---|
| 防盗链(Referer 检查) | location ~* \.(jpg|png|gif) { valid_referers none blocked server_names; if ($invalid_referer) { return 403; } } | 防止外部站点盗用媒体资源 | 需配合 valid_referers 指令使用 |
| 限制请求速率 | limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; location /login/ { limit_req zone=one burst=5 nodelay; } | 防止暴力破解、爬虫等高频请求 | zone 定义限速区域,burst 允许突发,nodelay 立即处理突发 |
| 限制连接数 | limit_conn_zone $binary_remote_addr zone=addr:10m; limit_conn addr 5; | 限制单个 IP 的并发连接数 | 适用于下载站、API 接口等 |
| 防止大请求体攻击 | client_max_body_size 1m; | 限制客户端上传文件大小 | 防止占用过多服务器资源 |
| 防止慢速 HTTP 攻击 | client_body_timeout 10s; client_header_timeout 10s; send_timeout 10s; | 限制请求体、头和响应发送的超时时间 | 缩短超时时间可抵御 Slowloris 等攻击 |
| 过滤恶意 User-Agent | if ($http_user_agent ~* "curl wget scanner") { return 403; } | 拦截恶意爬虫和扫描工具 | 可根据实际情况调整匹配规则 |
第7章 高级功能与模块应用
7.1 URL 重写与重定向(rewrite、return)
| 指令/模块 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
| rewrite | 基于正则表达式重写 URL,可选 last、break、redirect、permanent 标志 | rewrite ^/old/(.*)$ /new/$1 permanent; | permanent 为 301 跳转,redirect 为 302;last 继续内部处理,break 终止 |
| return | 直接返回指定状态码或重定向 | return 301 https://$server_name$request_uri; return 200 "OK"; | 简单跳转或响应推荐使用 return,性能优于 rewrite |
| if 指令 | 条件判断,常与 rewrite 或 return 结合使用 | if ($http_user_agent ~ Chrome) { rewrite ^ /chrome/ last; } | if 在 location 中有陷阱,仅用于简单判断,避免复杂逻辑 |
| set | 定义变量,用于 rewrite 或条件判断 | set $mobile "0"; if ($http_user_agent ~* "Mobile") { set $mobile "1"; } | 变量可用于后续 rewrite 或 add_header |
| 正则表达式 | 支持 PCRE,用于匹配 URI、Host、User-Agent 等 | `~* .(jpg | png)$`(不区分大小写匹配图片) |
7.2 访问控制(allow、deny)
| 指令/模块 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
| allow | 允许指定 IP 或网段访问 | allow 192.168.1.0/24; allow 2001:db8::/32;(IPv6) | 按顺序匹配,后出现的规则覆盖前面的 |
| deny | 拒绝指定 IP 或网段访问 | deny 10.0.0.1; deny all;(拒绝所有) | 常用于黑名单或限制访问区域 |
| 规则顺序 | 按配置顺序执行,一旦匹配即生效 | allow 192.168.1.10; deny all; → 仅允许该 IP | 默认策略:最后一条未匹配则拒绝 |
| 应用位置 | 可在 http、server、location 块中使用 | location /admin/ { allow 10.0.0.0/8; deny all; } | 推荐在 location 中限制敏感路径 |
| geo 模块 | 基于 IP 地理位置实现访问控制 | geo $geo { default allow; 1.2.3.4/24 deny; } | 需结合 map 或 if 使用,适合区域封锁 |
7.3 缓存配置(proxy_cache)
| 指令/模块 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
| proxy_cache_path | 定义缓存存储路径、层级、键、内存区域、过期策略等 | proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m max_size=10g inactive=60m; | keys_zone 为共享内存名和大小,inactive 指无访问后清理时间 |
| proxy_cache | 启用缓存并指定使用哪个 keys_zone | proxy_cache one; | 在 location 或 server 中启用 |
| proxy_cache_key | 自定义缓存键,决定哪些请求可复用缓存 | proxy_cache_key $scheme$proxy_host$request_uri; | 可加入 $args 区分参数,避免缓存污染 |
| proxy_cache_valid | 设置不同响应码的缓存时间 | proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; | 精确控制缓存生命周期 |
| proxy_cache_methods | 指定哪些请求方法可被缓存(默认 GET、HEAD) | proxy_cache_methods GET HEAD POST; | POST 通常不缓存,特殊场景需谨慎 |
| add_header X-Cache | 添加响应头显示缓存状态(MISS/HIT/BYPASS) | add_header X-Cache $upstream_cache_status; | 调试缓存命中率的重要工具 |
| proxy_no_cache | 根据条件不缓存响应 | proxy_no_cache $cookie_nocache $arg_nocache; | 用于登录用户或调试模式绕过缓存 |
| proxy_cache_bypass | 根据条件跳过缓存,直接请求后端 | proxy_cache_bypass $http_pragma $http_authorization; | 常用于认证请求或强制刷新 |
7.4 Gzip 压缩(gzip 指令集)
| 指令名称 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
| gzip on; | 启用 Gzip 压缩 | gzip on; | 核心开关 |
| gzip_types | 指定需要压缩的 MIME 类型 | gzip_types text/plain text/css application/json application/javascript; | 默认仅压缩 text/html,需手动添加其他类型 |
| gzip_comp_level | 压缩级别(1-9),1 最快,9 最高压缩比 | gzip_comp_level 6; | 推荐 4-6,平衡性能与压缩率 |
| gzip_min_length | 启用压缩的最小响应体大小 | gzip_min_length 1k; | 避免压缩极小文件(如图标)增加开销 |
| gzip_vary | 添加 Vary: Accept-Encoding 响应头 | gzip_vary on; | 帮助代理和 CDN 正确缓存压缩版本 |
| gzip_buffers | 压缩缓冲区大小和数量 | gzip_buffers 16 8k; | 根据响应大小调整,避免内存不足 |
| gzip_http_version | 指定启用压缩的 HTTP 协议版本 | gzip_http_version 1.1; | 通常为 1.1 |
| gzip_proxied | 控制代理请求的压缩行为(如 expired、no-cache、no-store、private) | gzip_proxied any; | any 表示所有代理响应都可压缩 |
7.5 FastCGI 配置(与 PHP 集成)
| 指令/模块 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
| fastcgi_pass | 指定 PHP-FPM 服务器地址 | fastcgi_pass 127.0.0.1:9000; fastcgi_pass unix:/var/run/php-fpm.sock; | 推荐使用 Unix Socket 提升性能 |
| fastcgi_index | 指定默认 PHP 索引文件 | fastcgi_index index.php; | 与 index 指令配合使用 |
| fastcgi_param | 设置传递给 PHP-FPM 的环境变量 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | SCRIPT_FILENAME 必须正确指向 PHP 文件路径 |
| include fastcgi_params; | 包含标准 FastCGI 参数文件 | include fastcgi_params; | 通常位于 /etc/nginx/fastcgi_params |
| try_files | 安全处理 PHP 请求,防止文件未找到时暴露源码 | try_files $uri =404; | 必须在 fastcgi_pass 前使用 try_files 防止 Nginx 漏洞 |
| fastcgi_read_timeout | 设置从 PHP-FPM 读取响应的超时时间 | fastcgi_read_timeout 300; | 适用于执行时间较长的脚本(如导出、上传) |
| fastcgi_buffering | 是否启用 FastCGI 响应缓冲 | fastcgi_buffering on; | 开启可提升性能,但流式响应需关闭 |
第8章 性能优化与监控
8.1 worker 进程与连接数优化(worker_processes、worker_connections)
| 指令/模块 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
| worker_processes | 设置 worker 进程数,通常设为 CPU 核心数 | worker_processes auto; | auto 自动检测 CPU 核心数 |
| worker_connections | 每个 worker 进程可处理的最大并发连接数 | events { worker_connections 1024; } | 受系统 ulimit -n 限制,总并发 = worker_processes × worker_connections |
| worker_rlimit_nofile | 设置 worker 进程的文件描述符限制 | worker_rlimit_nofile 65535; | 需同步调整系统 ulimit |
| epoll / kqueue | 高效事件驱动模型(Linux 使用 epoll,BSD 使用 kqueue) | use epoll; | 在 events 块中指定,现代系统通常自动选择 |
| multi_accept | 允许一个 worker 接受多个新连接 | multi_accept on; | 可提升吞吐量,但可能增加负载不均 |
8.2 开启高效传输(sendfile、tcp_nopush)
| 指令名称 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
| sendfile on; | 启用零拷贝文件传输,减少用户态/内核态切换 | sendfile on; | 显著提升静态文件传输性能 |
| tcp_nopush on; | 与 sendfile 配合,确保数据包满时再发送(TCP_CORK) | tcp_nopush on; | 减少网络小包,提升吞吐量 |
| tcp_nodelay on; | 禁用 Nagle 算法,立即发送小数据包(TCP_NODELAY) | tcp_nodelay on; | 适用于交互式应用(如 WebSocket),与 tcp_nopush 互斥 |
| open_file_cache | 缓存打开文件的元信息,减少 stat() 系统调用 | open_file_cache max=10000 inactive=20s; | 提升静态资源访问速度 |
| open_file_cache_valid | 缓存项的有效检查周期 | open_file_cache_valid 30s; | 定期验证文件状态 |
| open_file_cache_errors | 是否缓存文件错误信息(如 404) | open_file_cache_errors on; | 避免重复检查不存在的文件 |
8.3 日志切割与分析
| 工具/方法 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
| logrotate | Linux 标准日志轮转工具,按大小或时间切割 | 配置 /etc/logrotate.d/nginx:每日切割、压缩、保留 7 天 | 配合 postrotate 发送 USR1 信号重载日志 |
| USR1 信号 | 通知 Nginx 重新打开日志文件 | kill -USR1 $(cat /var/run/nginx.pid) | 切割后需执行此命令,否则日志仍写入旧文件 |
| access.log 格式定制 | 自定义日志格式以方便分析 | log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"'; | 可添加 $request_time、$upstream_response_time 等性能字段 |
| 日志分析工具 | awk、goaccess、ELK(Elasticsearch, Logstash, Kibana)等 | awk '{print $1}' access.log | sort | uniq -c | sort -nr | 分析访问来源、热门页面、错误请求等 |
| 错误日志级别 | 控制 error.log 的详细程度 | error_log /var/log/nginx/error.log warn; | 生产环境建议 error 或 warn,避免 debug 影响性能 |
8.4 使用 stub_status 模块监控状态
| 配置项/指标 | 说明 | 示例 | 注意事项 |
|---|---|---|---|
| stub_status 指令 | 启用基本状态监控 | location /nginx_status { stub_status; } | 需编译时包含 --with-http_stub_status_module |
| Active connections | 当前活跃连接数 | Active connections: 3 | 包括等待、读写状态的连接 |
| server accepts handled requests | 累计接受、处理的连接数和请求数 | 3 3 10 → 接受 3 连接,处理 3 连接,10 请求 | handled ≤ accepts,差值为丢弃连接 |
| Reading | Nginx 正在读取请求头的连接数 | Reading: 0 | 通常较小 |
| Writing | Nginx 正在向客户端发送响应的连接数 | Writing: 1 | 响应大文件时可能较高 |
| Waiting | 当前空闲但保持打开的 keep-alive 连接数 | Waiting: 2 | Active = Reading + Writing + Waiting |
| 访问控制 | 限制 /nginx_status 仅内网或授权 IP 访问 | location /nginx_status { allow 192.168.0.0/16; deny all; stub_status; } | 防止信息泄露 |
| 集成监控系统 | 结合 Prometheus + nginx-prometheus-exporter 实现高级监控 | exporter 抓取 /metrics 接口 | stub_status 仅提供基础指标,生产推荐使用 exporter |
第9章 实战配置案例
9.1 部署 Vue/React 前端应用
| 配置要点 | 说明与示例 | 注意事项 |
|---|---|---|
| 根目录设置 | 指定前端构建产物(如 dist)的路径 | root /var/www/myapp/dist; |
| 首页处理 | 确保 index.html 被正确返回 | index index.html; |
| SPA 路由支持 | 所有非资源请求均返回 index.html,由前端路由处理 | location / { try_files $uri $uri/ /index.html; } |
| 静态资源缓存 | 为 JS、CSS、图片等设置长期缓存和 Cache-Control | location ~* \.(js|css)$ { expires 1y; add_header Cache-Control "public, immutable"; } |
| Gzip 压缩 | 启用压缩以减小传输体积 | gzip on; gzip_types text/html application/javascript text/css; |
9.2 部署 Spring Boot 后端服务
| 配置要点 | 说明与示例 | 注意事项 |
|---|---|---|
| 反向代理 | 将请求转发到内嵌 Tomcat 的 Spring Boot 应用 | 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; } |
| 超时设置 | 防止长请求被中断 | proxy_connect_timeout 30s; proxy_send_timeout 30s; proxy_read_timeout 30s; |
| 负载均衡 | 多实例部署时使用 upstream | upstream backend { server 127.0.0.1:8080; server 127.0.0.1:8081; } location /api/ { proxy_pass http://backend; } |
| 健康检查 | 结合 max_fails 和 fail_timeout | server 127.0.0.1:8080 max_fails=3 fail_timeout=30s; |
| 安全头 | 添加安全响应头 | add_header X-Content-Type-Options nosniff; add_header X-Frame-Options DENY; |
9.3 多域名虚拟主机配置
| 配置要点 | 说明与示例 | 注意事项 |
|---|---|---|
| 基于域名的 server 块 | 每个域名一个 server,通过 server_name 区分 | server { listen 80; server_name site1.com www.site1.com; root /var/www/site1; index index.html; } server { listen 80; server_name site2.org; root /var/www/site2; } |
| 默认 server | 处理未匹配的请求 | server { listen 80 default_server; return 444; } |
| HTTPS 多域名 | 使用 SNI(Server Name Indication) | server { listen 443 ssl; server_name site1.com; ssl_certificate /path/to/site1.crt; ssl_certificate_key /path/to/site1.key; } |
| 端口复用 | 同一 IP 不同端口 | listen 8080; |
| 重定向 | 统一域名(如 www 到根域) | server { listen 80; server_name www.site1.com; return 301 http://site1.com$request_uri; } |
9.4 前后端分离项目部署
| 配置要点 | 说明与示例 | 注意事项 |
|---|---|---|
| 前端 server 块 | 部署 Vue/React 应用,监听 80 端口 | server { listen 80; server_name frontend.example.com; root /var/www/frontend/dist; location / { try_files $uri $uri/ /index.html; } } |
| 后端 server 块 | 代理 API 请求到 Spring Boot | server { listen 80; server_name frontend.example.com; location /api/ { proxy_pass http://backend-servers; } } |
| 跨域问题 | 若前后端不同域,需配置 CORS | add_header 'Access-Control-Allow-Origin' 'https://frontend.example.com'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; |
| 统一入口 | 单个 server 块处理所有逻辑 | 结合前端和后端配置于同一 server |
9.5 静态资源 CDN 模拟
| 配置要点 | 说明与示例 | 注意事项 |
|---|---|---|
| 专用域名 | 为静态资源设置子域名(如 static.example.com) | server_name static.example.com; |
| 长缓存策略 | 设置 Expires 和 Cache-Control | location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; } |
| Gzip/Brotli | 启用压缩 | gzip on; gzip_types text/css application/javascript image/svg+xml; brotli on; brotli_types text/css application/javascript; |
| ETag / Last-Modified | 启用协商缓存 | 默认开启,可显式配置 etag on; |
| 防盗链 | 防止资源被其他网站盗用 | valid_referers none blocked server_names *.example.com; if ($invalid_referer) { return 403; } |
第10章 故障排查与运维技巧
10.1 常见错误码分析
| 错误码 | 常见原因 | 排查方法 |
|---|---|---|
| 403 Forbidden | 权限不足(Nginx 进程无文件读取权限)、index 文件缺失且 autoindex 未开启、deny 规则阻止访问、SELinux 限制 | 检查文件/目录权限(ls -l)、确认 index 文件存在、检查 allow/deny 配置、临时禁用 SELinux 测试 |
| 404 Not Found | 请求路径在 root 或 alias 下无对应文件、location 匹配错误、静态资源路径配置错误 | 检查 root/alias 路径拼接、使用 curl -v 查看实际请求路径、检查 try_files 逻辑 |
| 502 Bad Gateway | 后端服务(如 PHP-FPM、Spring Boot)未启动或崩溃、proxy_pass 地址错误或端口不通、后端连接超时或拒绝连接 | 检查后端服务状态(systemctl status, netstat)、telnet 测试后端端口连通性、查看 error.log 中连接错误信息 |
| 504 Gateway Timeout | proxy_read_timeout / fastcgi_read_timeout 时间过短、后端处理请求过慢(如复杂 SQL、大文件处理) | 增大超时时间、优化后端代码性能、检查后端日志 |
10.2 日志分析技巧
| 日志类型 | 分析方法与工具 | 关键指标 |
|---|---|---|
| access.log | awk/grep 提取 IP、URL、状态码;goaccess 生成可视化报告;ELK 套件进行集中分析 | 访问量 Top IP/URL、4xx/5xx 错误请求分布、响应时间($request_time) |
| error.log | 按级别(error, crit, alert)过滤、结合时间戳关联 access.log、使用 grep 定位特定错误 | connect() failed (502)、Permission denied (403)、upstream timed out (504) |
| 日志格式优化 | 在 log_format 中添加关键字段 | "$request_time $upstream_response_time $http_user_agent" |
10.3 配置调试方法
| 方法 | 操作 | 用途 |
|---|---|---|
| nginx -t | nginx -t -c /path/to/nginx.conf | 语法检查,确认配置文件无误 |
| nginx -T | nginx -T | 打印完整配置(含包含文件),检查实际生效配置 |
| nginx -s reload | nginx -s reload | 平滑重载配置,不中断服务 |
| 调试日志 | error_log /path/to/debug.log debug; | 开启 debug 级别日志,追踪请求处理流程(生产慎用) |
| echo 模块 | location /test { echo "Hello World"; } | 快速测试 location 匹配或变量值(需编译模块) |
10.4 平滑升级与热部署
| 操作 | 步骤 | 说明 |
|---|---|---|
| 平滑升级 (二进制替换) | 1. 编译新版本 Nginx;2. 备份旧 nginx 二进制文件;3. 替换 /usr/sbin/nginx;4. 发送 kill -USR2 旧主进程;5. 旧主进程发 WINCH 给旧 worker;6. 确认新 worker 运行后,kill -QUIT 旧主进程 | 旧主进程变为 nginx: master process (old binary),实现不中断服务的升级 |
| 配置热重载 | nginx -s reload 或 kill -HUP $(cat /var/run/nginx.pid) | 启动新 worker 进程,优雅关闭旧 worker,连接不中断 |
| 回滚 | 1. 恢复旧版二进制文件;2. 发送 kill -USR2 新主进程;3. 发 WINCH 给新 worker;4. kill -QUIT 新主进程 | 升级失败时快速恢复 |
| 零停机部署 | 结合负载均衡器,逐台升级后端 Nginx 节点 | 适用于集群环境,实现完全无感知升级 |