Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Nginx 反向代理進階:動靜分離、proxy_cache 緩存、ngx_cache_purge 手動失效全實戰

編輯:Linux 教學

場景:Tomcat/Java 應用的前端加速架構

後端:Tomcat 8080 埠運行 Java Web 應用(動態 JSP/Servlet、靜態圖片/JS/CSS 混合)。
前端:Nginx 80 埠反向代理,實現:

  1. 動靜分離:靜態資源直接由 Nginx 服務,動態請求轉發 Tomcat。
  2. proxy_cache 緩存靜態資源:進一步降低 Tomcat 壓力,提升響應速度。
  3. ngx_cache_purge 手動失效:支援發布系統調用 API 精準清除緩存。

一、基礎反向代理配置

upstream tomcat_backend {
    server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
    keepalive 64;  # 連接複用
}

server {
    listen 80;
    server_name www.example.com;

    # 通用代理參數
    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_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Connection "";  # 清除 Connection 頭,配合 keepalive

    location / {
        proxy_pass https://tomcat_backend;
    }
}

二、動靜分離:三種實現模式對比

模式 A:子域名分離(推薦,架構最清晰)

# 靜態資源域名
server {
    listen 80;
    server_name static.example.com;
    root /var/www/static;  # 直接服務本地靜態文件
    expires 30d;
    add_header Cache-Control "public, immutable";
}

# 動態應用域名
server {
    listen 80;
    server_name www.example.com;
    location / {
        proxy_pass https://tomcat_backend;
    }
}
# 前端頁面引用:

模式 B:同域名下基於副檔名分離(無需改前端代碼)

server {
    listen 80;
    server_name www.example.com;

    # 靜態資源直接服務
    location ~* \.(gif|jpg|jpeg|png|bmp|swf|css|js|ico|woff2?|svg)$ {
        root /var/www/app;  # 需同步 Tomcat 靜態資源到此目錄
        expires 30d;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # 動態請求代理
    location / {
        proxy_pass https://tomcat_backend;
    }
}

模式 C:同域名下基於目錄前綴分離(規範化部署)

# Tomcat 部署時將靜態資源放入 /static 目錄
location /static/ {
    alias /var/www/app/static/;  # 注意 alias 末尾斜槿
    expires 30d;
    add_header Cache-Control "public, immutable";
    access_log off;
}

location / {
    proxy_pass https://tomcat_backend;
}

三、proxy_cache 緩存靜態資源(模式 B/C 進階)

若靜態資源無法同步到 Nginx 本地(如多台 Tomcat、動態生成的圖表),需代理緩存:

# http 上下文
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=tomcat_cache:100m inactive=7d max_size=20g use_temp_path=off;
proxy_temp_path /data/nginx/tmp;  # 必須同檔案系統

server {
    listen 80;
    server_name www.example.com;

    # 靜態資源:代理緩存
    location ~* \.(gif|jpg|jpeg|png|bmp|swf|css|js|ico|woff2?|svg)$ {
        proxy_cache tomcat_cache;
        proxy_cache_key "$scheme$request_method$host$request_uri$args";
        proxy_cache_valid 200 302 30d;
        proxy_cache_valid 404 1m;
        proxy_cache_min_uses 1;
        proxy_cache_methods GET HEAD;
        proxy_pass https://tomcat_backend;
        # 繼承通用 proxy_set_header
        expires 30d;  # 給客戶端瀏覽器緩存頭
    }

    # 動態請求:不緩存
    location / {
        proxy_cache off;
        proxy_pass https://tomcat_backend;
    }

    # 手動清除緩存
    location ~ /purge(/.*) {
        allow 10.0.0.0/8;
        allow 127.0.0.1;
        deny all;
        proxy_cache_purge tomcat_cache "$scheme$request_method$host$1$is_args$args";
    }
}

四、ngx_cache_purge 模組編譯與使用

1. 編譯安裝

# 下載模組
git clone https://github.com/FRiCKLE/ngx_cache_purge.git /usr/local/src/ngx_cache_purge

# 重新編譯 Nginx(保持原有參數,新增 --add-module)
cd /usr/local/src/nginx-1.24.0
./configure --prefix=/usr/local/nginx \
            --user=www --group=www \
            --with-http_ssl_module \
            --with-http_v2_module \
            --with-http_gzip_static_module \
            --add-module=/usr/local/src/ngx_cache_purge \
            ...(其他原有參數)
make && make install

# 平滑升級
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
sleep 2
kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`

2. PURGE API 使用

# 清除單個 URL 緩存
curl -X PURGE https://www.example.com/static/logo.png
# 或 GET 請求(配置支援)
curl https://www.example.com/purge/static/logo.png

# 批量清除(需 Lua 腳本或外部腳本遍歷)
# 例:清除 /static/ 目錄下所有
# 需配合 ngx_cache_purge 進階版或第三方模組

3. 發布系統整合範例

#!/bin/bash
# deploy.sh 片段
rsync -avz /build/static/ web1:/var/www/app/static/
rsync -avz /build/static/ web2:/var/www/app/static/

# 通知所有 Nginx 節點清除緩存
for nginx in nginx1 nginx2 nginx3; do
    ssh $nginx "curl -s -X PURGE https://localhost/purge/static/ >/dev/null"
done

五、防盜鏈與 404 佔位圖

location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ {
    valid_referers none blocked *.example.com example.com;
    if ($invalid_referer) {
        rewrite ^ /403.jpg break;
    }

    # 文件不存在返回預設圖
    if (!-f $request_filename) {
        rewrite ^ /404.jpg last;
    }

    expires 30d;
    proxy_cache tomcat_cache;
    proxy_pass https://tomcat_backend;
}

location = /403.jpg { root /var/www/app; access_log off; }
location = /404.jpg { root /var/www/app; access_log off; }

六、完整生產級配置匯總

# http 上下文
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=app_cache:200m inactive=30d max_size=100g use_temp_path=off;
proxy_temp_path /data/nginx/tmp;
proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args";
proxy_cache_valid 200 302 30d;
proxy_cache_valid 404 1m;
proxy_cache_min_uses 1;
proxy_cache_methods GET HEAD;

upstream tomcat_backend {
    server 127.0.0.1:8080 weight=3 max_fails=3 fail_timeout=30s;
    server 10.0.1.2:8080 weight=2 max_fails=3 fail_timeout=30s;
    keepalive 128;
}

server {
    listen 80;
    server_name www.example.com;

    # 通用代理參數
    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_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Connection "";

    # 靜態資源:代理緩存 + 防盜鏈 + 404 佔位
    location ~* \.(gif|jpg|jpeg|png|bmp|swf|css|js|ico|woff2?|svg)$ {
        valid_referers none blocked *.example.com example.com;
        if ($invalid_referer) { rewrite ^ /403.jpg break; }
        if (!-f $request_filename) { rewrite ^ /404.jpg last; }

        proxy_cache app_cache;
        proxy_pass https://tomcat_backend;
        expires 30d;
        add_header X-Cache-Status $upstream_cache_status;
    }

    # 動態應用:不緩存
    location / {
        proxy_cache off;
        proxy_pass https://tomcat_backend;
    }

    # 手動清除
    location ~ /purge(/.*) {
        allow 10.0.0.0/8; allow 127.0.0.1; deny all;
        proxy_cache_purge app_cache "$scheme$request_method$host$1$is_args$args";
    }

    # 佔位圖
    location = /403.jpg { root /var/www/app; internal; }
    location = /404.jpg { root /var/www/app; internal; }
}

七、關鍵避坑指南

坑點現象解決
proxy_temp_path 與 proxy_cache_path 不在同一檔案系統緩存寫入失敗,日誌 rename() failed: Invalid cross-device link兩者必須同掛載點,或設 use_temp_path=off(Nginx 1.7+)直接寫入緩存目錄
proxy_cache_key 缺少 $args不同查詢參數返回同一緩存(如 /api?page=1 和 ?page=2 內容相同)鍵中包含 $is_args$args
動態頁面被誤緩存用戶看到他人個人資訊、購物車混亂proxy_cache_off 或 proxy_no_cache $cookie_sessionid 精準排除
PURGE 請求被緩存清除 API 本身被緩存,導致後續 PURGE 失效location /purge { proxy_cache off; ... }
防盜鏈誤殺正常引用自家 App/WebView/郵件客戶端無 Referer 被擋valid_referers none blocked ... 允許無 Referer

總結

Nginx 反向代理進階三部曲:動靜分離(架構層) → proxy_cache 緩存(效能層) → ngx_cache_purge 失效(運維層)。掌握三種分離模式適用場景、緩存鍵設計原則、手動失效整合發布流程、防盜鏈與佔位圖細節,即可構建高性能、可運維、安全可控的 Java Web 前端加速層。

Copyright © Windows教程網 All Rights Reserved