熱門分類
載入中…
目錄0%

🌐 Nginx 反向代理進階篇:多站點、Rewrite 規則、Proxy Cache 完整教學

    🌐 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.comblog.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 參數提升連線能力

    🔗 延伸閱讀

    — WWFandy・Nginx 反代架構筆記

    🔗 分享這篇 LINE Facebook X

    沒有留言:

    字級