41. Nginx Web 服务器技术指南
目录
点击展开目录
Nginx 概述 - 什么是 Nginx - 核心特性 - 架构设计 - 与其他 Web 服务器对比
安装与配置 - 安装方式 - 目录结构 - 基础配置 - 服务管理
核心模块 - HTTP 核心模块 - Events 模块 - Mail 模块 - Stream 模块
配置语法 - 配置文件结构 - 指令语法 - 变量系统 - 正则表达式
虚拟主机 - 基于域名的虚拟主机 - 基于 IP 的虚拟主机 - 基于端口的虚拟主机 - SSL 虚拟主机
反向代理 - 代理配置 - 负载均衡 - 健康检查 - 缓存机制
静态文件服务 - 文件服务配置 - 目录浏览 - 文件压缩 - 缓存控制
SSL/TLS 配置 - SSL 证书配置 - 安全参数优化 - HTTP/2 支持 - HSTS 配置
性能优化 - 连接优化 - 缓存优化 - 压缩优化 - 系统调优
安全配置 - 访问控制 - 防护措施 - 日志安全 - 漏洞防护
监控与日志 - 访问日志 - 错误日志 - 状态监控 - 性能分析
高级特性 - Rewrite 规则 - Location 匹配 - 自定义模块 - Lua 脚本
容器化部署 - Docker 部署 - Kubernetes 部署 - 配置管理 - 镜像优化
Nginx 概述
什么是 Nginx
Nginx(发音为"engine-x")是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 服务器。由俄罗斯程序员 Igor Sysoev 开发,以其高性能、稳定性、丰富的功能集、简单的配置和低资源消耗而闻名。
核心价值:
- 高并发处理:支持数万并发连接
- 低内存消耗:事件驱动架构,内存占用极低
- 高可靠性:7x24 小时不间断运行
- 模块化设计:功能模块化,可按需编译
- 配置灵活:简洁而强大的配置语法
主要应用场景:
- Web 服务器:静态文件服务、动态内容代理
- 反向代理:负载均衡、API 网关
- 缓存服务器:内容缓存、CDN 节点
- SSL 终端:HTTPS 加密卸载
核心特性
Nginx 核心特性对比:
| 特性类别 | 具体特性 | 说明 | 优势 |
|---|---|---|---|
| 性能特性 | 事件驱动架构 | 异步非阻塞 I/O | 高并发处理能力 |
| 多进程模型 | Master-Worker 架构 | 稳定性和可扩展性 | |
| 内存池管理 | 高效内存分配 | 低内存消耗 | |
| 功能特性 | HTTP 服务器 | 静态文件服务 | 高效文件传输 |
| 反向代理 | 负载均衡和缓存 | 提升后端性能 | |
| SSL/TLS 支持 | HTTPS 加密 | 安全传输 | |
| 扩展特性 | 模块化架构 | 可插拔模块 | 功能可定制 |
| 第三方模块 | 丰富的扩展 | 生态系统完善 | |
| 脚本支持 | Lua 脚本集成 | 动态逻辑处理 |
架构设计
Nginx 进程架构:
进程职责说明:
| 进程类型 | 数量 | 主要职责 | 特点 |
|---|---|---|---|
| Master Process | 1 | 管理 Worker 进程、读取配置、处理信号 | 不处理请求 |
| Worker Process | N | 处理客户端请求、执行业务逻辑 | 多进程并行 |
| Cache Manager | 1 | 管理缓存元数据、清理过期缓存 | 定期执行 |
| Cache Loader | 1 | 启动时加载缓存索引 | 临时进程 |
事件驱动模型:
与其他 Web 服务器对比
主流 Web 服务器对比:
| 服务器 | 架构模型 | 并发性能 | 内存消耗 | 配置复杂度 | 适用场景 |
|---|---|---|---|---|---|
| Nginx | 事件驱动 | 很高 | 很低 | 中等 | 高并发、反向代理 |
| Apache | 多进程/线程 | 中等 | 高 | 高 | 传统 Web 应用 |
| IIS | 线程池 | 中等 | 中等 | 低 | Windows 环境 |
| Lighttpd | 事件驱动 | 高 | 低 | 中等 | 轻量级应用 |
| Caddy | Go 协程 | 高 | 中等 | 低 | 现代 Web 应用 |
Nginx 优势:
- 高并发处理:单机可处理数万并发连接
- 低资源消耗:内存和 CPU 使用效率极高
- 稳定可靠:久经考验的生产环境稳定性
- 功能丰富:Web 服务器、反向代理、负载均衡一体
- 生态完善:丰富的第三方模块和工具
安装与配置
安装方式
Nginx 支持多种安装方式,适用于不同的环境和需求。
安装方式对比:
| 安装方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 包管理器 | 简单快速、自动依赖 | 版本可能较旧 | 快速部署 |
| 官方仓库 | 版本较新、稳定 | 需要添加仓库 | 生产环境 |
| 源码编译 | 可定制模块、最新版本 | 编译复杂、耗时 | 特殊需求 |
| Docker 容器 | 环境隔离、易部署 | 需要容器知识 | 容器化环境 |
各平台安装命令:
# Ubuntu/Debian - 官方仓库
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
echo "deb https://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
sudo apt update
sudo apt install nginx
# CentOS/RHEL - 官方仓库
sudo yum install epel-release
sudo yum install nginx
# 或使用官方仓库
cat > /etc/yum.repos.d/nginx.repo << 'EOF'
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
EOF
sudo yum install nginx
# macOS - Homebrew
brew install nginx
# 源码编译
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -xzf nginx-1.24.0.tar.gz
cd nginx-1.24.0
./configure --prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_gzip_static_module
make && sudo make install
目录结构
Nginx 标准目录结构:
/etc/nginx/ # 主配置目录
├── nginx.conf # 主配置文件
├── conf.d/ # 配置片段目录
│ └── default.conf # 默认虚拟主机
├── sites-available/ # 可用站点配置
├── sites-enabled/ # 启用站点配置
├── modules-available/ # 可用模块
├── modules-enabled/ # 启用模块
├── snippets/ # 配置片段
│ ├── ssl-params.conf # SSL 参数
│ └── fastcgi-php.conf # FastCGI 配置
└── mime.types # MIME 类型定义
/var/log/nginx/ # 日志目录
├── access.log # 访问日志
└── error.log # 错误日志
/var/www/html/ # 默认网站根目录
└── index.html # 默认首页
/usr/share/nginx/ # Nginx 资源目录
├── html/ # 默认页面
└── modules/ # 动态模块
目录权限设置:
# 设置正确的目录权限
sudo chown -R nginx:nginx /var/www/html
sudo chmod -R 755 /var/www/html
sudo chown -R nginx:nginx /var/log/nginx
sudo chmod -R 640 /var/log/nginx
sudo chown root:root /etc/nginx/nginx.conf
sudo chmod 644 /etc/nginx/nginx.conf
基础配置
nginx.conf 基础配置结构:
# 全局配置
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
# 事件配置
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
# HTTP 配置
http {
# 基础设置
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
# 性能优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# 包含其他配置文件
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
配置参数详解:
| 参数 | 说明 | 推荐值 | 影响 |
|---|---|---|---|
| worker_processes | 工作进程数 | auto 或 CPU 核数 | 并发处理能力 |
| worker_connections | 每进程最大连接数 | 1024-65535 | 并发连接数 |
| keepalive_timeout | 连接保持时间 | 65s | 连接复用效率 |
| client_max_body_size | 请求体最大大小 | 1m-100m | 文件上传限制 |
| sendfile | 零拷贝文件传输 | on | 文件传输性能 |
服务管理
Nginx 服务管理命令:
# 系统服务管理(systemd)
sudo systemctl start nginx # 启动服务
sudo systemctl stop nginx # 停止服务
sudo systemctl restart nginx # 重启服务
sudo systemctl reload nginx # 重新加载配置
sudo systemctl enable nginx # 开机自启
sudo systemctl disable nginx # 禁用自启
sudo systemctl status nginx # 查看状态
# 直接命令管理
sudo nginx # 启动 Nginx
sudo nginx -s reload # 重新加载配置
sudo nginx -s reopen # 重新打开日志文件
sudo nginx -s stop # 快速停止
sudo nginx -s quit # 优雅停止
# 配置测试
sudo nginx -t # 测试配置文件语法
sudo nginx -T # 测试并显示配置内容
sudo nginx -V # 显示版本和编译信息
信号管理:
| 信号 | 作用 | 命令示例 |
|---|---|---|
| TERM, INT | 快速关闭 | kill -TERM $(cat /var/run/nginx.pid) |
| QUIT | 优雅关闭 | kill -QUIT $(cat /var/run/nginx.pid) |
| HUP | 重新加载配置 | kill -HUP $(cat /var/run/nginx.pid) |
| USR1 | 重新打开日志 | kill -USR1 $(cat /var/run/nginx.pid) |
| USR2 | 平滑升级 | kill -USR2 $(cat /var/run/nginx.pid) |
核心模块
HTTP 核心模块
HTTP 核心模块是 Nginx 最重要的模块,提供 Web 服务器的基础功能。
核心指令分类:
| 指令类别 | 主要指令 | 功能 | 配置示例 |
|---|---|---|---|
| 监听配置 | listen | 监听端口和地址 | listen 80; |
| 服务器配置 | server_name | 服务器名称 | server_name example.com; |
| 文档根目录 | root | 网站根目录 | root /var/www/html; |
| 默认文件 | index | 默认索引文件 | index index.html index.php; |
| 错误页面 | error_page | 自定义错误页面 | error_page 404 /404.html; |
HTTP 核心配置示例:
http {
# 客户端配置
client_max_body_size 100m; # 最大请求体大小
client_body_timeout 60s; # 请求体超时
client_header_timeout 60s; # 请求头超时
client_body_buffer_size 128k; # 请求体缓冲区大小
# 连接配置
keepalive_timeout 65; # 保持连接超时
keepalive_requests 100; # 保持连接最大请求数
send_timeout 60s; # 发送超时
# 文件处理
sendfile on; # 启用零拷贝
tcp_nopush on; # 优化数据包发送
tcp_nodelay on; # 禁用 Nagle 算法
# 哈希表配置
server_names_hash_bucket_size 64; # 服务器名称哈希桶大小
types_hash_max_size 2048; # MIME 类型哈希表大小
# 隐藏版本信息
server_tokens off; # 隐藏 Nginx 版本
# 字符集
charset utf-8; # 默认字符集
}
Events 模块
Events 模块配置 Nginx 的事件处理机制。
事件模型对比:
| 事件模型 | 平台 | 性能 | 说明 |
|---|---|---|---|
| epoll | Linux | 很高 | Linux 2.6+ 推荐 |
| kqueue | FreeBSD/macOS | 很高 | BSD 系统推荐 |
| select | 通用 | 低 | 兼容性好,性能差 |
| poll | Unix | 中等 | 比 select 稍好 |
Events 配置示例:
events {
# 事件模型(自动选择最优)
use epoll;
# 工作进程最大连接数
worker_connections 4096;
# 接受多个连接
multi_accept on;
# 接受连接的负载均衡
accept_mutex on;
accept_mutex_delay 500ms;
}
Mail 模块
Mail 模块提供邮件代理功能,支持 IMAP、POP3、SMTP 协议。
Mail 代理配置:
mail {
server_name mail.example.com;
auth_http localhost:9000/cgi-bin/nginxauth.cgi;
proxy_pass_error_message on;
# IMAP 配置
server {
listen 143;
protocol imap;
proxy on;
}
# POP3 配置
server {
listen 110;
protocol pop3;
proxy on;
}
# SMTP 配置
server {
listen 25;
protocol smtp;
proxy on;
smtp_auth login plain;
}
}
Stream 模块
Stream 模块提供 TCP/UDP 负载均衡功能。
Stream 配置示例:
stream {
# 上游服务器组
upstream backend {
server 192.168.1.10:3306 weight=3;
server 192.168.1.11:3306 weight=2;
server 192.168.1.12:3306 backup;
}
# TCP 负载均衡
server {
listen 3306;
proxy_pass backend;
proxy_timeout 1s;
proxy_responses 1;
}
# UDP 负载均衡
upstream dns_servers {
server 8.8.8.8:53;
server 8.8.4.4:53;
}
server {
listen 53 udp;
proxy_pass dns_servers;
proxy_timeout 1s;
proxy_responses 1;
}
}
配置语法
配置文件结构
Nginx 配置文件采用块结构,支持嵌套和继承。
配置块层次结构:
配置块作用域:
| 配置块 | 作用域 | 可包含指令 | 示例 |
|---|---|---|---|
| main | 全局 | 进程、日志、模块加载 | worker_processes auto; |
| events | 事件处理 | 连接处理相关 | worker_connections 1024; |
| http | HTTP 服务 | HTTP 相关指令 | gzip on; |
| server | 虚拟主机 | 服务器相关指令 | listen 80; |
| location | 请求匹配 | 请求处理指令 | proxy_pass http://backend; |
指令语法
Nginx 指令语法规则:
# 基本语法:指令名 参数1 参数2 ... 参数N;
directive_name parameter1 parameter2 ... parameterN;
# 块指令语法
block_directive parameter {
directive1 value1;
directive2 value2;
}
# 示例
server {
listen 80; # 简单指令
server_name example.com www.example.com; # 多参数指令
location / { # 块指令
root /var/www/html;
index index.html;
}
}
指令类型分类:
| 指令类型 | 说明 | 语法特点 | 示例 |
|---|---|---|---|
| 简单指令 | 单行配置 | 以分号结尾 | listen 80; |
| 块指令 | 包含子指令 | 用大括号包围 | server { ... } |
| 数组指令 | 多值配置 | 空格分隔多个值 | server_name a.com b.com; |
变量系统
Nginx 内置变量提供请求和服务器信息。
常用内置变量:
| 变量类别 | 变量名 | 说明 | 示例值 |
|---|---|---|---|
| 请求信息 | $request_uri | 完整请求 URI | /path?query=value |
$uri | 当前 URI | /path | |
$args | 查询参数 | query=value | |
$request_method | 请求方法 | GET | |
| 客户端信息 | $remote_addr | 客户端 IP | 192.168.1.100 |
$remote_user | 认证用户名 | john | |
$http_user_agent | 用户代理 | Mozilla/5.0... | |
| 服务器信息 | $server_name | 服务器名 | example.com |
$server_port | 服务器端口 | 80 | |
$scheme | 协议方案 | http |
自定义变量:
server {
# 设置自定义变量
set $custom_var "hello";
set $api_version "v1";
location / {
# 使用变量
add_header X-Custom-Var $custom_var;
add_header X-API-Version $api_version;
# 变量运算
set $full_path "${uri}?${args}";
add_header X-Full-Path $full_path;
}
}
正则表达式
Nginx 支持 PCRE 正则表达式用于 location 匹配和 rewrite 规则。
正则表达式语法:
| 元字符 | 说明 | 示例 | 匹配 |
|---|---|---|---|
| ^ | 行开始 | ^/api | 以 /api 开始 |
| $ | 行结束 | \.html$ | 以 .html 结束 |
| . | 任意字符 | a.c | abc, a1c, a@c |
| * | 零个或多个 | ab*c | ac, abc, abbc |
| + | 一个或多个 | ab+c | abc, abbc |
| ? | 零个或一个 | ab?c | ac, abc |
| [] | 字符类 | [0-9]+ | 数字 |
| () | 分组捕获 | (.*).html | 捕获文件名 |
正则表达式应用示例:
server {
# location 正则匹配
location ~ ^/api/v[0-9]+/ {
proxy_pass http://api_backend;
}
location ~ \.(jpg|jpeg|png|gif)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# rewrite 正则重写
rewrite ^/old-path/(.*)$ /new-path/$1 permanent;
rewrite ^/product/([0-9]+)$ /product.php?id=$1 last;
# 条件判断
if ($http_user_agent ~* "bot|crawler|spider") {
return 403;
}
}
虚拟主机
基于域名的虚拟主机
基于域名的虚拟主机是最常用的虚拟主机配置方式,通过 server_name 指令区分不同的网站。
虚拟主机配置示例:
# 主站点配置
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html index.php;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
# 子域名配置
server {
listen 80;
server_name blog.example.com;
root /var/www/blog.example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# API 服务配置
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}
server_name 匹配规则:
| 匹配类型 | 语法 | 示例 | 优先级 |
|---|---|---|---|
| 精确匹配 | 完整域名 | example.com | 1(最高) |
| 通配符前缀 | *.domain | *.example.com | 2 |
| 通配符后缀 | domain.* | example.* | 3 |
| 正则表达式 | ~regex | ~^(.+)\.example\.com$ | 4 |
| 默认服务器 | default_server | listen 80 default_server | 5(最低) |
基于 IP 的虚拟主机
基于 IP 的虚拟主机通过不同的 IP 地址区分网站。
# IP 1: 192.168.1.10
server {
listen 192.168.1.10:80;
server_name _;
root /var/www/site1;
location / {
try_files $uri $uri/ =404;
}
}
# IP 2: 192.168.1.11
server {
listen 192.168.1.11:80;
server_name _;
root /var/www/site2;
location / {
try_files $uri $uri/ =404;
}
}
基于端口的虚拟主机
基于端口的虚拟主机通过不同端口区分网站。
# 端口 80 - 主站
server {
listen 80;
server_name example.com;
root /var/www/main;
location / {
try_files $uri $uri/ =404;
}
}
# 端口 8080 - 管理后台
server {
listen 8080;
server_name example.com;
root /var/www/admin;
# 访问控制
allow 192.168.1.0/24;
deny all;
location / {
try_files $uri $uri/ =404;
}
}
# 端口 9000 - API 服务
server {
listen 9000;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:3000;
include proxy_params;
}
}
SSL 虚拟主机
SSL 虚拟主机配置 HTTPS 加密访问。
# HTTP 重定向到 HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
# HTTPS 虚拟主机
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL 证书配置
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# SSL 参数优化
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS 安全头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
root /var/www/example.com;
index index.html index.php;
location / {
try_files $uri $uri/ =404;
}
}
反向代理
代理配置
反向代理是 Nginx 的核心功能之一,用于将客户端请求转发到后端服务器。
基础代理配置:
# 基础反向代理
server {
listen 80;
server_name proxy.example.com;
location / {
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;
# 缓冲设置
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
}
}
代理参数详解:
| 参数 | 说明 | 推荐值 | 作用 |
|---|---|---|---|
| proxy_connect_timeout | 连接超时 | 30s | 建立连接的最大时间 |
| proxy_send_timeout | 发送超时 | 30s | 发送请求的最大时间 |
| proxy_read_timeout | 读取超时 | 30s | 读取响应的最大时间 |
| proxy_buffering | 启用缓冲 | on | 提高代理性能 |
| proxy_buffer_size | 缓冲区大小 | 4k | 响应头缓冲区大小 |
高级代理配置:
server {
listen 80;
server_name api.example.com;
# 定义上游服务器
location / {
proxy_pass http://backend_servers;
# 完整的代理头设置
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_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 错误处理
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_next_upstream_tries 3;
proxy_next_upstream_timeout 30s;
# 响应处理
proxy_intercept_errors on;
proxy_hide_header X-Powered-By;
proxy_hide_header Server;
}
}
负载均衡
Nginx 负载均衡支持多种算法和健康检查。
负载均衡算法对比:
| 算法 | 指令 | 特点 | 适用场景 |
|---|---|---|---|
| 轮询 | 默认 | 依次分发请求 | 服务器性能相近 |
| 加权轮询 | weight | 按权重分发 | 服务器性能不同 |
| IP 哈希 | ip_hash | 基于客户端 IP | 会话保持 |
| 最少连接 | least_conn | 连接数最少优先 | 长连接应用 |
| 哈希 | hash | 自定义哈希键 | 缓存一致性 |
负载均衡配置示例:
# 定义上游服务器组
upstream backend_servers {
# 加权轮询
server 192.168.1.10:8080 weight=3 max_fails=2 fail_timeout=30s;
server 192.168.1.11:8080 weight=2 max_fails=2 fail_timeout=30s;
server 192.168.1.12:8080 weight=1 max_fails=2 fail_timeout=30s;
# 备用服务器
server 192.168.1.13:8080 backup;
# 负载均衡算法
least_conn;
# 会话保持
keepalive 32;
}
# IP 哈希负载均衡
upstream session_backend {
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
# 一致性哈希
upstream cache_backend {
hash $request_uri consistent;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
server {
listen 80;
server_name lb.example.com;
location / {
proxy_pass http://backend_servers;
include proxy_params;
}
location /api/ {
proxy_pass http://session_backend;
include proxy_params;
}
}
健康检查
健康检查确保只将请求转发到健康的后端服务器。
被动健康检查:
upstream backend {
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 max_fails=3 fail_timeout=30s;
}
主动健康检查(需要 nginx-plus 或第三方模块):
upstream backend {
zone backend 64k;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
server {
listen 80;
location / {
proxy_pass http://backend;
health_check interval=5s fails=3 passes=2 uri=/health;
}
}
缓存机制
Nginx 代理缓存提高响应速度和减少后端负载。
缓存配置:
# 缓存路径配置
proxy_cache_path /var/cache/nginx/proxy
levels=1:2
keys_zone=my_cache:10m
max_size=1g
inactive=60m
use_temp_path=off;
server {
listen 80;
server_name cache.example.com;
location / {
proxy_pass http://backend_servers;
# 启用缓存
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
# 缓存键
proxy_cache_key "$scheme$request_method$host$request_uri";
# 缓存控制
proxy_cache_bypass $http_pragma $http_authorization;
proxy_no_cache $http_pragma $http_authorization;
# 缓存头信息
add_header X-Cache-Status $upstream_cache_status;
include proxy_params;
}
# 缓存清理接口
location ~ /purge(/.*) {
allow 127.0.0.1;
deny all;
proxy_cache_purge my_cache "$scheme$request_method$host$1";
}
}
缓存状态说明:
| 状态 | 说明 |
|---|---|
| MISS | 缓存未命中,从后端获取 |
| HIT | 缓存命中,直接返回缓存内容 |
| STALE | 缓存过期,但仍然返回旧内容 |
| UPDATING | 缓存正在更新 |
| REVALIDATED | 缓存重新验证 |
| BYPASS | 缓存被绕过 |
静态文件服务
文件服务配置
Nginx 静态文件服务是其最基础也是最高效的功能。
基础静态文件配置:
server {
listen 80;
server_name static.example.com;
root /var/www/static;
index index.html index.htm;
# 静态文件处理
location / {
try_files $uri $uri/ =404;
# 安全设置
location ~ /\. {
deny all;
}
}
# 图片文件优化
location ~* \.(jpg|jpeg|png|gif|ico|svg)$ {
expires 30d;
add_header Cache-Control "public, immutable";
add_header Vary Accept-Encoding;
# 防盗链
valid_referers none blocked server_names *.example.com;
if ($invalid_referer) {
return 403;
}
}
# CSS/JS 文件优化
location ~* \.(css|js)$ {
expires 7d;
add_header Cache-Control "public";
gzip_static on;
}
# 字体文件
location ~* \.(woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Access-Control-Allow-Origin "*";
}
}
文件类型处理:
| 文件类型 | 缓存时间 | 特殊处理 | 说明 |
|---|---|---|---|
| HTML | 不缓存或短时间 | no-cache | 内容可能频繁更新 |
| CSS/JS | 7-30天 | Gzip 压缩 | 版本化管理 |
| 图片 | 30天-1年 | 防盗链 | 不经常变更 |
| 字体 | 1年 | CORS 头 | 跨域使用 |
| 视频 | 长期缓存 | 范围请求 | 大文件处理 |
目录浏览
目录浏览功能允许用户浏览服务器目录结构。
server {
listen 80;
server_name files.example.com;
root /var/www/files;
location / {
# 启用目录浏览
autoindex on;
autoindex_exact_size off; # 显示文件大小(KB/MB)
autoindex_localtime on; # 显示本地时间
autoindex_format html; # 输出格式:html/xml/json/jsonp
# 自定义目录页面
add_header Content-Type "text/html; charset=utf-8";
# 访问控制
allow 192.168.1.0/24;
deny all;
}
# 隐藏特定文件
location ~ /\.(htaccess|htpasswd|git) {
deny all;
}
}
文件压缩
Gzip 压缩减少传输数据量,提高加载速度。
http {
# Gzip 基础配置
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_proxied any;
# 压缩文件类型
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/xml+rss
application/json
application/xml
image/svg+xml;
# 静态压缩文件
gzip_static on;
# Brotli 压缩(需要模块支持)
brotli on;
brotli_comp_level 6;
brotli_types
text/plain
text/css
application/json
application/javascript
text/xml
application/xml
application/xml+rss
text/javascript;
}
server {
listen 80;
server_name compress.example.com;
root /var/www/html;
location / {
# 预压缩文件检查顺序
try_files $uri $uri.br $uri.gz $uri/ =404;
}
}
压缩效果对比:
| 文件类型 | 原始大小 | Gzip 压缩 | Brotli 压缩 | 压缩率 |
|---|---|---|---|---|
| HTML | 100KB | 25KB | 22KB | 75-78% |
| CSS | 50KB | 12KB | 10KB | 76-80% |
| JavaScript | 200KB | 60KB | 55KB | 70-72% |
| JSON | 80KB | 15KB | 13KB | 81-84% |
缓存控制
HTTP 缓存控制优化客户端缓存策略。
server {
listen 80;
server_name cdn.example.com;
root /var/www/cdn;
# 不缓存的文件
location ~* \.(html|htm)$ {
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";
}
# 短期缓存
location ~* \.(css|js)$ {
expires 7d;
add_header Cache-Control "public, max-age=604800";
# ETag 支持
etag on;
# 条件请求处理
if_modified_since exact;
}
# 长期缓存
location ~* \.(jpg|jpeg|png|gif|ico|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
# 版本化文件永不过期
location ~* \.(jpg|jpeg|png|gif|ico|woff|woff2)\?v=[0-9]+ {
expires max;
add_header Cache-Control "public, max-age=31536000, immutable";
}
}
# API 响应缓存
location /api/ {
proxy_pass http://api_backend;
# 根据响应头设置缓存
proxy_cache_valid 200 5m;
proxy_cache_valid 404 1m;
proxy_cache_valid any 1m;
# 缓存键包含查询参数
proxy_cache_key "$scheme$request_method$host$request_uri";
}
}
缓存策略最佳实践:
| 资源类型 | 缓存策略 | 更新机制 | 实现方式 |
|---|---|---|---|
| HTML 页面 | 不缓存或短缓存 | 实时更新 | no-cache |
| CSS/JS | 中期缓存 | 版本号更新 | max-age=604800 |
| 图片资源 | 长期缓存 | 文件名变更 | max-age=31536000 |
| API 数据 | 短期缓存 | TTL 过期 | max-age=300 |
SSL/TLS 配置
SSL 证书配置
SSL/TLS 配置为网站提供 HTTPS 加密传输。
基础 SSL 配置:
server {
listen 443 ssl http2;
server_name secure.example.com;
# SSL 证书文件
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# 中间证书链(如果有)
ssl_trusted_certificate /etc/ssl/certs/example.com.chain.crt;
# 基础 SSL 参数
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
# 会话缓存
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
# OCSP 装订
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
root /var/www/secure;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# HTTP 重定向到 HTTPS
server {
listen 80;
server_name secure.example.com;
return 301 https://$server_name$request_uri;
}
证书类型对比:
| 证书类型 | 验证级别 | 适用场景 | 价格 | 申请时间 |
|---|---|---|---|---|
| DV | 域名验证 | 个人网站、博客 | 免费-低 | 几分钟 |
| OV | 组织验证 | 企业网站 | 中等 | 1-3天 |
| EV | 扩展验证 | 电商、银行 | 高 | 1-2周 |
| 通配符 | 域名验证 | 多子域名 | 中等-高 | 几分钟-几天 |
安全参数优化
SSL 安全参数优化提高 HTTPS 安全性。
# SSL 配置文件 /etc/nginx/snippets/ssl-params.conf
ssl_protocols TLSv1.2 TLSv1.3;
# 现代浏览器兼容的密码套件
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
# 服务器密码套件优先
ssl_prefer_server_ciphers off;
# DH 参数(用于 DHE 密码套件)
ssl_dhparam /etc/ssl/certs/dhparam.pem;
# 会话缓存优化
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# OCSP 装订
ssl_stapling on;
ssl_stapling_verify on;
# 安全头
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 使用配置
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
include /etc/nginx/snippets/ssl-params.conf;
# 网站内容...
}
生成 DH 参数:
# 生成强 DH 参数(需要较长时间)
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
# 或使用 4096 位(更安全但更慢)
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
HTTP/2 支持
HTTP/2 配置提升网站性能。
server {
listen 443 ssl http2;
server_name h2.example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
include /etc/nginx/snippets/ssl-params.conf;
root /var/www/h2;
index index.html;
# HTTP/2 服务器推送
location / {
try_files $uri $uri/ =404;
# 推送关键资源
location = /index.html {
http2_push /css/style.css;
http2_push /js/app.js;
http2_push https://imgcdn.dpdns.org/images/logo.png;
}
}
# 静态资源优化
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
# 预加载提示
add_header Link "</css/style.css>; rel=preload; as=style" always;
add_header Link "</js/app.js>; rel=preload; as=script" always;
}
}
HTTP/2 优势:
| 特性 | HTTP/1.1 | HTTP/2 | 改进 |
|---|---|---|---|
| 多路复用 | 串行请求 | 并行请求 | 减少延迟 |
| 头部压缩 | 无压缩 | HPACK 压缩 | 减少带宽 |
| 服务器推送 | 不支持 | 支持 | 主动推送资源 |
| 二进制协议 | 文本协议 | 二进制协议 | 解析效率高 |
HSTS 配置
HTTP Strict Transport Security 强制使用 HTTPS。
server {
listen 443 ssl http2;
server_name secure.example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
include /etc/nginx/snippets/ssl-params.conf;
# HSTS 配置
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# 其他安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# CSP 内容安全策略
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https:; connect-src 'self'; frame-ancestors 'none';" always;
root /var/www/secure;
location / {
try_files $uri $uri/ =404;
}
}
# 处理 HTTP 请求
server {
listen 80;
server_name secure.example.com;
# 永久重定向到 HTTPS
return 301 https://$server_name$request_uri;
}
HSTS 参数说明:
| 参数 | 说明 | 推荐值 |
|---|---|---|
| max-age | HSTS 有效期(秒) | 31536000(1年) |
| includeSubDomains | 包含子域名 | 建议启用 |
| preload | 预加载列表 | 可选启用 |
性能优化
连接优化
连接优化提高 Nginx 的并发处理能力和响应速度。
连接参数优化:
# 全局配置优化
user nginx;
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;
events {
# 事件模型优化
use epoll;
worker_connections 4096;
multi_accept on;
accept_mutex off;
}
http {
# 连接优化
keepalive_timeout 65;
keepalive_requests 1000;
send_timeout 30;
client_header_timeout 30;
client_body_timeout 30;
# 缓冲区优化
client_header_buffer_size 4k;
large_client_header_buffers 4 16k;
client_body_buffer_size 128k;
client_max_body_size 100m;
# 文件传输优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# 哈希表优化
server_names_hash_bucket_size 128;
server_names_hash_max_size 2048;
types_hash_max_size 2048;
variables_hash_max_size 2048;
}
性能参数调优表:
| 参数 | 默认值 | 推荐值 | 说明 |
|---|---|---|---|
| worker_processes | 1 | auto | CPU 核数 |
| worker_connections | 1024 | 4096-8192 | 每进程连接数 |
| keepalive_timeout | 75s | 65s | 连接保持时间 |
| keepalive_requests | 100 | 1000 | 连接最大请求数 |
| client_max_body_size | 1m | 根据需求 | 请求体大小限制 |
缓存优化
多层缓存策略提升网站性能。
# 代理缓存配置
proxy_cache_path /var/cache/nginx/proxy
levels=1:2
keys_zone=proxy_cache:100m
max_size=10g
inactive=60m
use_temp_path=off;
# FastCGI 缓存配置
fastcgi_cache_path /var/cache/nginx/fastcgi
levels=1:2
keys_zone=fastcgi_cache:100m
max_size=5g
inactive=60m
use_temp_path=off;
server {
listen 80;
server_name cache.example.com;
root /var/www/html;
# 静态文件缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Vary Accept-Encoding;
# 浏览器缓存
etag on;
if_modified_since exact;
}
# 动态内容缓存
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_cache fastcgi_cache;
fastcgi_cache_valid 200 301 302 1h;
fastcgi_cache_valid 404 10m;
fastcgi_cache_valid any 1m;
# 缓存键
fastcgi_cache_key "$scheme$request_method$host$request_uri";
# 缓存绕过条件
fastcgi_cache_bypass $http_pragma $http_authorization $cookie_nocache $arg_nocache;
fastcgi_no_cache $http_pragma $http_authorization $cookie_nocache $arg_nocache;
# 缓存状态头
add_header X-Cache-Status $upstream_cache_status;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# API 代理缓存
location /api/ {
proxy_pass http://api_backend;
proxy_cache proxy_cache;
proxy_cache_valid 200 5m;
proxy_cache_valid 404 1m;
# 智能缓存更新
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
include proxy_params;
}
}
缓存层次架构:
压缩优化
压缩优化减少传输数据量。
http {
# Gzip 压缩优化
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_proxied any;
gzip_buffers 16 8k;
gzip_http_version 1.1;
# 压缩文件类型
gzip_types
text/plain
text/css
text/xml
text/javascript
text/csv
application/javascript
application/json
application/xml
application/xml+rss
application/atom+xml
image/svg+xml
font/truetype
font/opentype
application/font-woff
application/font-woff2;
# Brotli 压缩(需要模块)
brotli on;
brotli_comp_level 6;
brotli_min_length 1024;
brotli_types
text/plain
text/css
application/json
application/javascript
text/xml
application/xml
application/xml+rss
text/javascript
image/svg+xml;
# 预压缩文件支持
gzip_static on;
brotli_static on;
}
server {
listen 80;
server_name compress.example.com;
root /var/www/html;
location / {
# 检查预压缩文件
try_files $uri $uri.br $uri.gz $uri/ =404;
}
# 实时压缩 API 响应
location /api/ {
proxy_pass http://api_backend;
# 强制压缩
gzip_proxied any;
gzip_min_length 1;
include proxy_params;
}
}
系统调优
系统级优化提升整体性能。
内核参数优化:
# /etc/sysctl.conf
# 网络优化
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_max_tw_buckets = 6000
# 文件描述符限制
fs.file-max = 2097152
# 应用生效
sudo sysctl -p
Nginx 进程限制:
# /etc/security/limits.conf
nginx soft nofile 65535
nginx hard nofile 65535
# 或在 systemd 服务文件中
# /etc/systemd/system/nginx.service.d/limits.conf
[Service]
LimitNOFILE=65535
性能监控脚本:
#!/bin/bash
# nginx-performance.sh
echo "=== Nginx 性能监控 ==="
# 连接统计
echo "当前连接数:"
ss -tuln | grep :80 | wc -l
# 进程状态
echo -e "\nNginx 进程状态:"
ps aux | grep nginx | grep -v grep
# 内存使用
echo -e "\n内存使用情况:"
free -h
# 负载情况
echo -e "\n系统负载:"
uptime
# 网络连接状态
echo -e "\n网络连接状态:"
ss -s
# 磁盘 I/O
echo -e "\n磁盘 I/O:"
iostat -x 1 1 | grep -E "(Device|sda|nvme)"
安全配置
访问控制
访问控制限制特定 IP 或网络的访问。
# IP 访问控制
server {
listen 80;
server_name admin.example.com;
# 允许特定 IP
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
# 基于地理位置的访问控制(需要 GeoIP 模块)
if ($geoip_country_code != CN) {
return 403;
}
location / {
root /var/www/admin;
index index.html;
}
# 敏感目录保护
location /admin/ {
allow 192.168.1.100;
deny all;
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
# 基于用户代理的访问控制
server {
listen 80;
server_name api.example.com;
# 阻止恶意爬虫
if ($http_user_agent ~* (bot|crawler|spider|scraper)) {
return 403;
}
# 阻止空用户代理
if ($http_user_agent = "") {
return 403;
}
location / {
proxy_pass http://api_backend;
include proxy_params;
}
}
HTTP 基础认证:
# 创建密码文件
sudo htpasswd -c /etc/nginx/.htpasswd admin
sudo htpasswd /etc/nginx/.htpasswd user1
# 设置权限
sudo chown root:nginx /etc/nginx/.htpasswd
sudo chmod 640 /etc/nginx/.htpasswd
防护措施
安全防护措施防范常见攻击。
# 安全配置文件 /etc/nginx/snippets/security.conf
# 隐藏 Nginx 版本
server_tokens off;
# 限制请求方法
if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|OPTIONS)$) {
return 405;
}
# 防止点击劫持
add_header X-Frame-Options "SAMEORIGIN" always;
# 防止 MIME 类型嗅探
add_header X-Content-Type-Options "nosniff" always;
# XSS 保护
add_header X-XSS-Protection "1; mode=block" always;
# 引用策略
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 权限策略
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
server {
listen 80;
server_name secure.example.com;
include /etc/nginx/snippets/security.conf;
# 请求大小限制
client_max_body_size 10m;
client_body_buffer_size 128k;
# 请求频率限制
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
# 连接数限制
limit_conn_zone $binary_remote_addr zone=conn:10m;
limit_conn conn 10;
location /login {
limit_req zone=login burst=3 nodelay;
proxy_pass http://auth_backend;
include proxy_params;
}
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://api_backend;
include proxy_params;
}
# 阻止访问敏感文件
location ~ /\.(ht|git|svn) {
deny all;
}
location ~ \.(sql|bak|backup|log)$ {
deny all;
}
}
DDoS 防护配置:
# DDoS 防护
http {
# 连接限制
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
# 请求限制
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=5r/s;
server {
listen 80;
server_name protected.example.com;
# 应用限制
limit_conn perip 10;
limit_conn perserver 100;
limit_req zone=req_limit_per_ip burst=10 nodelay;
# 慢速攻击防护
client_body_timeout 10s;
client_header_timeout 10s;
send_timeout 10s;
location / {
# 检查请求频率
if ($request_time > 10) {
return 444;
}
proxy_pass http://backend;
include proxy_params;
}
}
}
日志安全
安全日志配置记录和分析安全事件。
http {
# 安全日志格式
log_format security '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time '
'$geoip_country_code';
# 访问日志
access_log /var/log/nginx/access.log main;
access_log /var/log/nginx/security.log security;
# 错误日志
error_log /var/log/nginx/error.log warn;
server {
listen 80;
server_name log.example.com;
# 记录可疑请求
location / {
# 记录长 URI
if ($request_uri ~ ".{255,}") {
access_log /var/log/nginx/suspicious.log security;
}
# 记录 SQL 注入尝试
if ($args ~ "(union|select|insert|delete|update|drop|create|alter)") {
access_log /var/log/nginx/sqli.log security;
return 403;
}
# 记录 XSS 尝试
if ($args ~ "(<script|javascript:|vbscript:|onload=|onerror=)") {
access_log /var/log/nginx/xss.log security;
return 403;
}
proxy_pass http://backend;
include proxy_params;
}
}
}
日志分析脚本:
#!/bin/bash
# security-analysis.sh
LOG_FILE="/var/log/nginx/access.log"
DATE=$(date +%Y-%m-%d)
echo "=== Nginx 安全日志分析 ($DATE) ==="
# 统计访问最多的 IP
echo "访问最多的 IP:"
awk '{print $1}' $LOG_FILE | sort | uniq -c | sort -nr | head -10
# 统计 404 错误
echo -e "\n404 错误统计:"
awk '$9==404 {print $7}' $LOG_FILE | sort | uniq -c | sort -nr | head -10
# 统计可疑的 User-Agent
echo -e "\n可疑 User-Agent:"
awk -F'"' '$6 ~ /(bot|crawler|scanner|exploit)/ {print $6}' $LOG_FILE | sort | uniq -c | sort -nr
# 统计大文件请求
echo -e "\n大文件请求(>10MB):"
awk '$10>10485760 {print $1, $7, $10}' $LOG_FILE | sort -k3 -nr | head -10
# 统计慢请求
echo -e "\n慢请求(>5秒):"
awk '$NF>5 {print $1, $7, $NF}' $LOG_FILE | sort -k3 -nr | head -10
漏洞防护
常见漏洞防护配置。
server {
listen 80;
server_name secure.example.com;
# 防止路径遍历
location ~ \.\./ {
return 403;
}
# 防止 NULL 字节攻击
location ~ \x00 {
return 403;
}
# 防止 HTTP 请求走私
if ($http_transfer_encoding ~* chunked) {
return 400;
}
# 防止 HTTP 头注入
if ($http_host !~ ^[a-zA-Z0-9.-]+$) {
return 400;
}
# 防止大 Cookie 攻击
if ($http_cookie ~ ".{4096,}") {
return 400;
}
# 文件上传安全
location /upload {
client_max_body_size 50m;
# 限制文件类型
if ($request_filename ~* \.(php|jsp|asp|sh|py|pl)$) {
return 403;
}
proxy_pass http://upload_backend;
include proxy_params;
}
# API 安全
location /api/ {
# 验证 Content-Type
if ($content_type !~ "^application/(json|x-www-form-urlencoded)") {
return 415;
}
# CORS 安全配置
add_header Access-Control-Allow-Origin "https://trusted-domain.com" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
add_header Access-Control-Max-Age "86400" always;
proxy_pass http://api_backend;
include proxy_params;
}
}
监控与日志
访问日志
访问日志记录所有 HTTP 请求信息。
自定义日志格式:
http {
# 标准日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 详细日志格式
log_format detailed '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
# JSON 格式日志
log_format json escape=json '{'
'"timestamp":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"request":"$request",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"request_time":$request_time,'
'"upstream_response_time":"$upstream_response_time"'
'}';
# 性能分析格式
log_format performance '$remote_addr [$time_local] "$request" '
'$status $body_bytes_sent '
'rt=$request_time '
'uct=$upstream_connect_time '
'uht=$upstream_header_time '
'urt=$upstream_response_time';
server {
listen 80;
server_name monitor.example.com;
# 多种日志记录
access_log /var/log/nginx/access.log main;
access_log /var/log/nginx/performance.log performance;
access_log /var/log/nginx/json.log json;
# 条件日志记录
map $status $log_4xx_5xx {
~^[45] 1;
default 0;
}
access_log /var/log/nginx/errors.log main if=$log_4xx_5xx;
location / {
proxy_pass http://backend;
include proxy_params;
}
}
}
错误日志
错误日志记录服务器错误和调试信息。
# 全局错误日志
error_log /var/log/nginx/error.log warn;
# 调试日志(仅在需要时启用)
error_log /var/log/nginx/debug.log debug;
server {
listen 80;
server_name debug.example.com;
# 服务器级错误日志
error_log /var/log/nginx/debug.example.com.error.log info;
location / {
# 位置级错误日志
error_log /var/log/nginx/location.error.log debug;
proxy_pass http://backend;
include proxy_params;
}
}
错误日志级别:
| 级别 | 说明 | 记录内容 | 适用场景 |
|---|---|---|---|
| debug | 调试信息 | 详细的调试信息 | 开发调试 |
| info | 信息 | 一般信息 | 详细监控 |
| notice | 通知 | 重要信息 | 正常监控 |
| warn | 警告 | 警告信息 | 生产环境 |
| error | 错误 | 错误信息 | 最小日志 |
| crit | 严重 | 严重错误 | 紧急情况 |
状态监控
Nginx 状态监控提供实时性能指标。
# 启用状态模块
server {
listen 80;
server_name status.example.com;
# 基础状态页面
location /nginx_status {
stub_status on;
access_log off;
# 访问控制
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}
# 详细状态信息(需要第三方模块)
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
access_log off;
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}
# Prometheus 指标
location /metrics {
prometheus;
access_log off;
allow 127.0.0.1;
deny all;
}
}
状态监控脚本:
#!/bin/bash
# nginx-status.sh
STATUS_URL="http://localhost/nginx_status"
# 获取状态信息
STATUS=$(curl -s $STATUS_URL)
if [ $? -eq 0 ]; then
echo "=== Nginx 状态监控 ==="
echo "$STATUS"
# 解析状态信息
ACTIVE=$(echo "$STATUS" | grep "Active connections" | awk '{print $3}')
ACCEPTS=$(echo "$STATUS" | grep "server accepts" | awk '{print $1}')
HANDLED=$(echo "$STATUS" | grep "server accepts" | awk '{print $2}')
REQUESTS=$(echo "$STATUS" | grep "server accepts" | awk '{print $3}')
READING=$(echo "$STATUS" | grep "Reading" | awk '{print $2}')
WRITING=$(echo "$STATUS" | grep "Reading" | awk '{print $4}')
WAITING=$(echo "$STATUS" | grep "Reading" | awk '{print $6}')
echo -e "\n=== 解析结果 ==="
echo "活跃连接数: $ACTIVE"
echo "总接受连接: $ACCEPTS"
echo "总处理连接: $HANDLED"
echo "总请求数: $REQUESTS"
echo "正在读取: $READING"
echo "正在写入: $WRITING"
echo "等待连接: $WAITING"
# 计算连接处理率
if [ "$ACCEPTS" -gt 0 ]; then
HANDLE_RATE=$(echo "scale=2; $HANDLED * 100 / $ACCEPTS" | bc)
echo "连接处理率: ${HANDLE_RATE}%"
fi
else
echo "无法获取 Nginx 状态信息"
exit 1
fi
性能分析
性能分析工具帮助优化 Nginx 配置。
日志分析脚本:
#!/bin/bash
# nginx-performance-analysis.sh
LOG_FILE="/var/log/nginx/performance.log"
TEMP_DIR="/tmp/nginx_analysis"
mkdir -p $TEMP_DIR
echo "=== Nginx 性能分析报告 ==="
# 响应时间分析
echo "1. 响应时间分析:"
awk '{
if ($NF > 5) slow++;
else if ($NF > 1) medium++;
else fast++;
total++;
sum += $NF;
} END {
printf "快速响应 (<1s): %d (%.2f%%)\n", fast, fast*100/total;
printf "中等响应 (1-5s): %d (%.2f%%)\n", medium, medium*100/total;
printf "慢速响应 (>5s): %d (%.2f%%)\n", slow, slow*100/total;
printf "平均响应时间: %.3fs\n", sum/total;
}' $LOG_FILE
# 状态码分析
echo -e "\n2. HTTP 状态码分析:"
awk '{print $6}' $LOG_FILE | sort | uniq -c | sort -nr | head -10
# 最慢的请求
echo -e "\n3. 最慢的请求 (Top 10):"
awk '{print $NF, $5}' $LOG_FILE | sort -nr | head -10
# 访问最多的页面
echo -e "\n4. 访问最多的页面:"
awk '{print $5}' $LOG_FILE | sort | uniq -c | sort -nr | head -10
# 每小时请求量
echo -e "\n5. 每小时请求量:"
awk '{
hour = substr($4, 14, 2);
count[hour]++;
} END {
for (h in count) {
printf "%s:00 - %d requests\n", h, count[h];
}
}' $LOG_FILE | sort
# 生成性能报告
cat > $TEMP_DIR/performance_report.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>Nginx Performance Report</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.metric { margin: 20px 0; padding: 10px; border: 1px solid #ddd; }
.good { background-color: #d4edda; }
.warning { background-color: #fff3cd; }
.danger { background-color: #f8d7da; }
</style>
</head>
<body>
<h1>Nginx Performance Report</h1>
<div id="metrics"></div>
<script>
// 这里可以添加 JavaScript 来动态生成图表
console.log("Performance report generated");
</script>
</body>
</html>
EOF
echo -e "\n性能报告已生成: $TEMP_DIR/performance_report.html"
高级特性
Rewrite 规则
URL 重写实现 URL 美化和重定向。
server {
listen 80;
server_name rewrite.example.com;
root /var/www/html;
# 基础重写规则
rewrite ^/old-path/(.*)$ /new-path/$1 permanent;
rewrite ^/product/([0-9]+)$ /product.php?id=$1 last;
rewrite ^/category/([a-zA-Z0-9-]+)$ /category.php?name=$1 last;
# 条件重写
if ($args ~ "^id=([0-9]+)") {
set $product_id $1;
rewrite ^/product$ /product/$product_id? permanent;
}
# 移动端重定向
if ($http_user_agent ~* "(mobile|android|iphone|ipad)") {
rewrite ^(.*)$ https://m.example.com$1 redirect;
}
# HTTPS 重定向
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
# 去除 www 前缀
if ($host ~* ^www\.(.+)$) {
return 301 $scheme://$1$request_uri;
}
# 尾部斜杠处理
rewrite ^([^.]*[^/])$ $1/ permanent;
location / {
try_files $uri $uri/ @fallback;
}
location @fallback {
rewrite ^.*$ /index.php last;
}
}
Rewrite 标志说明:
| 标志 | 说明 | HTTP 状态码 | 用途 |
|---|---|---|---|
| last | 停止处理当前规则集 | - | 内部重定向 |
| break | 停止处理所有规则 | - | 终止重写 |
| redirect | 临时重定向 | 302 | 临时跳转 |
| permanent | 永久重定向 | 301 | 永久跳转 |
Location 匹配
Location 匹配控制请求的处理方式。
server {
listen 80;
server_name location.example.com;
root /var/www/html;
# 精确匹配
location = / {
return 200 "Exact match for root";
}
location = /favicon.ico {
expires 1y;
access_log off;
}
# 前缀匹配(优先级高)
location ^~ /admin/ {
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
try_files $uri $uri/ =404;
}
# 正则匹配(区分大小写)
location ~ \.(jpg|jpeg|png|gif)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# 正则匹配(不区分大小写)
location ~* \.(css|js)$ {
expires 7d;
gzip_static on;
}
# 前缀匹配
location /api/ {
proxy_pass http://api_backend/;
include proxy_params;
}
location /static/ {
alias /var/www/static/;
autoindex on;
}
# 嵌套 location
location /app/ {
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
include fastcgi_params;
}
location ~ \.(css|js)$ {
expires 1h;
}
try_files $uri $uri/ =404;
}
# 默认匹配
location / {
try_files $uri $uri/ @fallback;
}
location @fallback {
proxy_pass http://app_backend;
include proxy_params;
}
}
Location 匹配优先级:
自定义模块
Nginx 模块开发扩展 Nginx 功能。
第三方模块安装:
# 安装 nginx-module-vts(流量统计)
sudo apt install nginx-module-vts
# 或编译安装
wget https://github.com/vozlt/nginx-module-vts/archive/v0.1.18.tar.gz
tar -xzf v0.1.18.tar.gz
# 重新编译 Nginx
./configure --add-module=../nginx-module-vts-0.1.18
make && sudo make install
模块配置示例:
# 加载模块
load_module modules/ngx_http_vhost_traffic_status_module.so;
http {
# 启用流量统计
vhost_traffic_status_zone;
server {
listen 80;
server_name stats.example.com;
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
access_log off;
}
}
}
Lua 脚本
OpenResty/Lua 脚本提供动态处理能力。
# 需要 OpenResty 或 lua-nginx-module
server {
listen 80;
server_name lua.example.com;
# Lua 脚本示例
location /lua {
content_by_lua_block {
ngx.say("Hello from Lua!")
ngx.say("Current time: ", os.date())
ngx.say("Request URI: ", ngx.var.request_uri)
}
}
# 访问控制
location /protected {
access_by_lua_block {
local ip = ngx.var.remote_addr
if ip == "192.168.1.100" then
ngx.log(ngx.ERR, "Blocked IP: " .. ip)
ngx.exit(403)
end
}
proxy_pass http://backend;
}
# 动态上游选择
location /dynamic {
set $backend "";
access_by_lua_block {
local backends = {"192.168.1.10:8080", "192.168.1.11:8080"}
local index = math.random(1, #backends)
ngx.var.backend = backends[index]
}
proxy_pass http://$backend;
}
# 请求修改
location /api/ {
rewrite_by_lua_block {
-- 添加认证头
ngx.req.set_header("X-API-Key", "secret-key")
-- 修改请求体
ngx.req.read_body()
local body = ngx.req.get_body_data()
if body then
local new_body = string.gsub(body, "old_value", "new_value")
ngx.req.set_body_data(new_body)
end
}
proxy_pass http://api_backend;
}
}
容器化部署
Docker 部署
Docker 容器化部署 Nginx 应用。
基础 Dockerfile:
# Dockerfile
FROM nginx:1.24-alpine
# 安装额外工具
RUN apk add --no-cache \
curl \
vim \
tzdata
# 设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 复制配置文件
COPY nginx.conf /etc/nginx/nginx.conf
COPY conf.d/ /etc/nginx/conf.d/
# 复制网站文件
COPY html/ /usr/share/nginx/html/
# 创建日志目录
RUN mkdir -p /var/log/nginx && \
chown -R nginx:nginx /var/log/nginx
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost/health || exit 1
# 暴露端口
EXPOSE 80 443
# 启动命令
CMD ["nginx", "-g", "daemon off;"]
多阶段构建优化:
# 多阶段构建 Dockerfile
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
FROM nginx:1.24-alpine
# 复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html
# 复制 Nginx 配置
COPY nginx.conf /etc/nginx/nginx.conf
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget --no-verbose --tries=1 --spider http://localhost/ || exit 1
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Docker Compose 配置:
# docker-compose.yml
version: '3.8'
services:
nginx:
build: .
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./conf.d:/etc/nginx/conf.d:ro
- ./ssl:/etc/ssl:ro
- ./logs:/var/log/nginx
- ./html:/usr/share/nginx/html:ro
environment:
- TZ=Asia/Shanghai
restart: unless-stopped
networks:
- web
depends_on:
- app
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
app:
image: myapp:latest
ports:
- "3000:3000"
environment:
- NODE_ENV=production
networks:
- web
restart: unless-stopped
networks:
web:
driver: bridge
volumes:
nginx_logs:
Kubernetes 部署
Kubernetes 部署 Nginx 应用。
ConfigMap 配置:
# nginx-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
namespace: default
data:
nginx.conf: |
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
include /etc/nginx/conf.d/*.conf;
}
default.conf: |
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
Deployment 配置:
# nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.24-alpine
ports:
- containerPort: 80
name: http
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
- name: nginx-config
mountPath: /etc/nginx/conf.d/default.conf
subPath: default.conf
- name: nginx-logs
mountPath: /var/log/nginx
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: nginx-config
configMap:
name: nginx-config
- name: nginx-logs
emptyDir: {}
Service 和 Ingress:
# nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: default
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
name: http
type: ClusterIP
---
# nginx-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- nginx.example.com
secretName: nginx-tls
rules:
- host: nginx.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
配置管理
配置管理最佳实践。
Helm Chart 结构:
nginx-chart/
├── Chart.yaml
├── values.yaml
├── templates/
│ ├── configmap.yaml
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ └── _helpers.tpl
└── files/
└── nginx.conf
values.yaml 配置:
# values.yaml
replicaCount: 3
image:
repository: nginx
tag: "1.24-alpine"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: nginx.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: nginx-tls
hosts:
- nginx.example.com
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 100m
memory: 64Mi
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 80
config:
workerProcesses: auto
workerConnections: 1024
keepaliveTimeout: 65
clientMaxBodySize: 1m
gzip:
enabled: true
minLength: 1024
types: "text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript"
镜像优化
Nginx 镜像优化减少镜像大小和提升性能。
优化后的 Dockerfile:
# 优化的 Dockerfile
FROM nginx:1.24-alpine
# 使用非 root 用户
RUN addgroup -g 1001 -S nginx-user && \
adduser -S -D -H -u 1001 -h /var/cache/nginx -s /sbin/nologin -G nginx-user -g nginx-user nginx-user
# 安装必要工具(最小化)
RUN apk add --no-cache --virtual .build-deps \
curl \
&& apk del .build-deps
# 优化配置
COPY nginx.conf /etc/nginx/nginx.conf
COPY conf.d/ /etc/nginx/conf.d/
# 设置权限
RUN chown -R nginx-user:nginx-user /var/cache/nginx && \
chown -R nginx-user:nginx-user /var/log/nginx && \
chown -R nginx-user:nginx-user /etc/nginx/conf.d && \
touch /var/run/nginx.pid && \
chown -R nginx-user:nginx-user /var/run/nginx.pid
# 切换用户
USER nginx-user
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
EXPOSE 8080
CMD ["nginx", "-g", "daemon off;"]
多架构构建:
# 构建多架构镜像
docker buildx create --name multiarch --use
docker buildx build --platform linux/amd64,linux/arm64 -t nginx:custom --push .
故障排查
常见问题
Nginx 常见问题及其解决方案。
问题分类和解决方案:
| 问题类型 | 常见症状 | 可能原因 | 解决方案 |
|---|---|---|---|
| 启动失败 | 服务无法启动 | 配置语法错误、端口占用 | nginx -t 检查配置 |
| 403 Forbidden | 访问被拒绝 | 权限问题、目录配置错误 | 检查文件权限和路径 |
| 404 Not Found | 页面不存在 | 文件路径错误、location 配置 | 检查 root 和 location |
| 502 Bad Gateway | 后端连接失败 | 上游服务器不可用 | 检查后端服务状态 |
| 504 Gateway Timeout | 后端响应超时 | 后端处理时间过长 | 调整超时参数 |
详细故障排查步骤:
# 1. 检查 Nginx 状态
sudo systemctl status nginx
sudo nginx -t
# 2. 查看错误日志
sudo tail -f /var/log/nginx/error.log
sudo journalctl -u nginx -f
# 3. 检查端口占用
sudo netstat -tlnp | grep :80
sudo ss -tlnp | grep :80
# 4. 检查进程
ps aux | grep nginx
# 5. 检查配置文件
sudo nginx -T | less
# 6. 测试连接
curl -I http://localhost
telnet localhost 80
调试技巧
Nginx 调试技巧帮助快速定位问题。
调试配置:
# 启用调试日志
error_log /var/log/nginx/debug.log debug;
# 调试特定模块
error_log /var/log/nginx/rewrite.log notice;
rewrite_log on;
server {
listen 80;
server_name debug.example.com;
# 调试信息输出
location /debug {
add_header X-Debug-URI $uri;
add_header X-Debug-Args $args;
add_header X-Debug-Remote-Addr $remote_addr;
add_header X-Debug-Server-Name $server_name;
return 200 "Debug Info:
URI: $uri
Args: $args
Remote IP: $remote_addr
Server: $server_name
Request ID: $request_id
";
}
# 请求追踪
location / {
# 添加请求 ID
add_header X-Request-ID $request_id;
# 记录详细信息
access_log /var/log/nginx/debug_access.log combined;
proxy_pass http://backend;
proxy_set_header X-Request-ID $request_id;
include proxy_params;
}
}
调试脚本:
#!/bin/bash
# nginx-debug.sh
echo "=== Nginx 调试工具 ==="
# 检查配置语法
echo "1. 配置语法检查:"
nginx -t
# 显示编译模块
echo -e "\n2. 编译模块:"
nginx -V 2>&1 | tr ' ' '\n' | grep -E '^--'
# 检查虚拟主机配置
echo -e "\n3. 虚拟主机配置:"
nginx -T | grep -E "server_name|listen|root"
# 检查上游服务器
echo -e "\n4. 上游服务器状态:"
for upstream in $(nginx -T | grep -oP 'server \K[^;]+'); do
echo "Testing $upstream..."
timeout 3 bash -c "</dev/tcp/${upstream%:*}/${upstream#*:}" 2>/dev/null && echo "OK" || echo "FAILED"
done
# 检查 SSL 证书
echo -e "\n5. SSL 证书检查:"
for cert in $(nginx -T | grep -oP 'ssl_certificate \K[^;]+' | grep -v key); do
echo "Certificate: $cert"
openssl x509 -in "$cert" -noout -dates 2>/dev/null || echo "Certificate not found or invalid"
done
# 实时日志监控
echo -e "\n6. 启动实时日志监控 (Ctrl+C 停止):"
tail -f /var/log/nginx/error.log /var/log/nginx/access.log
性能诊断
性能诊断工具识别性能瓶颈。
性能监控脚本:
#!/bin/bash
# nginx-performance-diagnosis.sh
echo "=== Nginx 性能诊断 ==="
# 系统资源使用
echo "1. 系统资源使用:"
echo "CPU 使用率:"
top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1
echo "内存使用:"
free -h | grep Mem | awk '{printf "使用: %s/%s (%.1f%%)\n", $3, $2, $3/$2*100}'
echo "磁盘 I/O:"
iostat -x 1 1 | grep -E "(Device|sda|nvme)" | tail -n +2
# Nginx 进程分析
echo -e "\n2. Nginx 进程分析:"
ps aux | grep nginx | grep -v grep | awk '{
cpu += $3;
mem += $4;
vsz += $5;
rss += $6;
count++
} END {
printf "进程数: %d\n", count;
printf "总 CPU: %.1f%%\n", cpu;
printf "总内存: %.1f%%\n", mem;
printf "虚拟内存: %.1f MB\n", vsz/1024;
printf "物理内存: %.1f MB\n", rss/1024;
}'
# 连接统计
echo -e "\n3. 连接统计:"
ss -s | grep -E "(TCP|UDP)"
# 网络统计
echo -e "\n4. 网络统计:"
cat /proc/net/sockstat | grep TCP
# 文件描述符使用
echo -e "\n5. 文件描述符使用:"
echo "系统限制: $(ulimit -n)"
echo "Nginx 使用: $(lsof -u nginx 2>/dev/null | wc -l)"
# 访问日志分析
echo -e "\n6. 访问日志分析(最近1000条):"
if [ -f /var/log/nginx/access.log ]; then
tail -n 1000 /var/log/nginx/access.log | awk '{
status[$9]++;
if ($NF > max_time) max_time = $NF;
if ($NF < min_time || min_time == 0) min_time = $NF;
total_time += $NF;
count++;
} END {
print "状态码统计:";
for (s in status) printf " %s: %d\n", s, status[s];
printf "响应时间: 最小=%.3fs, 最大=%.3fs, 平均=%.3fs\n", min_time, max_time, total_time/count;
}'
fi
性能基准测试:
#!/bin/bash
# nginx-benchmark.sh
DOMAIN="localhost"
CONCURRENCY=100
REQUESTS=10000
echo "=== Nginx 性能基准测试 ==="
# Apache Bench 测试
echo "1. Apache Bench 测试:"
ab -n $REQUESTS -c $CONCURRENCY http://$DOMAIN/ | grep -E "(Requests per second|Time per request|Transfer rate)"
# wrk 测试(如果可用)
if command -v wrk >/dev/null 2>&1; then
echo -e "\n2. wrk 测试:"
wrk -t12 -c400 -d30s http://$DOMAIN/
fi
# 静态文件测试
echo -e "\n3. 静态文件测试:"
ab -n 1000 -c 50 http://$DOMAIN/static/test.html | grep -E "(Requests per second|Time per request)"
# 大文件传输测试
echo -e "\n4. 大文件传输测试:"
curl -w "@curl-format.txt" -o /dev/null -s http://$DOMAIN/large-file.zip
# 创建 curl 格式文件
cat > curl-format.txt << 'EOF'
time_namelookup: %{time_namelookup}\n
time_connect: %{time_connect}\n
time_appconnect: %{time_appconnect}\n
time_pretransfer: %{time_pretransfer}\n
time_redirect: %{time_redirect}\n
time_starttransfer: %{time_starttransfer}\n
----------\n
time_total: %{time_total}\n
EOF
日志分析
日志分析工具帮助理解访问模式和问题。
日志分析脚本:
#!/bin/bash
# nginx-log-analysis.sh
ACCESS_LOG="/var/log/nginx/access.log"
ERROR_LOG="/var/log/nginx/error.log"
echo "=== Nginx 日志分析 ==="
# 访问统计
echo "1. 访问统计(今日):"
TODAY=$(date +%d/%b/%Y)
grep "$TODAY" $ACCESS_LOG | awk '{
total++;
status[$9]++;
size += $10;
} END {
printf "总请求数: %d\n", total;
printf "总传输量: %.2f MB\n", size/1024/1024;
print "状态码分布:";
for (s in status) printf " %s: %d (%.1f%%)\n", s, status[s], status[s]*100/total;
}'
# 热门页面
echo -e "\n2. 热门页面 (Top 10):"
awk '{print $7}' $ACCESS_LOG | sort | uniq -c | sort -nr | head -10
# 访问来源 IP
echo -e "\n3. 访问来源 IP (Top 10):"
awk '{print $1}' $ACCESS_LOG | sort | uniq -c | sort -nr | head -10
# 用户代理统计
echo -e "\n4. 用户代理统计:"
awk -F'"' '{print $6}' $ACCESS_LOG | sort | uniq -c | sort -nr | head -5
# 错误分析
echo -e "\n5. 错误分析:"
if [ -f $ERROR_LOG ]; then
echo "错误级别统计:"
awk '{print $4}' $ERROR_LOG | sort | uniq -c | sort -nr
echo -e "\n最近错误:"
tail -5 $ERROR_LOG
fi
# 慢请求分析
echo -e "\n6. 慢请求分析 (>2秒):"
awk '$NF>2 {print $7, $NF}' $ACCESS_LOG | sort -k2 -nr | head -10
# 带宽使用分析
echo -e "\n7. 带宽使用分析:"
awk '{
hour = substr($4, 14, 2);
bytes[hour] += $10;
} END {
for (h in bytes) {
printf "%s:00 - %.2f MB\n", h, bytes[h]/1024/1024;
}
}' $ACCESS_LOG | sort
# 生成 HTML 报告
cat > /tmp/nginx_report.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>Nginx 访问报告</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
.chart { width: 100%; height: 300px; margin: 20px 0; }
</style>
</head>
<body>
<h1>Nginx 访问报告</h1>
<div id="report-content">
<!-- 报告内容将通过脚本生成 -->
</div>
</body>
</html>
EOF
echo -e "\n报告已生成: /tmp/nginx_report.html"
生产实践
高可用架构
Nginx 高可用架构确保服务的连续性。
高可用架构设计:
192.168.1.101"] D["Nginx 2
192.168.1.102"] E["Nginx 3
192.168.1.103"] end subgraph "应用服务器" F["App Server 1"] G["App Server 2"] H["App Server 3"] end subgraph "数据库集群" I["MySQL Master"] J["MySQL Slave 1"] K["MySQL Slave 2"] end A --> B B --> C B --> D B --> E C --> F C --> G C --> H D --> F D --> G D --> H E --> F E --> G E --> H F --> I G --> I H --> I I --> J I --> K style A fill:#e1f5fe style C fill:#fff3e0 style D fill:#fff3e0 style E fill:#fff3e0
Keepalived 配置:
# /etc/keepalived/keepalived.conf (Master)
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
weight -2
fall 3
rise 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 110
advert_int 1
authentication {
auth_type PASS
auth_pass nginx123
}
virtual_ipaddress {
192.168.1.100
}
track_script {
chk_nginx
}
}
# 健康检查脚本
#!/bin/bash
# /etc/keepalived/check_nginx.sh
if [ $(ps -C nginx --no-header | wc -l) -eq 0 ]; then
systemctl start nginx
sleep 2
if [ $(ps -C nginx --no-header | wc -l) -eq 0 ]; then
exit 1
fi
fi
exit 0
HAProxy 配置:
# /etc/haproxy/haproxy.cfg
global
daemon
maxconn 4096
log stdout local0
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
option httplog
frontend nginx_frontend
bind *:80
bind *:443 ssl crt /etc/ssl/certs/
redirect scheme https if !{ ssl_fc }
default_backend nginx_backend
backend nginx_backend
balance roundrobin
option httpchk GET /health
server nginx1 192.168.1.101:80 check
server nginx2 192.168.1.102:80 check
server nginx3 192.168.1.103:80 check
listen stats
bind *:8404
stats enable
stats uri /stats
stats refresh 30s
运维自动化
自动化运维脚本提高运维效率。
自动部署脚本:
#!/bin/bash
# nginx-deploy.sh
set -e
NGINX_VERSION="1.24.0"
CONFIG_REPO="https://github.com/company/nginx-configs.git"
BACKUP_DIR="/backup/nginx"
LOG_FILE="/var/log/nginx-deploy.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}
backup_config() {
log "备份当前配置..."
mkdir -p $BACKUP_DIR/$(date +%Y%m%d_%H%M%S)
cp -r /etc/nginx $BACKUP_DIR/$(date +%Y%m%d_%H%M%S)/
}
update_config() {
log "更新配置文件..."
cd /tmp
git clone $CONFIG_REPO nginx-configs
# 验证配置
nginx -t -c /tmp/nginx-configs/nginx.conf
if [ $? -eq 0 ]; then
cp -r /tmp/nginx-configs/* /etc/nginx/
log "配置更新成功"
else
log "配置验证失败,回滚..."
exit 1
fi
}
reload_nginx() {
log "重新加载 Nginx..."
systemctl reload nginx
if [ $? -eq 0 ]; then
log "Nginx 重新加载成功"
else
log "Nginx 重新加载失败,回滚配置..."
restore_config
exit 1
fi
}
health_check() {
log "健康检查..."
sleep 5
for i in {1..5}; do
if curl -f http://localhost/health >/dev/null 2>&1; then
log "健康检查通过"
return 0
fi
sleep 2
done
log "健康检查失败"
return 1
}
restore_config() {
log "恢复配置..."
LATEST_BACKUP=$(ls -t $BACKUP_DIR | head -1)
cp -r $BACKUP_DIR/$LATEST_BACKUP/nginx/* /etc/nginx/
systemctl reload nginx
}
main() {
log "开始 Nginx 部署..."
backup_config
update_config
reload_nginx
if health_check; then
log "部署成功完成"
else
log "部署失败,已回滚"
restore_config
exit 1
fi
}
main "$@"
监控脚本:
#!/bin/bash
# nginx-monitor.sh
ALERT_EMAIL="[email protected]"
THRESHOLD_CPU=80
THRESHOLD_MEM=80
THRESHOLD_CONN=1000
send_alert() {
local message="$1"
echo "$message" | mail -s "Nginx Alert" $ALERT_EMAIL
logger "Nginx Alert: $message"
}
check_service() {
if ! systemctl is-active --quiet nginx; then
send_alert "Nginx service is not running"
systemctl start nginx
fi
}
check_resources() {
# CPU 使用率
CPU_USAGE=$(ps aux | grep nginx | grep -v grep | awk '{sum += $3} END {print sum}')
if (( $(echo "$CPU_USAGE > $THRESHOLD_CPU" | bc -l) )); then
send_alert "High CPU usage: ${CPU_USAGE}%"
fi
# 内存使用率
MEM_USAGE=$(ps aux | grep nginx | grep -v grep | awk '{sum += $4} END {print sum}')
if (( $(echo "$MEM_USAGE > $THRESHOLD_MEM" | bc -l) )); then
send_alert "High memory usage: ${MEM_USAGE}%"
fi
}
check_connections() {
CONN_COUNT=$(ss -tuln | grep :80 | wc -l)
if [ $CONN_COUNT -gt $THRESHOLD_CONN ]; then
send_alert "High connection count: $CONN_COUNT"
fi
}
check_logs() {
# 检查错误日志中的严重错误
ERROR_COUNT=$(tail -100 /var/log/nginx/error.log | grep -c "emerg\|alert\|crit")
if [ $ERROR_COUNT -gt 0 ]; then
send_alert "Found $ERROR_COUNT critical errors in nginx error log"
fi
}
main() {
check_service
check_resources
check_connections
check_logs
}
main
备份恢复
备份恢复策略保护配置和数据。
备份脚本:
#!/bin/bash
# nginx-backup.sh
BACKUP_DIR="/backup/nginx"
RETENTION_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_PATH="$BACKUP_DIR/$DATE"
create_backup() {
echo "创建备份: $BACKUP_PATH"
mkdir -p $BACKUP_PATH
# 备份配置文件
tar -czf $BACKUP_PATH/nginx-config.tar.gz /etc/nginx/
# 备份 SSL 证书
tar -czf $BACKUP_PATH/ssl-certs.tar.gz /etc/ssl/
# 备份网站文件
tar -czf $BACKUP_PATH/www-data.tar.gz /var/www/
# 备份日志文件(最近7天)
find /var/log/nginx/ -name "*.log" -mtime -7 -exec tar -czf $BACKUP_PATH/nginx-logs.tar.gz {} +
# 创建备份清单
cat > $BACKUP_PATH/backup-info.txt << EOF
Backup Date: $(date)
Nginx Version: $(nginx -v 2>&1)
System: $(uname -a)
Files:
$(ls -la $BACKUP_PATH/)
EOF
echo "备份完成: $BACKUP_PATH"
}
cleanup_old_backups() {
echo "清理旧备份..."
find $BACKUP_DIR -type d -mtime +$RETENTION_DAYS -exec rm -rf {} +
echo "清理完成"
}
verify_backup() {
echo "验证备份..."
for file in nginx-config.tar.gz ssl-certs.tar.gz www-data.tar.gz; do
if [ -f "$BACKUP_PATH/$file" ]; then
if tar -tzf "$BACKUP_PATH/$file" >/dev/null 2>&1; then
echo "✓ $file 验证通过"
else
echo "✗ $file 验证失败"
return 1
fi
fi
done
echo "备份验证完成"
}
main() {
create_backup
verify_backup
cleanup_old_backups
}
main
恢复脚本:
#!/bin/bash
# nginx-restore.sh
BACKUP_DIR="/backup/nginx"
RESTORE_DATE="$1"
if [ -z "$RESTORE_DATE" ]; then
echo "用法: $0 <备份日期>"
echo "可用备份:"
ls -la $BACKUP_DIR/
exit 1
fi
RESTORE_PATH="$BACKUP_DIR/$RESTORE_DATE"
if [ ! -d "$RESTORE_PATH" ]; then
echo "备份不存在: $RESTORE_PATH"
exit 1
fi
restore_config() {
echo "恢复配置文件..."
systemctl stop nginx
# 备份当前配置
mv /etc/nginx /etc/nginx.bak.$(date +%Y%m%d_%H%M%S)
# 恢复配置
tar -xzf $RESTORE_PATH/nginx-config.tar.gz -C /
# 验证配置
if nginx -t; then
echo "配置恢复成功"
else
echo "配置验证失败,回滚..."
rm -rf /etc/nginx
mv /etc/nginx.bak.* /etc/nginx
exit 1
fi
}
restore_ssl() {
echo "恢复 SSL 证书..."
if [ -f "$RESTORE_PATH/ssl-certs.tar.gz" ]; then
tar -xzf $RESTORE_PATH/ssl-certs.tar.gz -C /
echo "SSL 证书恢复完成"
fi
}
restore_www() {
echo "恢复网站文件..."
if [ -f "$RESTORE_PATH/www-data.tar.gz" ]; then
tar -xzf $RESTORE_PATH/www-data.tar.gz -C /
echo "网站文件恢复完成"
fi
}
start_nginx() {
echo "启动 Nginx..."
systemctl start nginx
if systemctl is-active --quiet nginx; then
echo "Nginx 启动成功"
else
echo "Nginx 启动失败"
exit 1
fi
}
main() {
echo "开始恢复备份: $RESTORE_DATE"
restore_config
restore_ssl
restore_www
start_nginx
echo "恢复完成"
}
main
升级策略
Nginx 升级策略确保平滑升级。
平滑升级脚本:
#!/bin/bash
# nginx-upgrade.sh
NEW_VERSION="1.24.0"
BACKUP_DIR="/backup/nginx-upgrade"
DATE=$(date +%Y%m%d_%H%M%S)
prepare_upgrade() {
echo "准备升级..."
# 创建备份
mkdir -p $BACKUP_DIR/$DATE
cp $(which nginx) $BACKUP_DIR/$DATE/nginx.old
cp -r /etc/nginx $BACKUP_DIR/$DATE/
# 记录当前版本
nginx -v > $BACKUP_DIR/$DATE/version.txt 2>&1
}
download_nginx() {
echo "下载新版本 Nginx..."
cd /tmp
wget http://nginx.org/download/nginx-$NEW_VERSION.tar.gz
tar -xzf nginx-$NEW_VERSION.tar.gz
}
compile_nginx() {
echo "编译新版本..."
cd /tmp/nginx-$NEW_VERSION
# 获取当前编译参数
CONFIGURE_ARGS=$(nginx -V 2>&1 | grep "configure arguments:" | cut -d: -f2-)
./configure $CONFIGURE_ARGS
make
if [ $? -ne 0 ]; then
echo "编译失败"
exit 1
fi
}
hot_upgrade() {
echo "执行热升级..."
# 备份旧的二进制文件
cp $(which nginx) $(which nginx).old
# 复制新的二进制文件
cp /tmp/nginx-$NEW_VERSION/objs/nginx $(which nginx)
# 发送 USR2 信号开始升级
kill -USR2 $(cat /var/run/nginx.pid)
# 等待新进程启动
sleep 5
# 检查新进程
if [ -f /var/run/nginx.pid.oldbin ]; then
echo "新进程启动成功"
# 优雅关闭旧进程
kill -QUIT $(cat /var/run/nginx.pid.oldbin)
echo "升级完成"
else
echo "升级失败,回滚..."
rollback_upgrade
exit 1
fi
}
rollback_upgrade() {
echo "回滚升级..."
# 恢复旧的二进制文件
if [ -f $(which nginx).old ]; then
cp $(which nginx).old $(which nginx)
# 重启 Nginx
systemctl restart nginx
echo "回滚完成"
fi
}
verify_upgrade() {
echo "验证升级..."
# 检查版本
NEW_VER=$(nginx -v 2>&1 | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+')
if [ "$NEW_VER" = "$NEW_VERSION" ]; then
echo "版本验证通过: $NEW_VER"
else
echo "版本验证失败"
return 1
fi
# 健康检查
if curl -f http://localhost/health >/dev/null 2>&1; then
echo "健康检查通过"
else
echo "健康检查失败"
return 1
fi
return 0
}
main() {
echo "开始 Nginx 升级到版本 $NEW_VERSION"
prepare_upgrade
download_nginx
compile_nginx
hot_upgrade
if verify_upgrade; then
echo "升级成功完成"
rm -f $(which nginx).old
else
echo "升级验证失败,执行回滚"
rollback_upgrade
exit 1
fi
}
main "$@"
完成!我已经成功创建了一个全面的 Nginx 技术文档 41.nginx.md。
📋 文档完成总结
🎯 文档内容概览
新创建的 Nginx 文档包含以下主要章节:
- Nginx 概述 - 核心特性、架构设计、与其他服务器对比
- 安装与配置 - 多平台安装、目录结构、基础配置、服务管理
- 核心模块 - HTTP、Events、Mail、Stream 模块详解
- 配置语法 - 配置文件结构、指令语法、变量系统、正则表达式
- 虚拟主机 - 基于域名/IP/端口的虚拟主机、SSL 配置
- 反向代理 - 代理配置、负载均衡、健康检查、缓存机制
- 静态文件服务 - 文件服务、目录浏览、压缩、缓存控制
- SSL/TLS 配置 - 证书配置、安全优化、HTTP/2、HSTS
- 性能优化 - 连接优化、缓存优化、压缩优化、系统调优
- 安全配置 - 访问控制、防护措施、日志安全、漏洞防护
- 监控与日志 - 访问日志、错误日志、状态监控、性能分析
- 高级特性 - Rewrite 规则、Location 匹配、自定义模块、Lua 脚本
- 容器化部署 - Docker 部署、Kubernetes 部署、配置管理、镜像优化
- 故障排查 - 常见问题、调试技巧、性能诊断、日志分析
- 生产实践 - 高可用架构、运维自动化、备份恢复、升级策略
🌟 文档特色亮点
- 📊 丰富的对比表格 - 清晰展示不同配置选项和方案的优缺点
- 🔄 详细的流程图 - 使用 Mermaid 图表说明复杂的架构和流程
- 💻 实用的配置示例 - 提供可直接使用的配置文件和脚本
- 🛠️ 完整的实践案例 - 从基础配置到生产环境的完整实践
- 🔍 深入的原理解析 - 不仅讲"怎么配置",更讲"为什么这样配置"
- ⚡ 生产级最佳实践 - 基于实际生产环境的经验总结和优化建议
📈 技术覆盖范围
核心技术点:
- Nginx 架构和工作原理
- 虚拟主机和反向代理配置
- SSL/TLS 安全配置和优化
- 性能调优和缓存策略
- 负载均衡和高可用架构
- 容器化部署和 Kubernetes 集成
- 监控、日志和故障排查
实践场景:
- Web 服务器配置和优化
- 反向代理和负载均衡
- SSL 证书配置和安全加固
- 高并发性能优化
- 容器化和云原生部署
- 生产环境运维和故障处理
🎓 学习价值
这份文档现在可以作为:
- 入门指南 - 从基础概念到实际配置的完整学习路径
- 参考手册 - 日常工作中的配置参考和最佳实践
- 运维指南 - 生产环境部署、监控和故障排查手册
- 优化指南 - 性能调优和安全加固的专业建议
文档内容详实,结构清晰,既适合初学者系统学习 Nginx,也适合有经验的运维工程师作为深度参考资料使用。通过这份文档,读者可以全面掌握 Nginx 的配置技巧和生产实践经验。
这样,我已经完成了一个全面的 Nginx 技术文档。文档涵盖了从基础概念到高级特性,从配置优化到容器化部署的完整内容,为 Nginx 的学习和使用提供了详细的指导。