📚 前言
Nginx(发音:engine-x)是一个高性能的 Web 服务器、反向代理服务器和负载均衡器。全球超过 30% 的网站使用 Nginx,包括 Netflix、Airbnb、GitHub 等大型网站。
🎯 Nginx 能做什么?
| 功能 |
说明 |
| 静态文件服务 |
直接返回 HTML、CSS、JS、图片等 |
| 反向代理 |
转发请求到后端服务器 |
| 负载均衡 |
将请求分发到多台服务器 |
| HTTPS 证书 |
配置 SSL/TLS 加密 |
| 缓存 |
缓存后端响应,提升性能 |
| Gzip 压缩 |
压缩响应内容,减少传输 |
| 限流 |
限制请求速率,防止攻击 |
🔧 安装 Nginx
Ubuntu/Debian
1 2 3 4 5 6 7 8 9
| sudo apt update sudo apt install nginx
sudo systemctl start nginx sudo systemctl enable nginx
sudo systemctl status nginx
|
CentOS/RHEL
1 2 3 4 5
| sudo yum install epel-release sudo yum install nginx
sudo systemctl start nginx sudo systemctl enable nginx
|
macOS
1 2 3 4
| brew install nginx
brew services start nginx
|
Docker
1
| docker run -d -p 80:80 nginx
|
📁 目录结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| /etc/nginx/ ├── nginx.conf # 主配置文件 ├── conf.d/ # 自定义配置目录 │ └── default.conf ├── sites-available/ # 可用站点配置 ├── sites-enabled/ # 已启用站点(软链接) ├── mime.types # MIME 类型映射 └── modules-enabled/ # 已启用模块
/var/log/nginx/ ├── access.log # 访问日志 └── error.log # 错误日志
/var/www/html/ # 默认网站根目录
|
📝 配置文件结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
user nginx; worker_processes auto; error_log /var/log/nginx/error.log;
events { worker_connections 1024; }
http { include /etc/nginx/mime.types;
server { listen 80; server_name example.com;
location / { root /var/www/html; index index.html; } } }
|
配置层级
1 2 3 4 5
| 全局块(main) ├── events 块 → 连接处理 └── http 块 → HTTP 服务 └── server 块 → 虚拟主机 └── location 块 → URL 匹配规则
|
🌐 基础配置
1. 静态网站
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| server { listen 80; server_name example.com www.example.com;
root /var/www/example; index index.html index.htm;
location / { try_files $uri $uri/ =404; }
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ { expires 30d; add_header Cache-Control "public, immutable"; } }
|
2. 配置 HTTPS(SSL)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| server { listen 443 ssl http2; server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m;
root /var/www/example; index index.html; }
server { listen 80; server_name example.com; return 301 https://$host$request_uri; }
|
3. 使用 Let’s Encrypt 免费证书
1 2 3 4 5 6 7 8
| sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
sudo certbot renew --dry-run
|
🔄 反向代理
什么是反向代理?
1 2 3 4 5 6 7
| 正向代理(VPN):代理客户端(帮你访问) 客户端 → 代理服务器 → 目标服务器 (客户端知道代理,服务器不知道客户端,代理站在你这边,帮你出去)
反向代理:代理服务器(帮服务器接客) 客户端 → Nginx → 后端服务器 (客户端不知道后端,只知道 Nginx,代理站在服务器这边,帮服务器接客)
|
| 类型 |
代理谁 |
隐藏谁 |
例子 |
| 正向代理 |
客户端 |
隐藏客户端 |
VPN、科学上网 |
| 反向代理 |
服务器 |
隐藏服务器 |
Nginx、CDN |
基础反向代理
1 2 3 4 5 6 7 8 9 10 11 12 13
| server { listen 80; server_name api.example.com;
location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; 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
1 2 3 4 5 6 7 8
| location /ws { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_read_timeout 86400; }
|
前后端分离部署
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| server { listen 80; server_name example.com;
location / { root /var/www/frontend/dist; index index.html; try_files $uri $uri/ /index.html; }
location /api/ { proxy_pass http://localhost:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
location /static/ { alias /var/www/static/; expires 30d; } }
|
⚖️ 负载均衡
基础配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| upstream backend { server 192.168.1.101:8080; server 192.168.1.102:8080; server 192.168.1.103:8080; }
server { listen 80; server_name example.com;
location / { proxy_pass http://backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
|
负载均衡策略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| upstream backend { server 192.168.1.101:8080; server 192.168.1.102:8080; }
upstream backend { server 192.168.1.101:8080 weight=3; server 192.168.1.102:8080 weight=2; }
upstream backend { ip_hash; server 192.168.1.101:8080; server 192.168.1.102:8080; }
upstream backend { least_conn; server 192.168.1.101:8080; server 192.168.1.102:8080; }
upstream backend { server 192.168.1.101:8080 max_fails=3 fail_timeout=30s; server 192.168.1.102:8080 max_fails=3 fail_timeout=30s; server 192.168.1.103:8080 backup; }
|
负载均衡策略对比
| 策略 |
说明 |
适用场景 |
| 轮询 |
依次分发 |
服务器性能相近 |
| 权重 |
按权重分发 |
服务器性能不同 |
| IP Hash |
同 IP 固定服务器 |
需要会话保持 |
| 最少连接 |
分给最空闲的 |
请求处理时间差异大 |
🗂️ location 匹配规则
匹配语法
1 2 3
| location [ = | ~ | ~* | ^~ ] uri { }
|
| 符号 | 说明 | 示例 |
| —- | ———————— | ———————- | —— |
| = | 精确匹配 | location = /api |
| ^~ | 前缀匹配(优先) | location ^~ /static/ |
| ~ | 正则匹配(区分大小写) | location ~ \.php$ |
| ~* | 正则匹配(不区分大小写) | location ~\* \.(jpg | png)$ |
| 无 | 前缀匹配 | location /api/ |
匹配优先级
1 2 3 4
| 1. = 精确匹配(最高) 2. ^~ 前缀匹配 3. ~ 或 ~* 正则匹配(按配置顺序) 4. 普通前缀匹配(最长匹配)
|
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| server { location = / { root /var/www/html; index index.html; }
location ^~ /static/ { alias /var/www/static/; expires 30d; }
location ~* \.(jpg|jpeg|png|gif|ico|svg)$ { root /var/www/images; expires 7d; }
location /api/ { proxy_pass http://localhost:8080/; }
location / { root /var/www/app; try_files $uri $uri/ /index.html; } }
|
⚡ 性能优化
1. Gzip 压缩
1 2 3 4 5 6 7 8 9
| http { gzip on; gzip_vary on; gzip_min_length 1024; gzip_comp_level 6; gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml; }
|
2. 缓存配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| location ~* \.(css|js)$ { expires 1y; add_header Cache-Control "public, immutable"; }
location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ { expires 30d; add_header Cache-Control "public"; }
location ~* \.html$ { expires -1; add_header Cache-Control "no-cache, no-store, must-revalidate"; }
|
3. 连接优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| http { keepalive_timeout 65; keepalive_requests 100;
sendfile on; tcp_nopush on; tcp_nodelay on;
client_body_buffer_size 16k; client_max_body_size 100m;
client_body_timeout 12; client_header_timeout 12; send_timeout 10; }
|
4. 代理缓存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| http { proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m;
server { location /api/ { proxy_pass http://backend; proxy_cache my_cache; proxy_cache_valid 200 10m; proxy_cache_valid 404 1m; add_header X-Cache-Status $upstream_cache_status; } } }
|
🔒 安全配置
1. 隐藏版本号
1 2 3
| http { server_tokens off; }
|
2. 安全响应头
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| server { add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Strict-Transport-Security "max-age=31536000" always;
add_header Content-Security-Policy "default-src 'self'" always; }
|
3. 限制请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| http { limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; limit_conn_zone $binary_remote_addr zone=addr:10m;
server { location /api/ { limit_req zone=one burst=20 nodelay; limit_conn addr 10; proxy_pass http://backend; } } }
|
4. IP 黑白名单
1 2 3 4 5 6 7 8
| location /admin/ { allow 192.168.1.0/24; allow 10.0.0.1; deny all;
proxy_pass http://localhost:8080; }
|
5. 防止目录遍历
1 2 3
| location / { autoindex off; }
|
📊 日志配置
自定义日志格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 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 json escape=json '{' '"time":"$time_iso8601",' '"ip":"$remote_addr",' '"method":"$request_method",' '"uri":"$request_uri",' '"status":$status,' '"size":$body_bytes_sent,' '"referer":"$http_referer",' '"ua":"$http_user_agent",' '"rt":$request_time' '}';
access_log /var/log/nginx/access.log main; access_log /var/log/nginx/access.json json; }
|
按条件记录日志
1 2 3 4 5 6 7
| location ~* \.(css|js|png|jpg|gif|ico)$ { access_log off; }
access_log /var/log/nginx/access.log combined if=$loggable;
|
🛠️ 常用命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| nginx -t
nginx -s reload
nginx -s stop nginx -s quit
nginx -v nginx -V
ps aux | grep nginx
netstat -tlnp | grep nginx
|
🐛 常见问题
1. 502 Bad Gateway
1 2 3 4 5 6 7
| 原因:后端服务未启动或不可达
排查: 1. 检查后端服务是否运行 2. 检查 proxy_pass 地址是否正确 3. 检查防火墙是否放行 4. 查看 error.log
|
2. 504 Gateway Timeout
1 2 3 4 5 6 7
| location /api/ { proxy_pass http://backend; proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; }
|
3. 413 Request Entity Too Large
1 2 3 4
| http { client_max_body_size 100m; }
|
4. 跨域问题
1 2 3 4 5 6 7 8 9 10 11 12
| location /api/ { add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always; add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
if ($request_method = OPTIONS) { return 204; }
proxy_pass http://backend; }
|
📋 实战配置模板
完整的生产环境配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
| user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid;
events { worker_connections 4096; 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" $request_time'; 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_comp_level 6; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
server_tokens off;
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
upstream backend { least_conn; server 127.0.0.1:3001 weight=2; server 127.0.0.1:3002 weight=1; keepalive 32; }
server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; }
server { listen 443 ssl http2; server_name example.com www.example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m;
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 Strict-Transport-Security "max-age=31536000" always;
location / { root /var/www/frontend/dist; index index.html; try_files $uri $uri/ /index.html;
location ~* \.(css|js)$ { expires 1y; add_header Cache-Control "public, immutable"; }
location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ { expires 30d; } }
location /api/ { limit_req zone=api burst=20 nodelay;
proxy_pass http://backend/; proxy_http_version 1.1; 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 Connection "";
proxy_connect_timeout 30s; proxy_send_timeout 30s; proxy_read_timeout 30s; }
location /ws/ { proxy_pass http://backend/ws/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 86400; } } }
|
🎯 总结
核心功能
| 功能 |
关键配置 |
| 静态服务 |
root, index, try_files |
| 反向代理 |
proxy_pass, proxy_set_header |
| 负载均衡 |
upstream, weight, ip_hash |
| HTTPS |
ssl_certificate, ssl_protocols |
| 缓存 |
expires, proxy_cache |
| 压缩 |
gzip on |
| 限流 |
limit_req_zone, limit_conn_zone |
记忆口诀
Nginx 三大能力:静态服务、反向代理、负载均衡
性能三件套:Gzip、缓存、长连接
安全三要素:HTTPS、限流、安全头
📚 相关资源