🌐 Nginx 反向代理進階篇:多站點、Rewrite 規則、Proxy Cache 完整教學
在你已經具備基本 Nginx Reverse Proxy 能力後,下一步就是深入「進階反代架構」:多站點代理、Rewrite URL 規則、Proxy Cache 靜態加速、健康檢查與後端錯誤處理等。 本文完整整理企業與大型網站常用的 Nginx 反代技巧,從基礎架構圖、設定範例到最佳化參數全都涵蓋。 這篇文章適合已經部署基本反代、想讓網站更快、更穩、更可維運的你。
一、反向代理的完整工作流程圖
理解 Nginx 作為 Reverse Proxy 的角色,有助於配置更加正確:
[Client] → HTTPS → [Nginx Reverse Proxy] → HTTP/HTTPS → [Backend Web App]
│
└─> SSL/TLS Termination(Nginx)
├─ URL Rewrite
├─ Load Balancing(選擇性)
├─ Header 改寫(Host / X-Forwarded-For)
├─ Proxy Cache(靜態/動態頁面加速)
└─ Error Handling(502/504 重試)
Nginx 的價值就在於「抽象化後端」,並在中間層提供加速、安全、監控與彈性部署。
二、多站點反代(Multi-Site Reverse Proxy)
當你想在一台 Nginx 上代理多個後端站點,可以使用 server_name 分流。
2-1. 多網域反代範例
# /etc/nginx/sites-available/multi-proxy.conf
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://10.10.0.10:8080;
include proxy_params;
}
}
server {
listen 80;
server_name blog.example.com;
location / {
proxy_pass http://10.10.0.20:8000;
include proxy_params;
}
}
如此一來 api.example.com 與 blog.example.com 的流量就能分別反代至不同後端。
2-2. 子路徑反代(Path-based Reverse Proxy)
若你想以子路徑作區隔(例如 /api、/app):
server {
listen 80;
server_name example.com;
location /api/ {
proxy_pass http://10.10.0.10:8080/;
include proxy_params;
}
location /app/ {
proxy_pass http://10.10.0.20:9000/;
include proxy_params;
}
}
注意 proxy_pass 結尾是否包含 /,會影響 URL 對應方式,是反代常見踩雷。
三、URL Rewrite 實務:最容易搞錯也最常用的功能
Rewrite 是 Nginx 用於 URL 改寫、跳轉與後端路徑調整的重要工具。
3-1. 常見跳轉需求:HTTP → HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
3-2. 移除 URL 結尾斜線
rewrite ^/(.*)/$ /$1 permanent;
3-3. 保留 query string 的 rewrite(非常重要)
rewrite ^/old/(.*)$ /new/$1 last;
若用 ? 結尾會清除 query string,務必注意:
rewrite ^/old/(.*)$ /new/$1? last; # ← query string 會被清掉
3-4. 前端 SPA(Vue/React)導向 index.html
location / {
try_files $uri $uri/ /index.html;
}
四、Proxy Cache:讓反代伺服器變成加速器
Nginx 的 proxy_cache 可以有效降低後端負載,適用:
- 靜態 API 結果(如查詢清單、排行榜)
- 高 QPS 的圖片/縮圖服務
- 第三方 API 緩存
4-1. 建立 Cache 區域
# 在 http {} 區塊內
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:50m inactive=30m max_size=5g;
說明:
- keys_zone=mycache:50m:儲存快取索引的共享記憶體大小。
- inactive=30m:無人存取後多少時間自動刪除。
- max_size=5g:整體快取上限。
4-2. 在反代 server 中啟用 cache
location /api/ {
proxy_cache mycache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_pass http://10.10.0.10:8080;
}
這代表:
- 200/302 回應快取 10 分鐘
- 404 回應快取 1 分鐘(避免大量無效查詢)
4-3. 避免快取登入資料(Cookie 過濾)
常見安全需求:登入後不能快取。
proxy_cache_bypass $http_authorization $cookie_sessionid;
proxy_no_cache $http_authorization $cookie_sessionid;
五、提升後端穩定性:重試、超時、緩衝區隊列
5-1. 設定 Proxy 超時值
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
proxy_send_timeout 30s;
proxy_buffering on;
5-2. 反代重試(避免短暫 502)
proxy_next_upstream error timeout invalid_header http_502 http_503 http_504;
proxy_next_upstream_tries 3;
當後端短暫掛掉,Nginx 可嘗試重新連線,讓前端不會立即 502。
六、負載平衡快速設定(Round Robin / Least Conn)
Nginx 內建 upstream 負載平衡:
6-1. Round-Robin
upstream backend {
server 10.10.0.10;
server 10.10.0.11;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
6-2. Least Connections(適合 API)
upstream backend {
least_conn;
server 10.10.0.10;
server 10.10.0.11;
}
6-3. 健康檢查(被動檢查)
proxy_next_upstream error timeout http_502 http_503;
七、安全性設定:Header、XFF、限制大小、黑名單
7-1. 設定真實訪客 IP(X-Forwarded-For)
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
7-2. 限制上傳大小
client_max_body_size 20M;
7-3. 封鎖惡意 UA
if ($http_user_agent ~* (badbot|crawler|scanner)) {
return 403;
}
八、完整範例:前端 + 多站點 + Cache + Rewrite 整合配置
# /etc/nginx/sites-available/full-reverse-proxy.conf
upstream api_backend {
least_conn;
server 10.10.0.10;
server 10.10.0.11;
}
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:50m inactive=30m max_size=10g;
server {
listen 80;
server_name api.example.com;
# 強制 HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
location /v1/ {
rewrite ^/v1/(.*)$ /api/$1 last;
}
location /api/ {
proxy_pass http://api_backend;
# Header
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Cache
proxy_cache mycache;
proxy_cache_valid 200 10m;
proxy_cache_use_stale error timeout invalid_header updating;
}
}
這是一個真實企業常用架構,可支援高流量、高效率的 API 服務。
九、問題排查:502、504、rewrite 錯誤的常見原因
9-1. 反代 URL 錯位
# 錯誤(多一層路徑)
proxy_pass http://10.0.0.1/api/;
# 正確
proxy_pass http://10.0.0.1/;
9-2. 後端無法接收 Host
部分後端需要正確 Host header:
proxy_set_header Host $host;
9-3. 因後端延遲造成 504
proxy_read_timeout 30s; # 依需求調整
9-4. Cache 未生效
- 後端回應 header 設定
Cache-Control: no-store - cookie 未忽略,造成 cache bypass
十、部署建議:如何讓你的 Nginx 架構更長久可維護?
- 分離設定檔(upstream / server / rewrite 各自獨立)
- 使用 include proxy_params 簡化重複設定
- 建立 Health Check 機制避免後端故障造成大規模 502
- proxy_cache 填滿時要調整 max_size,避免 I/O 滿載
- 使用 systemd 設定 limit 參數提升連線能力
🔗 延伸閱讀
- 🌐 Nginx 反向代理與 HTTPS 完整教學
- 🐧 Linux 防火牆整合:Firewalld / iptables / nftables
- 📜 Systemd + Logrotate 整合教學
- 🧱 Linux 安全性完整指南:SELinux / AppArmor / Auditd 解析
- 🧩 Linux 檔案系統比較:ext4 vs XFS vs Btrfs vs ZFS
— WWFandy・Nginx 反代架構筆記
沒有留言: