本文詳解Nginx反向代理原理、配置技巧和負載均衡策略,從入門到生產級實踐。
前言
Nginx是最流行的Web服務器和反向代理:
- 全球使用率超過30%
- 性能強悍,10萬+併發輕鬆
- 配置靈活,功能豐富
今天來深入講解Nginx反向代理和負載均衡的實戰配置。
一、反向代理基礎
1.1 什麼是反向代理
正向代理(代理客户端):
客户端 → 代理服務器 → 目標服務器
例如:FQ工具
反向代理(代理服務端):
客户端 → Nginx → 後端服務器
例如:網站負載均衡
1.2 反向代理的作用
|
功能
|
説明
|
|
負載均衡
|
分發請求到多台後端
|
|
SSL終結
|
統一處理HTTPS
|
|
緩存加速
|
緩存靜態資源
|
|
安全隔離
|
隱藏真實服務器
|
|
統一入口
|
多服務共用80/443端口
|
1.3 安裝Nginx
# Ubuntu/Debian
sudo apt update
sudo apt install nginx -y
# CentOS
sudo yum install epel-release -y
sudo yum install nginx -y
# 啓動
sudo systemctl start nginx
sudo systemctl enable nginx
# 驗證
curl http://localhost
二、基礎反向代理配置
2.1 最簡配置
# /etc/nginx/conf.d/proxy.conf
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
2.2 完整配置模板
server {
listen 80;
server_name example.com;
# 日誌
access_log /var/log/nginx/example_access.log;
error_log /var/log/nginx/example_error.log;
location / {
proxy_pass http://127.0.0.1:8080;
# 傳遞真實IP
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 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 緩衝設置
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
}
2.3 多服務代理
# 不同路徑代理到不同服務
server {
listen 80;
server_name example.com;
# 前端靜態文件
location / {
root /var/www/html;
try_files $uri $uri/ /index.html;
}
# API服務
location /api/ {
proxy_pass http://127.0.0.1:3000/;
}
# 管理後台
location /admin/ {
proxy_pass http://127.0.0.1:8000/;
}
# WebSocket
location /ws/ {
proxy_pass http://127.0.0.1:9000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
三、負載均衡
3.1 負載均衡策略
|
策略
|
説明
|
適用場景
|
|
輪詢(默認)
|
依次分發
|
服務器配置相同
|
|
加權輪詢
|
按權重分發
|
服務器配置不同
|
|
IP Hash
|
同IP固定後端
|
需要會話保持
|
|
Least Conn
|
最少連接優先
|
長連接場景
|
|
Fair
|
響應時間優先
|
需要第三方模塊
|
3.2 輪詢配置
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;
}
}
3.3 加權輪詢
upstream backend {
server 192.168.1.101:8080 weight=5; # 處理50%請求
server 192.168.1.102:8080 weight=3; # 處理30%請求
server 192.168.1.103:8080 weight=2; # 處理20%請求
}
3.4 IP Hash(會話保持)
upstream backend {
ip_hash;
server 192.168.1.101:8080;
server 192.168.1.102:8080;
server 192.168.1.103:8080;
}
3.5 最少連接
upstream backend {
least_conn;
server 192.168.1.101:8080;
server 192.168.1.102:8080;
server 192.168.1.103:8080;
}
3.6 健康檢查
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; # 備用服務器
}
# max_fails: 失敗次數閾值
# fail_timeout: 標記不可用時長
# backup: 主服務器都掛了才啓用
四、HTTPS配置
4.1 SSL證書配置
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優化
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;
ssl_session_timeout 10m;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
}
}
# HTTP跳轉HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
4.2 Let's Encrypt自動證書
# 安裝certbot
sudo apt install certbot python3-certbot-nginx -y
# 自動配置
sudo certbot --nginx -d example.com
# 自動續期
sudo certbot renew --dry-run
五、性能優化
5.1 Gzip壓縮
http {
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;
}
5.2 靜態文件緩存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
5.3 代理緩存
http {
# 定義緩存區
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m
max_size=1g inactive=60m use_temp_path=off;
}
server {
location / {
proxy_pass http://backend;
# 啓用緩存
proxy_cache my_cache;
proxy_cache_valid 200 60m;
proxy_cache_valid 404 1m;
proxy_cache_key "$scheme$request_method$host$request_uri";
# 緩存狀態頭
add_header X-Cache-Status $upstream_cache_status;
}
}
5.4 連接優化
http {
# 長連接
keepalive_timeout 65;
keepalive_requests 1000;
# upstream長連接
upstream backend {
server 127.0.0.1:8080;
keepalive 32;
}
}
六、跨網絡代理場景
6.1 常見場景
場景:公司有多個機房/分支,需要統一入口
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 總部機房 │ │ 分部A │ │ 分部B │
│ Nginx │ │ 後端服務 │ │ 後端服務 │
│ 192.168.1.1│ │192.168.2.10│ │192.168.3.10│
└─────────────┘ └─────────────┘ └─────────────┘
問題:各機房網絡不通,Nginx無法直接代理到分部服務器。
6.2 組網解決方案
使用組網軟件(如星空組網)打通網絡:
組網後:
┌─────────────┐
│ Nginx │
│ 10.10.0.1 │←─┐
└─────────────┘ │
│ 組網虛擬局域網
┌─────────────┐ │
│ 分部A │←─┤
│ 10.10.0.2 │ │
└─────────────┘ │
│
┌─────────────┐ │
│ 分部B │←─┘
│ 10.10.0.3 │
└─────────────┘
Nginx配置:
upstream all_servers {
server 10.10.0.1:8080; # 總部(組網IP)
server 10.10.0.2:8080; # 分部A(組網IP)
server 10.10.0.3:8080; # 分部B(組網IP)
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://all_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
效果:
- 多機房服務統一入口
- 負載均衡跨機房
- 故障自動切換
- 無需公網暴露各分部服務
6.3 按地域分流
# 根據用户IP分流到最近機房
upstream beijing {
server 10.10.0.1:8080;
}
upstream shanghai {
server 10.10.0.2:8080;
}
upstream guangzhou {
server 10.10.0.3:8080;
}
# 需要GeoIP模塊
map $geoip_city $backend {
default beijing;
"Shanghai" shanghai;
"Guangzhou" guangzhou;
}
server {
location / {
proxy_pass http://$backend;
}
}
七、安全配置
7.1 限流
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/ {
# 每秒10個請求,突發20個
limit_req zone=one burst=20 nodelay;
# 每IP最多100連接
limit_conn addr 100;
proxy_pass http://backend;
}
}
7.2 訪問控制
location /admin/ {
# 白名單
allow 192.168.1.0/24;
allow 10.10.0.0/24; # 組網IP段
deny all;
proxy_pass http://backend;
}
7.3 隱藏版本信息
http {
server_tokens off;
}
7.4 防盜鏈
location ~* \.(gif|jpg|png)$ {
valid_referers none blocked example.com *.example.com;
if ($invalid_referer) {
return 403;
}
}
八、監控與日誌
8.1 自定義日誌格式
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$upstream_addr $upstream_response_time $request_time';
access_log /var/log/nginx/access.log main;
}
8.2 狀態監控
server {
listen 8080;
location /nginx_status {
stub_status on;
allow 127.0.0.1;
allow 10.10.0.0/24; # 組網IP
deny all;
}
}
# 查看狀態
curl http://localhost:8080/nginx_status
Active connections: 42
server accepts handled requests
7368 7368 12345
Reading: 0 Writing: 5 Waiting: 37
8.3 日誌分析
# 統計請求數
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -20
# 統計狀態碼
awk '{print $9}' access.log | sort | uniq -c | sort -rn
# 慢請求分析
awk '$NF > 1 {print $0}' access.log
九、常見問題
9.1 502 Bad Gateway
# 後端服務未啓動或無法連接
# 檢查後端服務
curl http://127.0.0.1:8080
# 檢查Nginx錯誤日誌
tail -f /var/log/nginx/error.log
9.2 504 Gateway Timeout
# 增加超時時間
location / {
proxy_pass http://backend;
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}
9.3 配置檢查
# 檢查配置語法
nginx -t
# 重載配置
nginx -s reload
十、總結
Nginx反向代理配置要點:
- 基礎代理:proxy_pass + 必要的header
- 負載均衡:根據場景選擇策略
- 健康檢查:設置失敗閾值和備用服務器
- HTTPS:Let's Encrypt免費證書
- 性能優化:Gzip、緩存、長連接
- 跨網絡代理:組網打通多機房
- 安全加固:限流、訪問控制
生產環境建議:
- 配置健康檢查
- 啓用訪問日誌
- 配置合理的超時
- 使用HTTPS