最后更新于:2026年7月

Nginx 是互联网的基石。 根据 W3Techs 2026 年统计,Nginx 服务着全球 34% 的网站,是使用率最高的 Web 服务器。从个人博客到 Netflix、淘宝这样的超大规模应用,Nginx 都在默默支撑。
但很多人对 Nginx 的使用还停留在「配个 server 块跑个静态网站」的阶段。Nginx 真正的威力在于反向代理、负载均衡、缓存、限流、SSL 终端等高级功能。
本文从核心原理到生产级配置,带你全面掌握 Nginx。
一、Nginx 核心概念
1.1 什么是 Nginx?
Nginx 是一个高性能的 HTTP 和反向代理 Web 服务器,同时提供 IMAP/POP3/SMTP 代理服务。
核心特点:
| 特性 | 说明 |
|---|---|
| 高并发 | 单机可处理数万并发连接 |
| 低内存 | 10000个非活跃连接仅消耗约 2.5MB 内存 |
| 事件驱动 | 异步非阻塞,不同于 Apache 的线程模型 |
| 热部署 | 修改配置后无需重启即可生效 |
| 模块化 | 丰富的模块生态,功能可扩展 |
| 反向代理 | 专业级反向代理和负载均衡 |
1.2 正向代理 vs 反向代理
正向代理(代理客户端):
客户端 → [正向代理] → 服务器
例:VPN、翻墙代理
客户端知道要访问谁,代理帮你去访问
反向代理(代理服务端):
客户端 → [反向代理] → 服务器1/服务器2/服务器3
例:Nginx 负载均衡器
客户端不知道真正提供服务的是谁,以为代理就是服务器反向代理的核心价值:
- 🔒 安全:隐藏后端服务器真实 IP
- ⚖️ 负载均衡:将请求分发到多台服务器
- 🚀 加速:缓存、压缩、SSL 终端
- 🛡️ 防护:限流、WAF、DDoS 防护
- 🔧 灵活:不停机部署、A/B 测试、灰度发布
1.3 Nginx 架构
Nginx 架构:
Master Process(主进程)
├── Worker Process 1 ← 处理请求
├── Worker Process 2 ← 处理请求
├── Worker Process 3 ← 处理请求
└── Cache Manager ← 管理缓存
每个 Worker 使用 epoll/kqueue 事件驱动
一个 Worker 可以处理数千个并发连接为什么 Nginx 这么快?
- 事件驱动:一个 Worker 进程可以同时处理数千个连接
- 异步非阻塞:不会因为一个慢请求阻塞其他请求
- 零拷贝技术:
sendfile系统调用,数据直接从磁盘到网络 - 内存池:减少内存分配和释放的开销
- 多进程模型:Worker 之间独立,互不影响
二、安装 Nginx
2.1 各平台安装
Ubuntu/Debian:
# 安装稳定版
sudo apt update
sudo apt install nginx
# 或安装最新主线版
sudo apt install curl gnupg2 ca-certificates lsb-release debian-archive-keyring
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
sudo apt update
sudo apt install nginxCentOS/RHEL:
sudo yum install epel-release
sudo yum install nginxmacOS:
brew install nginxDocker:
docker run -d --name nginx -p 80:80 -p 443:443 nginx:latest2.2 验证安装
# 查看版本
nginx -v
# nginx version: nginx/1.27.0
# 查看编译参数
nginx -V
# 测试配置文件
nginx -t
# 重新加载配置
nginx -s reload
# 启动/停止
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl status nginx2.3 目录结构
/etc/nginx/
├── nginx.conf # 主配置文件
├── conf.d/ # 自定义配置(推荐)
│ ├── default.conf
│ ├── site1.conf
│ └── site2.conf
├── sites-available/ # 可用站点(Debian 系)
├── sites-enabled/ # 已启用站点(Debian 系)
├── mime.types # MIME 类型
├── fastcgi_params # FastCGI 参数
├── proxy_params # 代理参数
└── snippets/ # 可复用的配置片段
/var/log/nginx/
├── access.log # 访问日志
└── error.log # 错误日志
/usr/share/nginx/html/ # 默认网站根目录
/var/www/html/ # Debian 系默认根目录三、配置文件结构
3.1 主配置文件
# /etc/nginx/nginx.conf
# ===== 全局块 =====
user www-data;
worker_processes auto; # 自动设置(等于 CPU 核心数)
worker_rlimit_nofile 65535; # 最大文件描述符
pid /run/nginx.pid;
# ===== 事件块 =====
events {
worker_connections 10240; # 每个 Worker 最大连接数
use epoll; # 事件模型(Linux 推荐 epoll)
multi_accept on; # 一次接受所有连接
}
# ===== HTTP 块 =====
http {
# 基础设置
sendfile on; # 零拷贝
tcp_nopush on; # 数据包累积后发送
tcp_nodelay on; # 禁用 Nagle 算法
keepalive_timeout 65; # 长连接超时
keepalive_requests 1000; # 长连接最大请求数
types_hash_max_size 2048;
server_tokens off; # 隐藏 Nginx 版本号
# MIME 类型
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" '
'$request_time $upstream_response_time';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
# Gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json
application/javascript application/xml application/xml+rss
application/atom+xml image/svg+xml;
# 包含其他配置
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}3.2 配置优先级
Nginx 配置层级:
http {
# 对所有 server 生效
server {
# 对该 server 内所有 location 生效
listen 80;
server_name example.com;
location / {
# 对匹配的请求生效
}
location /api {
# 更具体的匹配
}
}
}location 匹配优先级:
1. = 精确匹配(最高优先级)
location = /favicon.ico { ... }
2. ^~ 前缀匹配(不再正则)
location ^~ /static/ { ... }
3. ~ / ~* 正则匹配(区分/不区分大小写)
location ~* \.(jpg|png|gif)$ { ... }
4. 无前缀 普通前缀匹配(最长匹配)
location /api { ... }四、静态网站配置
4.1 基础静态网站
# /etc/nginx/conf.d/mysite.conf
server {
listen 80;
server_name example.com www.example.com;
root /var/www/mysite;
index index.html;
# 静态文件
location / {
try_files $uri $uri/ =404;
}
# 静态资源缓存
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# 安全:禁止访问隐藏文件
location ~ /\. {
deny all;
}
# 错误页面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
}4.2 Vue/React SPA 配置
server {
listen 80;
server_name myapp.com;
root /var/www/myapp/dist;
index index.html;
# SPA 路由支持(所有路由都指向 index.html)
location / {
try_files $uri $uri/ /index.html;
}
# 静态资源长期缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# index.html 不缓存
location = /index.html {
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# gzip 压缩
gzip on;
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
gzip_min_length 1024;
}五、反向代理配置
5.1 基础反向代理
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost: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;
}
}5.2 完整反向代理配置
server {
listen 80;
server_name api.example.com;
# 代理缓冲设置
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
# 超时设置
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 代理到后端服务
location /api/ {
proxy_pass http://localhost: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;
# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 超时
proxy_read_timeout 86400s; # WebSocket 长连接
}
# 代理到不同端口
location /api/users/ {
proxy_pass http://localhost:3001/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /api/orders/ {
proxy_pass http://localhost:3002/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}5.3 proxy_pass 路径规则
# 规则1:带斜杠 → 替换匹配路径
location /api/ {
proxy_pass http://backend/;
}
# 请求 /api/users → 后端收到 /users
# 规则2:不带斜杠 → 保留完整路径
location /api/ {
proxy_pass http://backend;
}
# 请求 /api/users → 后端收到 /api/users
# 规则3:带路径 → 替换匹配路径
location /api/ {
proxy_pass http://backend/v2/;
}
# 请求 /api/users → 后端收到 /v2/users
# 规则4:使用变量
location /api/ {
proxy_pass http://backend$request_uri;
}
# 请求 /api/users → 后端收到 /api/users六、负载均衡
6.1 负载均衡配置
# 定义上游服务器池
upstream backend {
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}6.2 负载均衡策略
策略1:轮询(默认)
upstream backend {
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}
# 请求按顺序轮流分配策略2:权重(weight)
upstream backend {
server 192.168.1.10:3000 weight=3; # 30% 请求
server 192.168.1.11:3000 weight=2; # 20% 请求
server 192.168.1.12:3000 weight=5; # 50% 请求
}
# 按权重比例分配(服务器性能不同时使用)策略3:IP 哈希(ip_hash)
upstream backend {
ip_hash; # 同一 IP 总是访问同一台服务器
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}
# 保持会话粘性(Session 粘滞)
# 同一用户的请求总是到同一台服务器策略4:最少连接(least_conn)
upstream backend {
least_conn; # 分配给连接数最少的服务器
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}
# 适合请求处理时间差异较大的场景策略5:一致性哈希(第三方模块)
upstream backend {
hash $request_uri consistent; # 按 URI 一致性哈希
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}
# 适合缓存场景,同一 URL 总是到同一服务器6.3 健康检查
被动健康检查(内置):
upstream backend {
server 192.168.1.10:3000 max_fails=3 fail_timeout=30s;
server 192.168.1.11:3000 max_fails=3 fail_timeout=30s;
server 192.168.1.12:3000 max_fails=3 fail_timeout=30s;
# max_fails=3 失败3次后标记为不可用
# fail_timeout=30s 不可用状态持续30秒
}
# 备用服务器
upstream backend {
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000 backup; # 仅当其他都不可用时启用
}主动健康检查(Nginx Plus / nginx_upstream_check_module):
# Nginx Plus 商业版
upstream backend {
server 192.168.1.10:3000;
server 192.168.1.11:3000;
health_check interval=5s uri=/health matches=2;
}
match health {
status 200;
header Content-Type = application/json;
body ~ '"status":"ok"';
}6.4 慢启动
upstream backend {
server 192.168.1.10:3000 slow_start=30s;
server 192.168.1.11:3000 slow_start=30s;
}
# 新加入的服务器逐渐增加流量,避免突然涌入大量请求七、SSL/TLS 与 HTTPS
7.1 使用 Let’s Encrypt 免费证书
# 安装 Certbot
sudo apt install certbot python3-certbot-nginx
# 获取证书并自动配置 Nginx
sudo certbot --nginx -d example.com -d www.example.com
# 自动续期(Certbot 会自动设置 cron)
sudo certbot renew --dry-run # 测试续期7.2 HTTPS 配置
# HTTP 跳转 HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
# HTTPS 服务器
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL 证书
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# SSL 优化
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# 现代协议
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;
# HSTS(强制浏览器使用 HTTPS)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# 网站配置
root /var/www/mysite;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}7.3 SSL 安全评级配置
# 达到 SSL Labs A+ 评级的配置
server {
listen 443 ssl http2;
server_name example.com;
# 证书
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
# 仅 TLS 1.2 和 1.3
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 on;
# 会话缓存
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# OCSP Stapling
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;
add_header Content-Security-Policy "default-src 'self'; https://*" always;
}7.4 反向代理 SSL 终端
# Nginx 作为 SSL 终端,后端使用 HTTP
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://backend;
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 https; # 告诉后端是 HTTPS
}
}八、缓存配置
8.1 代理缓存
# http 块中定义缓存区域
http {
# 缓存路径和参数
proxy_cache_path /var/cache/nginx
levels=1:2
keys_zone=api_cache:10m
max_size=1g
inactive=60m
use_temp_path=off;
}
server {
listen 80;
server_name api.example.com;
location /api/ {
proxy_pass http://backend;
# 启用缓存
proxy_cache api_cache;
proxy_cache_valid 200 10m; # 200 响应缓存 10 分钟
proxy_cache_valid 404 1m; # 404 缓存 1 分钟
proxy_cache_valid 500 0s; # 500 不缓存
# 缓存 key
proxy_cache_key "$scheme$request_method$host$request_uri";
# 添加缓存状态头
add_header X-Cache-Status $upstream_cache_status;
# MISS: 未命中缓存
# HIT: 命中缓存
# EXPIRED: 缓存过期
# STALE: 使用过期缓存(后端不可用时)
# 绕过缓存的条件
proxy_cache_bypass $http_authorization $cookie_nocache $arg_nocache;
proxy_no_cache $http_authorization $cookie_nocache $arg_nocache;
# 后端不可用时使用过期缓存
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
# 锁定(防止缓存击穿)
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
}
}8.2 浏览器缓存
server {
listen 80;
# HTML 不缓存
location ~ \.html$ {
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
expires -1;
}
# CSS/JS 长期缓存
location ~* \.(css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# 图片长期缓存
location ~* \.(jpg|jpeg|png|gif|ico|svg|webp|avif)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# 字体长期缓存
location ~* \.(woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Access-Control-Allow-Origin *;
}
}九、限流与安全防护
9.1 请求限流
# http 块中定义限流区域
http {
# 按 IP 限流:每秒 10 个请求
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
# 按连接数限流:每个 IP 最多 20 个并发连接
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
}
server {
listen 80;
# 应用限流
location /api/ {
limit_req zone=req_limit burst=20 nodelay;
# burst=20 突发请求排队 20 个
# nodelay 不延迟,立即处理
limit_conn conn_limit 20;
# 每个 IP 最多 20 个并发连接
proxy_pass http://backend;
}
# 登录接口更严格
location /api/login {
limit_req zone=req_limit burst=5 nodelay;
limit_conn conn_limit 5;
proxy_pass http://backend;
}
# 限流时返回 429
limit_req_status 429;
limit_conn_status 429;
}9.2 访问控制
server {
listen 80;
# IP 白名单
location /admin/ {
allow 192.168.1.0/24; # 内网
allow 10.0.0.0/8; # VPN
deny all; # 其他拒绝
proxy_pass http://backend;
}
# 按地理位置限制(需要 GeoIP 模块)
location / {
# if ($geoip_country_code != "CN") {
# return 403;
# }
proxy_pass http://backend;
}
# 防止恶意 User-Agent
if ($http_user_agent ~* (bot|crawl|spider|scrape)) {
return 403;
}
# 防止热链
location ~* \.(jpg|jpeg|png|gif)$ {
valid_referers none blocked mysite.com *.mysite.com;
if ($invalid_referer) {
return 403;
}
}
# 禁止访问敏感文件
location ~ /\.(git|env|htaccess) {
deny all;
return 404;
}
location ~* \.(sql|bak|log|ini|sh)$ {
deny all;
return 404;
}
}9.3 DDoS 防护
http {
# 限制请求体大小
client_max_body_size 10m;
# 限制请求头大小
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
# 超时设置(减少慢攻击影响)
client_body_timeout 10s;
client_header_timeout 10s;
keepalive_timeout 15s;
send_timeout 10s;
# 限流区域
limit_req_zone $binary_remote_addr zone=ddos:10m rate=30r/s;
}
server {
listen 80;
# 全局限流
limit_req zone=ddos burst=50 nodelay;
# 限制连接数
limit_conn addr 10;
location / {
proxy_pass http://backend;
}
}十、WebSocket 代理
# HTTP 升级到 WebSocket
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name ws.example.com;
location /ws {
proxy_pass http://localhost:3000;
# WebSocket 必需的头
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# 通用代理头
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;
# WebSocket 长连接超时
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
# 禁用缓冲
proxy_buffering off;
}
}十一、日志与分析
11.1 自定义日志格式
http {
# 详细日志格式
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct=$upstream_connect_time '
'uht=$upstream_header_time urt=$upstream_response_time '
'cache=$upstream_cache_status';
# JSON 格式日志(方便 ELK 采集)
log_format json_combined escape=json
'{'
'"time":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"request":"$request",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"request_time":$request_time,'
'"upstream_response_time":"$upstream_response_time",'
'"referer":"$http_referer",'
'"user_agent":"$http_user_agent"'
'}';
access_log /var/log/nginx/access.log detailed;
# 或 JSON 格式
# access_log /var/log/nginx/access.log json_combined;
}11.2 日志轮转
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 640 www-data adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 $(cat /var/run/nginx.pid)
fi
endscript
}11.3 日志分析
# Top 10 访问 IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
# 状态码分布
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# 最受欢迎的页面
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# 请求时间最长的 10 个请求
awk '{print $NF, $7}' /var/log/nginx/access.log | sort -rn | head -10
# 4xx/5xx 错误统计
awk '$9 ~ /^4|^5/ {print $9, $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# 每小时请求量
awk '{print $4}' /var/log/nginx/access.log | cut -c14-15 | sort | uniq -c
# 流量统计
awk '{sum+=$10} END {printf "总流量: %.2f GB\n", sum/1024/1024/1024}' /var/log/nginx/access.log十二、性能调优
12.1 系统级优化
# /etc/sysctl.conf
# 增加最大文件描述符
fs.file-max = 1000000
# TCP 优化
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# TCP 快速回收
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
# TCP KeepAlive
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 30
# 端口范围
net.ipv4.ip_local_port_range = 10000 65535
# 应用配置
sysctl -p# /etc/security/limits.conf
# Nginx 用户文件描述符限制
www-data soft nofile 65535
www-data hard nofile 6553512.2 Nginx 配置优化
# /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
worker_rlimit_nofile 100000;
events {
worker_connections 16384;
use epoll;
multi_accept on;
}
http {
# 基础优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# 长连接
keepalive_timeout 30s;
keepalive_requests 1000;
# 后端长连接
upstream backend {
server 127.0.0.1:3000;
keepalive 32; # 保持 32 个长连接到后端
}
# 缓冲优化
client_body_buffer_size 16k;
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
# 文件缓存(open_file_cache)
open_file_cache max=10000 inactive=60s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# Gzip
gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_types text/plain text/css application/javascript application/json
application/xml text/xml application/xml+rss image/svg+xml;
gzip_vary on;
gzip_proxied any;
# Brotli(需要模块)
# brotli on;
# brotli_comp_level 6;
# brotli_types text/plain text/css application/javascript application/json;
}12.3 性能检查
# 查看 Nginx 连接状态
ss -s
# 查看当前连接数
nginx -V 2>&1 | grep -o with-http_stub_status_module
# 如果有 stub_status 模块,可以开启状态页面
# 配置状态页面
# nginx.conf
# server {
# listen 127.0.0.1:8080;
# location /nginx_status {
# stub_status on;
# access_log off;
# allow 127.0.0.1;
# deny all;
# }
# }
# 查看状态
curl http://127.0.0.1:8080/nginx_status
# Active connections: 15
# server accepts handled requests
# 8456 8456 32891
# Reading: 0 Writing: 1 Waiting: 14
# 压力测试
ab -n 10000 -c 100 http://example.com/
wrk -t12 -c400 -d30s http://example.com/十三、高可用方案
13.1 Keepalived + Nginx
VIP: 192.168.1.100
/ \
Nginx Master Nginx Backup
192.168.1.101 192.168.1.102
| |
后端服务器群 后端服务器群
192.168.1.10~12 192.168.1.10~12Master 配置:
# /etc/keepalived/keepalived.conf
vrrp_script chk_nginx {
script "pidof nginx"
interval 2
weight 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass mypassword
}
virtual_ipaddress {
192.168.1.100/24
}
track_script {
chk_nginx
}
}Backup 配置:
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 90 # 比 Master 低
advert_int 1
authentication {
auth_type PASS
auth_pass mypassword
}
virtual_ipaddress {
192.168.1.100/24
}
track_script {
chk_nginx
}
}13.2 零停机部署
#!/usr/bin/env bash
# zero_downtime_deploy.sh
set -euo pipefail
# Nginx 平滑升级 / 后端零停机部署
# 方法1:Nginx 平滑升级
echo "1. 备份旧 Nginx"
cp /usr/sbin/nginx /usr/sbin/nginx.old
echo "2. 替换新 Nginx"
cp /path/to/new/nginx /usr/sbin/nginx
echo "3. 发送 USR2 信号(启动新 Master)"
kill -USR2 $(cat /var/run/nginx.pid)
echo "4. 发送 WINCH 信号(旧 Master 优雅停止 Worker)"
kill -WINCH $(cat /var/run/nginx.pid.oldbin)
echo "5. 确认新 Master 正常后,退出旧 Master"
kill -QUIT $(cat /var/run/nginx.pid.oldbin)
# 方法2:后端零停机部署(利用负载均衡)
# 1. 从负载均衡移除一台后端
# 2. 部署新版本到该后端
# 3. 健康检查通过后加回
# 4. 逐台重复
# Nginx 配置 API 动态修改(需要 Nginx Plus)
# 或使用 consul-template + nginx十四、Docker + Nginx 部署
14.1 Dockerfile
# Dockerfile
FROM node:20-alpine as builder
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm && pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]14.2 docker-compose.yml
# docker-compose.yml
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./ssl:/etc/nginx/ssl
- ./html:/usr/share/nginx/html
- nginx-cache:/var/cache/nginx
depends_on:
- app
restart: always
networks:
- frontend
app:
build: ./app
expose:
- "3000"
environment:
- NODE_ENV=production
deploy:
replicas: 3
restart: always
networks:
- frontend
volumes:
nginx-cache:
networks:
frontend:14.3 Nginx 配置(Docker 版)
# nginx.conf
upstream app {
# Docker 服务名作为主机名
app:3000;
# 如果有多个副本
# app:3000 weight=1;
# app:3000 weight=1;
# app:3000 weight=1;
}
server {
listen 80;
server_name _;
# 健康检查端点
location /health {
return 200 'ok';
add_header Content-Type text/plain;
}
location / {
proxy_pass http://app;
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;
}
}十五、常见问题
Q1:502 Bad Gateway 怎么办?
原因:Nginx 无法连接到后端服务
排查步骤:
1. 检查后端服务是否运行
systemctl status myapp
curl http://localhost:3000/health
2. 检查 Nginx 错误日志
tail -f /var/log/nginx/error.log
3. 检查防火墙/安全组
iptables -L -n
4. 检查 SELinux
getenforce # 如果是 Enforcing,可能阻止了代理
setsebool -P httpd_can_network_connect 1Q2:504 Gateway Timeout 怎么办?
# 增加超时时间
location /api/ {
proxy_pass http://backend;
proxy_connect_timeout 60s;
proxy_send_timeout 120s;
proxy_read_timeout 120s;
}Q3:文件上传 413 错误?
# 增加上传文件大小限制
http {
client_max_body_size 50m; # 全局设置
}
server {
location /upload {
client_max_body_size 100m; # 特定路径设置
proxy_pass http://backend;
}
}Q4:配置不生效怎么办?
# 1. 检查配置语法
nginx -t
# 2. 重新加载
nginx -s reload
# 3. 检查是否真正重启
systemctl status nginx
# 4. 检查端口监听
ss -tlnp | grep nginx
# 5. 清除浏览器缓存或用 curl 测试
curl -I http://example.com/Q5:Nginx 性能怎么优化?
1. 调整 worker_processes 和 worker_connections
2. 开启 sendfile、tcp_nopush、tcp_nodelay
3. 开启 gzip 压缩
4. 配置缓存(proxy_cache 和浏览器缓存)
5. 使用 HTTP/2
6. 开启 keepalive 长连接
7. 优化 SSL/TLS 配置
8. 使用 open_file_cache
9. 调整系统参数(sysctl)
10. 监控和分析日志十六、总结
Nginx 配置检查清单
-
nginx -t配置语法正确 - 隐藏版本号
server_tokens off - 配置 HTTPS 和 HTTP 跳转
- 设置安全响应头
- 配置 Gzip 压缩
- 设置合理的超时
- 配置日志格式和轮转
- 设置访问控制和限流
- 配置缓存策略
- 配置错误页面
- 性能参数调优
- 设置监控和告警
Nginx 学习路径
入门(第1周):
→ 安装 Nginx
→ 配置静态网站
→ 理解配置文件结构
进阶(第2-3周):
→ 反向代理配置
→ 负载均衡
→ SSL/HTTPS 配置
→ 日志分析
高级(第1-2月):
→ 缓存配置
→ 限流和安全防护
→ WebSocket 代理
→ 性能调优
专家(第3月+):
→ 高可用(Keepalived)
→ 零停机部署
→ 动态配置
→ Lua 扩展(OpenResty)【相关推荐】
- Linux Shell 脚本与自动化运维完全指南 - 运维自动化
- VPS 性能优化完全指南 - 服务器调优
- Docker Compose 配置指南 - 容器编排
- VPS 安全加固完全指南 - 服务器安全
Nginx 是运维工程师和后端开发者的必修课。 掌握 Nginx,你就掌握了高性能 Web 服务的钥匙。从静态文件服务到大规模负载均衡,Nginx 都能优雅地胜任。🚀
