在 Nginx 中配置負載均衡,主要是通過 upstream 模塊來定義一組後端服務器,並選擇合適的負載均衡算法,然後在 location 塊中通過 proxy_pass 指令將請求轉發給這個服務器組。
下面這個表格整理了 Nginx 常用的負載均衡算法,你可以根據業務場景快速選擇。
|
算法名稱 |
配置指令 |
核心邏輯 |
適用場景 |
|
輪詢 (Round Robin) |
默認,無需配置
|
請求按時間順序逐一分配到不同後端服務器。 |
後端服務器性能相近的無狀態服務。 |
|
加權輪詢 (Weighted Round Robin) |
|
在輪詢基礎上,通過權重決定服務器接收請求的比例。 |
後端服務器性能不均,希望高性能服務器處理更多請求。 |
|
IP哈希 (IP Hash) |
|
根據客户端IP的哈希值分配請求,同一IP的請求總是發往同一台服務器。 |
需要會話保持 (session persistence) 的場景,如用户登錄狀態。 |
|
最少連接 (Least Connections) |
|
將新請求分配給當前活躍連接數最少的服務器。 |
後端服務器處理請求的耗時長短不一,希望實現更公平的負載,如長連接應用。 |
|
URL哈希 (URL Hash) |
|
根據請求URL的哈希值分配請求,同一URL的請求總是發往同一台服務器。 |
主要為了提高後端緩存命中率,需要安裝第三方模塊。 |
|
Fair (響應時間) |
|
根據後端服務器的響應時間來分配請求,響應時間短的優先分配。 |
後端服務器性能波動較大,希望更智能地進行負載,需要安裝第三方模塊。 |
⚙️ 一、如何配置負載均衡
以下是配置 Nginx 負載均衡的基本步驟和一個配置示例。
基本步驟
- 安裝 Nginx:確保你的服務器上已經安裝了 Nginx。
- 編輯配置文件:打開 Nginx 的配置文件,通常位於
/etc/nginx/nginx.conf或/etc/nginx/conf.d/default.conf。 - 添加 Upstream 塊:在
http塊內,使用upstream指令定義一個後端服務器組。 - 配置代理轉發:在
server塊下的location中,使用proxy_pass指令指向 upstream 組的名稱。 - 檢查並重啓:執行
sudo nginx -t測試配置語法是否正確,然後使用sudo systemctl restart nginx重啓 Nginx 使配置生效。
配置示例
以下是一個結合了加權輪詢和最少連接算法的配置示例,幷包含了一些常用的反向代理參數。
http {
upstream backend_servers {
# 使用'least_conn'最少連接算法
least_conn;
# 定義後端服務器列表並設置權重
server backend1.example.com weight=3;
server backend2.example.com weight=2;
server backend3.example.com weight=1;
# 可選的服務器狀態參數
# server backup.example.com backup; # 標記為備份服務器,其他服務器不可用時才啓用
# server down.example.com down; # 標記為永久停機
}
server {
listen 80;
server_name yourdomain.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;
}
}
}
- 服務器健康檢查:Nginx 開源版默認只支持被動的健康檢查(當請求失敗時標記服務器不可用)。更強大的主動健康檢查功能需要 Nginx Plus 或第三方模塊(如
ngx_http_upstream_check_module)來實現。 - 會話保持:如果選擇了
ip_hash算法,需要注意當後端服務器宕機或增刪時,哈希結果可能會改變,影響會話一致性。此外,ip_hash與backup參數不能同時配置。 - 故障轉移:可以使用
proxy_next_upstream指令定義在何種情況下(如超時、後端返回500錯誤等)將請求轉發到下一台服務器,從而實現故障轉移。
2.1 存在的問題以及解決方案
1.解決會話一致性問題
問題描述:
- 用户登錄狀態丟失(會話數據存儲在後端實例內存中)
- 購物車內容不一致
- 表單重複提交
解決方案:
# 方法1:IP Hash策略(簡單但不完美)
upstream backend_servers {
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
# 方法2:Cookie-based會話保持(Nginx Plus)
upstream backend_servers {
sticky cookie srv_id expires=1h domain=.example.com path=/;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
更好的解決方案:
- 使用Redis/Memcached等外部會話存儲
- 採用JWT等無狀態身份驗證
2. 文件上傳與存儲一致性問題
問題描述:
用户上傳的文件只存在於某個特定實例
後續請求可能被路由到沒有該文件的實例
# 使用共享存儲方案
# 1. 網絡文件系統(NFS)
mount -t nfs 192.168.1.100:/shared_storage /app/uploads
# 2. 對象存儲(推薦)
# 直接使用AWS S3、阿里雲OSS等雲服務
3. 配置管理與一致性
問題描述:
- 不同實例配置不一致
- 環境變量差異
- 代碼版本不同步
這裏解決方案是使用docker構建應用。
# 使用Docker + 配置管理工具
version: '3'
services:
app:
image: your-app:${VERSION}
environment:
- DATABASE_URL=${DB_URL}
- REDIS_URL=${REDIS_URL}
volumes:
- shared_uploads:/app/uploads
4. 數據庫連接瓶頸
問題描述:
-- 每個應用實例都創建數據庫連接
-- 可能導致數據庫連接數爆滿
SHOW PROCESSLIST; -- 查看當前連接數
解決方案:
# 連接池優化 + 數據庫代理
upstream backend_servers {
server 192.168.1.10:8080 max_conns=100; # 限制單個實例最大連接數
server 192.168.1.11:8080 max_conns=100;
# 使用最少連接策略分散負載
least_conn;
}
5. 健康檢查與故障轉移
問題描述:
- 殭屍實例繼續接收流量
- 故障轉移不及時
- 雪崩效應
解決方案:
upstream backend_servers {
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
# 主動健康檢查(Nginx Plus)
# health_check interval=5s fails=3 passes=2;
}
server {
location / {
proxy_pass http://backend_servers;
# 增強故障轉移配置
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
proxy_next_upstream_tries 2;
proxy_next_upstream_timeout 10s;
}
}
6. 緩存一致性問題
問題描述:
- 本地緩存不一致
- 緩存失效策略難以同步
解決方案:
# 使用分佈式緩存
upstream backend_servers {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
# 在Nginx層面添加統一緩存
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m;
server {
location / {
proxy_pass http://backend_servers;
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
}
}
7. 日誌收集與監控困難
問題描述:
- 日誌分散在不同實例
- 問題排查困難
- 性能監控不全面
解決方案:
# 統一的日誌格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'upstream: $upstream_addr response_time: $upstream_response_time';
access_log /var/log/nginx/access.log main;
8. SSL/TLS終止性能問題
問題描述:
- SSL加解密消耗CPU資源
- 影響Nginx性能
解決方案:
# 在Nginx終止SSL,後端使用HTTP
server {
listen 443 ssl;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://backend_servers; # 注意是http://
}
}
完整的解決方案:
http {
# 分佈式會話存儲
upstream redis_cluster {
server 192.168.1.50:6379;
server 192.168.1.51:6379;
}
# 應用集羣
upstream app_cluster {
least_conn;
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
keepalive 32;
}
server {
listen 80;
# 靜態資源直接由Nginx處理
location /static/ {
alias /shared_storage/static/;
expires 1y;
add_header Cache-Control "public, immutable";
}
# API請求負載均衡
location /api/ {
proxy_pass http://app_cluster;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 故障轉移配置
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
}
# 健康檢查端點
location /health {
access_log off;
proxy_pass http://app_cluster/health;
}
}
}
希望這份指南能幫助你順利配置 Nginx 負載均衡。如果你能分享一下你計劃使用負載均衡的具體業務場景,或許我能給你提供更具體的算法選型建議。