🤖 作者簡介:水煮白菜王,一位前端勸退師 👻
👀 文章專欄: 前端專欄 ,記錄一下平時在博客寫作中,總結出的一些開發技巧和知識歸納總結?。
感謝支持💕💕💕
目錄
- 單體節點部署
- Nginx反向代理-負載均衡
- 1.示例
- 2.Nginx conf配置(負載均衡)
- 3.Nginx請求分發原理:
- Nginx動靜分離
- 1.什么是動靜分離?
- 2.一個真實場景:訪問淘寶首頁
- 3.動靜分離的核心
- 4.Nginx操作
- Nginx資源壓縮
- Nginx緩沖區
- Nginx緩存機制
- **? 緩存清理**
- 1. 安裝 ngx_cache_purge
- 2. 配置 ngx_cache_purge
- 緩存命中率如何監控?
- 使用日志分析工具:
- 緩存穿透、緩存雪崩、緩存擊穿的解決方案
- 1.緩存穿透
- 2.緩存雪崩
- 3. 緩存擊穿
- Nginx實現IP黑白名單
- Nginx跨域配置
- Nginx防盜鏈設計
- Nginx大文件傳輸配置
- 如果你覺得這篇文章對你有幫助,請點贊 👍、收藏 👏 并關注我!👀
單體節點部署
在傳統的單體架構中,Nginx 通常以單一節點的形式運行,作為 Web 服務器或反向代理服務器。這種部署方式簡單易用,適合小型項目或開發測試環境。
類型 | 描述 |
---|---|
? 優點 | - 部署簡單,配置方便 - 成本低,資源占用少 - 維護成本較低 |
? 缺點 | - 無法承載高并發流量:隨著業務的發展和用戶量的增長,單體結構難以應對日益增長的訪問壓力,容易成為性能瓶頸 - 存在單點故障風險:一旦后端服務節點宕機或 Nginx 本身出現異常,整個系統將無法對外提供服務,導致業務中斷 |
因此,在生產環境中,建議采用更加高可用、可擴展的部署方案,如負載均衡集群。
Nginx反向代理-負載均衡
為提升系統的可用性和處理能力,可以使用 Nginx 搭配多個后端應用服務器,實現 反向代理 + 負載均衡 的架構設計。
1.示例
通過一個簡單的 Spring Boot 應用來展示不同實例的響應結果。
@Controller
public class IndexNginxController {@Value("${server.port}")private String port;@RequestMapping("/")public ModelAndView index() {ModelAndView model = new ModelAndView();model.addObject("port", port);model.setViewName("index");return model;}
}
在該Controller類中,存在一個成員變量:port,它的值即是從application.properties配置文件中獲取server.port
值。當出現訪問/資源的請求時,跳轉前端index頁面,并將該值攜帶返回。
前端模板 index.ftl 展示當前請求被分發到的服務端口,前端的index.ftl文件代碼如下:
<html> <head> <title>Nginx Page</title> <link href="nginx_style.css" rel="stylesheet" type="text/css"/> </head> <body> <div style="border: 2px solid red;margin: auto;width: 800px;text-align: center"> <div id="nginx_title"> <h1>歡迎來到 ${port}頁面!</h1> </div> </div> </body>
</html>
2.Nginx conf配置(負載均衡)
upstream nginx_boot{ # 30s內檢查心跳發送兩次包,未回復就代表該機器宕機,請求分發權重比為1:2 server 192.168.0.000:8080 weight=100 max_fails=2 fail_timeout=30s; server 192.168.0.000:8090 weight=200 max_fails=2 fail_timeout=30s; # 這里的IP請配置成你WEB服務所在的機器IP
} server { location / { root html; # 配置一下index的地址,最后加上index.ftl。index index.html index.htm index.jsp index.ftl; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 請求交給名為nginx_boot的upstream上 proxy_pass http://nginx_boot; }
}
3.Nginx請求分發原理:
客戶端發出的請求192.168.12.129
最終會轉變為:http://192.168.12.129:80/
,然后再向目標IP發起請求:
● 由于Nginx監聽了
192.168.12.129
的80端口,所以最終該請求會找到Nginx進程;
● Nginx首先會根據配置的location規則進行匹配,根據客戶端的請求路徑/,會定位到location /{}
規則;
● 然后根據該location中配置的proxy_pass
會再找到名為nginx_boot的upstream
;
● 最后根據upstream
中的配置信息,將請求轉發到運行WEB服務的機器處理,由于配置了多個WEB服務,且配置了權重值,因此Nginx會依次根據權重比分發請求。
Nginx 通過 upstream 模塊定義一組后端服務器,并根據配置的負載均衡算法(如輪詢、加權輪詢、IP哈希等)將客戶端請求合理地分發到不同的后端節點上。
常見的分發策略包括:
- 輪詢(默認):依次將請求分發給每個節點;
- 加權輪詢(weight):根據節點的配置權重分配請求比例;
- IP哈希(ip_hash):保證來自同一 IP 的請求始終轉發到同一個后端節點;
- 最少連接數(least_conn):將請求分配給當前連接數最少的節點。
Nginx動靜分離
在討論網站性能優化時,“動靜分離”是一個常見的話題。那么,為什么我們需要實施動靜分離?它具體帶來了哪些好處呢?
1.什么是動靜分離?
實際上,一旦理解了網站運行的本質,動靜分離的重要性就不言而喻了。簡而言之,動靜分離是指將靜態資源(如 HTML、CSS、JavaScript
文件和圖片等)與動態內容(由服務器端腳本生成的內容)分開處理。這樣做不僅可以顯著提高頁面加載速度,還能減輕服務器負擔,從而提升用戶體驗。
通過合理配置 Nginx 實現動靜分離,可以使得靜態資源直接從 Nginx 服務器快速響應給客戶端,而動態請求則轉發至后端應用服務器進行處理。這種架構不僅提高了資源的利用效率,還增強了系統的可擴展性和穩定性。
2.一個真實場景:訪問淘寶首頁
以訪問 www.taobao.com 首頁為例,打開瀏覽器開發者工具可以看到,首頁加載時會出現 200+ 的請求。其中至少有 100+ 是靜態資源請求(如 .js、.css、.html、.jpg
等)。
在常規項目開發中,這些靜態資源通常存放在后端項目的 resources/static/
目錄下,并隨著應用打包部署到后端服務中。
但如果淘寶也采用這種方式部署,那意味著:
每個用戶訪問首頁,都會對后端服務器發起上百次請求!
這無疑會給后端服務器帶來極大的并發壓力。
3.動靜分離的核心
既然這些靜態資源很少變動,為什么不提前處理掉呢?答案是肯定的 —— 我們完全可以在 Nginx 層就攔截這些請求,直接返回資源,避免請求穿透到后端。
? 做了動靜分離之后,后端服務器的并發請求數可以減少一半以上!
這就是動靜分離所帶來的巨大性能收益。
4.Nginx操作
在 Nginx 安裝目錄下創建一個專門存放靜態資源的目錄:
mkdir /soft/nginx/static_resources
將項目中所有的靜態資源(如 HTML、JS、CSS、圖片
等)拷貝到該目錄下,并從項目中移除這些文件重新打包部署。
編輯 nginx.conf 文件,在 server 塊中添加如下配置:
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ {root /soft/nginx/static_resources;expires 7d; # 設置緩存時間為7天,提升加載效率
}
🔍 配置說明:
- ~:表示正則匹配,且區分大小寫;
- .*:匹配任意字符多次;
- .:轉義點號,用于匹配文件后綴;
- (html|…|css):匹配括號內列出的所有靜態資源類型;
- root:指定靜態資源根目錄;
- expires 7d:設置瀏覽器緩存時間,減少重復請求。
優勢 | 描述 |
---|---|
提升加載速度 | 靜態資源由 Nginx 快速響應,無需等待后端處理 |
減少后端壓力 | 后端只需處理真正的動態請求,降低并發量 |
提高系統穩定性 | 分層架構更健壯,便于維護和擴展 |
動靜分離不僅是性能優化的一種手段,更是構建高性能 Web 架構的基礎實踐之一。結合 Nginx 強大的靜態資源處理能力,能夠有效支撐高并發、低延遲的業務需求。
Nginx資源壓縮
建立在動靜分離的基礎之上,如果一個靜態資源的Size越小,那么自然傳輸速度會更快,同時也會更節省帶寬,因此我們在部署項目時,也可以通過Nginx對于靜態資源實現壓縮傳輸,一方面可以節省帶寬資源,第二方面也可以加快響應速度并提升系統整體吞吐。
在Nginx也提供了三個支持資源壓縮的模塊:
ngx_http_gzip_module
、ngx_http_gzip_static_module
、ngx_http_gunzip_module
,
其中,ngx_http_gzip_module
是 Nginx 的內置模塊,意味著可以直接使用該模塊下的相關壓縮指令來配置資源壓縮功能。
http {# 開啟壓縮機制gzip on;# 指定會被壓縮的文件類型(也可根據需要自行擴展)gzip_types text/plain application/javascript text/css application/xml text/javascript image/jpeg image/gif image/png;# 設置壓縮級別,數值越高壓縮效果越好,但資源消耗也越大gzip_comp_level 5;# 在響應頭部中添加 Vary: Accept-Encoding(建議開啟)gzip_vary on;# 壓縮請求處理的緩沖區數量和大小gzip_buffers 16 8k;# 對于不支持壓縮的客戶端請求,不啟用壓縮機制gzip_disable "MSIE [1-6]\."; # 禁用低版本 IE 瀏覽器的壓縮支持# 設置壓縮響應所支持的 HTTP 最低版本gzip_http_version 1.1;# 設置觸發壓縮的最小文件大小gzip_min_length 2k;# 關閉對后端服務器響應結果的壓縮處理gzip_proxied off;
}
Nginx緩沖區
我們先來思考一個問題:接入 Nginx 的項目,其請求流程通常為:
客戶端 → Nginx → 服務端
在這個過程中,存在兩個獨立的連接:
- 客戶端 ←→ Nginx
- Nginx ←→ 服務端
如果這兩個連接之間的傳輸速度不一致,就可能影響用戶體驗(例如瀏覽器加載速度跟不上服務端響應速度)。
這種情況其實類似于計算機中 CPU 和內存之間的速度差異。為了緩解這種速率不匹配帶來的性能瓶頸,CPU 設計中引入了“三級高速緩沖區”。同樣地,Nginx 也提供了緩沖區機制,其核心目的就是:
解決前后端連接之間傳輸速度不匹配的問題。
有了緩沖機制后,Nginx 可以暫存后端服務器的響應數據,然后根據客戶端的實際接收能力,按需輸出數據給客戶端,從而提升整體的訪問體驗。
常見的緩沖區相關配置項如下:
- proxy_buffering:是否啟用緩沖機制,默認為 on,即開啟狀態。
- client_body_buffer_size:設置用于緩沖客戶端請求體的內存大小。
- proxy_buffers:為每個請求設置緩沖區的數量和大小,默認為 4 4k/8k。
- proxy_buffer_size:設置用于存儲后端響應頭的緩沖區大小。
- proxy_busy_buffers_size:當后端尚未完全返回數據時,Nginx 可將處于“busy”狀態的緩沖區數據提前發送給客戶端。該參數用于控制 busy 狀態下可發送的數據大小,默認為 proxy_buffer_size * 2。
- proxy_temp_path:當內存緩沖區已滿時,可以將數據臨時寫入磁盤。此參數用于設置臨時存儲緩沖數據的目錄路徑。
- proxy_temp_file_write_size:設置每次寫入臨時文件的數據大小限制。
- proxy_max_temp_file_size:設置臨時緩沖目錄中允許存儲的最大容量。
- 非緩沖相關參數:
- proxy_connect_timeout:設置與后端服務器建立連接的超時時間。
- proxy_read_timeout:設置從后端服務器讀取響應的超時時間。
- proxy_send_timeout:設置向后端服務器發送請求數據的超時時間。
具體的nginx.conf配置如下:
http {proxy_connect_timeout 10;proxy_read_timeout 120;proxy_send_timeout 10;proxy_buffering on;client_body_buffer_size 512k;proxy_buffers 4 64k;proxy_buffer_size 16k;proxy_busy_buffers_size 128k;proxy_temp_file_write_size 128k;proxy_temp_path /soft/nginx/temp_buffer;
}
上述的緩沖區參數,是基于每個請求分配的空間,而并不是所有請求的共享空間。當然,具體的參數值還需要根據業務去決定,要綜合考慮機器的內存以及每個請求的平均數據大小。
合理使用緩沖機制,還可以有效減少即時傳輸對帶寬的瞬時占用,進一步提升系統穩定性與網絡利用率。
Nginx緩存機制
在性能優化方案中,緩存是一種能夠顯著提升系統性能的有效手段。因此,在現代架構設計中幾乎隨處可見緩存的身影:客戶端緩存、代理緩存、服務器緩存等。
而 Nginx 的緩存機制屬于“代理緩存”,即位于客戶端與后端服務器之間的中間層緩存。引入緩存機制對整個系統來說,具有以下幾個顯著優勢:
- 減少了向后端或文件服務器重復請求資源所帶來的帶寬消耗;
- 降低了下游服務器的訪問壓力,從而提升系統的整體吞吐能力;
- 縮短了響應時間,加快了頁面加載速度,用戶體驗更佳。
那么在 Nginx 中,我們又該如何配置代理緩存呢?首先來看一下與緩存相關的核心配置項。
? 核心緩存配置項:proxy_cache_path
proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
每個參數項的含義:
- path:緩存數據的存儲路徑;
- levels:設置緩存目錄的層級結構,最多支持三層(如 1:2 表示一級目錄 + 二級目錄);
- use_temp_path:是否使用臨時路徑進行緩存寫入;
- keys_zone:定義共享內存區域用于存儲熱點 Key(1MB 可存儲約 8000 個 Key);
- inactive:設置緩存多長時間未被訪問后自動清除,默認為 10 分鐘;
- max_size:允許緩存的最大磁盤空間,超出后按 LRU 算法清理,Nginx 會通過 Cache Manager 進程進行清理,也可以通過 purge 方式手動清除;
- manager_files:每次 Cache Manager 清理緩存時的最大文件數量;
- manager_sleep:Cache Manager 每次清理操作的最大執行時間;
- manager_threshold:Cache Manager 每次清理完成后暫停的時間間隔;
- loader_files:重啟 Nginx 時,每次加載緩存的最大文件數,默認為 100;
- loader_sleep:每次加載緩存時的最大允許時間,默認為 200ms;
- loader_threshold:一次加載后暫停的時間間隔,默認為 50ms;
- purger:是否開啟基于 purge 的緩存刪除機制;
- purger_files:每次 purge 刪除的最大緩存文件數;
- purger_sleep:每次 purge 刪除操作的最大執行時間;
- purger_threshold:purge 刪除完成后的暫停時間間隔。
常見緩存配置(nginx.conf)
http {# 設置緩存目錄,并指定內存中的緩存區名為 hot_cache,大小為 128MB,# 3 天未被訪問的緩存將被自動清除,磁盤最大緩存容量為 2GB。proxy_cache_path /soft/nginx/cache levels=1:2 keys_zone=hot_cache:128m inactive=3d max_size=2g;server {location / {# 使用名為 hot_cache 的緩存空間proxy_cache hot_cache;# 對于 200、206、304、301、302 狀態碼的數據緩存 1 天proxy_cache_valid 200 206 304 301 302 1d;# 其他狀態碼的緩存時間為 30 分鐘proxy_cache_valid any 30m;# 定義緩存鍵規則(以 host + uri + args 作為 Key)proxy_cache_key $host$uri$is_args$args;# 資源至少被訪問三次后才加入緩存proxy_cache_min_uses 3;# 當有多個相同請求時,只讓一個去后端取數據,其余從緩存讀取proxy_cache_lock on;# 鎖等待超時時間為 3 秒,超過后其他請求直接去后端獲取proxy_cache_lock_timeout 3s;# 若 cookie 或參數中聲明不緩存,則跳過緩存proxy_no_cache $cookie_nocache $arg_nocache $arg_comment;# 在響應頭中添加緩存命中狀態,便于調試分析add_header Cache-Status $upstream_cache_status;}}
}
第一次訪問時,由于緩存中尚未存在該資源,所以不會命中;第二次、第三次訪問仍未命中;直到第四次訪問時才會顯示緩存命中。這是因為在配置中設置了 proxy_cache_min_uses 3,意味著資源必須被請求三次以上才會被加入緩存,從而避免無效緩存占用存儲空間。
? 緩存清理
當緩存數據過多而不及時清理時,可能會導致磁盤空間被占滿。因此我們需要一套完善的緩存清理機制。
在前面提到的 proxy_cache_path 配置中,已經包含了一些自動清理緩存的參數,例如 inactive 和 manager 相關選項。但需要注意的是:
? purger 系列參數僅在商業版 Nginx Plus 中可用,普通開源版本不支持。
不過可以借助強大的第三方模塊 ngx_cache_purge
來實現緩存清理功能。
ngx_cache_purge 是一個第三方模塊,它允許我們通過 HTTP 請求來清除指定的緩存。以下是安裝和配置步驟:
1. 安裝 ngx_cache_purge
首先確保已經下載了 Nginx ,并且準備好了 ngx_cache_purge
模塊
# 假設你的 Nginx 源碼位于 /usr/local/src/nginx-1.21.4
cd /usr/local/src/nginx-1.21.4# 下載 ngx_cache_purge 模塊
git clone https://github.com/FRiCKLE/ngx_cache_purge.git# 重新編譯 Nginx 并添加 ngx_cache_purge 模塊
./configure --add-module=/path/to/ngx_cache_purge
make
make install
2. 配置 ngx_cache_purge
在 nginx.conf 中添加 purge 相關配置:
http {# 配置緩存路徑proxy_cache_path /soft/nginx/cache levels=1:2 keys_zone=hot_cache:128m inactive=3d max_size=2g;server {listen 80;server_name example.com;location / {proxy_pass http://backend;proxy_cache hot_cache;proxy_cache_valid 200 1d;}# 配置 purge 功能location ~ /purge(/.*) {allow 127.0.0.1; # 允許本地 IP 進行清除操作deny all; # 拒絕其他所有 IP 的清除請求proxy_cache_purge hot_cache $host$1$is_args$args;}}
}
現在,你可以通過訪問 http://example.com/purge/some/path 來清除特定 URL 的緩存。
緩存命中率如何監控?
為了監控緩存命中率,可以在響應頭中添加 X-Cache-Status 或者直接查看 Nginx 日志文件。
在響應頭中添加緩存狀態信息:
location / {proxy_cache hot_cache;add_header X-Cache-Status $upstream_cache_status;
}
$upstream_cache_status 可能返回以下幾種狀態:
- MISS:未命中緩存,從后端服務器獲取數據。
- HIT:命中緩存,直接返回緩存數據。
- EXPIRED:緩存已過期,需要重新獲取數據。
- UPDATING:正在更新緩存。
- STALE:返回過期緩存(僅當啟用 stale 數據時)
使用日志分析工具:
可以將 $upstream_cache_status 添加到日志格式中進行記錄:
log_format cache '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for" ''Cache-Status:$upstream_cache_status';access_log /var/log/nginx/access.log cache;
然后使用日志分析工具(如 GoAccess、ELK Stack 等)分析命中率。
緩存穿透、緩存雪崩、緩存擊穿的解決方案
1.緩存穿透
定義:指查詢一個不存在的數據,由于緩存中沒有該數據,導致每次都要去數據庫查詢,增加了數據庫的壓力。
解決方案:
- 布隆過濾器:用于過濾掉那些不可能存在的數據,減少對數據庫的無效查詢。
- 緩存空結果:對于查詢不到的數據,也可以設置短暫的緩存時間(如 5 分鐘),避免頻繁查詢。
nginx
location / {if ($arg_id = "") {return 404;}proxy_cache hot_cache;proxy_cache_valid 200 1d;proxy_cache_valid 404 1m; # 對于不存在的數據緩存 1 分鐘
}
2.緩存雪崩
定義:指大量緩存在同一時間段內失效,導致大量請求直接打到數據庫,造成系統崩潰。
解決方案:
- 隨機化過期時間:為每個緩存項設置不同的過期時間,避免同時失效。
- 多級緩存:除了 Nginx 緩存外,還可以增加應用層緩存或客戶端緩存。
proxy_cache_valid 200 1d random=$rnd(60m); # 隨機過期時間
3. 緩存擊穿
定義:某個熱點數據在緩存中過期,但短時間內有大量請求到達,導致這些請求都打到了數據庫。
解決方案:
- 加鎖機制:保證只有一個請求去數據庫取數據,其他請求等待緩存更新完成后再讀取緩存。
- 提前續期:在緩存即將過期前,提前刷新緩存。
proxy_cache_lock on; # 開啟鎖機制
proxy_cache_lock_timeout 3s; # 鎖超時時間為 3 秒
完整的緩存調優建議值表格
參數 | 描述 | 推薦值 | 備注 |
---|---|---|---|
proxy_cache_path | 設置緩存目錄及參數 | /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m | 根據實際需求調整大小 |
proxy_cache_min_uses | 資源至少被訪問幾次后才加入緩存 | 3 | 減少無效緩存占用空間 |
proxy_cache_valid | 設置不同狀態碼的緩存時間 | 200 1d , 404 1m | 根據業務需求調整 |
proxy_cache_key | 定義緩存鍵規則 | $scheme$proxy_host$request_uri | 確保唯一性 |
proxy_cache_lock | 開啟鎖機制防止緩存擊穿 | on | 提高并發性能 |
proxy_cache_lock_timeout | 鎖等待超時時間 | 3s | 根據實際情況調整 |
proxy_no_cache | 不緩存特定條件下的請求 | $cookie_nocache $arg_nocache | 根據具體場景定制 |
通過以上優化措施,可以有效提升系統的緩存效率,減少不必要的數據庫查詢,降低服務器負載,從而提高整體性能和用戶體驗。
Nginx實現IP黑白名單
有時候往往有些需求,可能某些接口只能開放給對應的合作商,或者購買/接入API的合作伙伴,那么此時就需要實現類似于IP白名單的功能。而有時候有些惡意攻擊者或爬蟲程序,被識別后需要禁止其再次訪問網站,因此也需要實現IP黑名單。那么這些功能無需交由后端實現,可直接在Nginx中處理。
Nginx做黑白名單機制,主要是通過allow、deny配置項來實現:
allow xxx.xxx.xxx.xxx; # 允許指定的IP訪問,可以用于實現白名單。
deny xxx.xxx.xxx.xxx; # 禁止指定的IP訪問,可以用于實現黑名單。
當需要配置多個 IP 地址時,如果將所有規則都直接寫在 nginx.conf 中,會導致配置文件臃腫冗余。因此建議采用外部配置文件的方式進行管理。新建兩個文件BlocksIP.conf、WhiteIP.conf:
# -------- 黑名單:BlocksIP.conf ---------
deny 192.177.12.222; # 屏蔽 192.177.12.222 的訪問
deny 192.177.44.201; # 屏蔽 192.177.44.201 的訪問
deny 127.0.0.0/8; # 屏蔽 127.0.0.1 到 127.255.255.254 的網段訪問# -------- 白名單:WhiteIP.conf ---------
allow 192.177.12.222; # 允許 192.177.12.222 訪問
allow 192.177.44.201; # 允許 192.177.44.201 訪問
allow 127.45.0.0/16; # 允許 127.45.0.1 到 127.45.255.254 的網段訪問
deny all; # 除上述 IP 外,其他 IP 均禁止訪問
可以將配置文件在nginx.conf中導入,以達到靈活控制的目的:
http {# 全局屏蔽黑名單中的 IPinclude /soft/nginx/IP/BlocksIP.conf;server {location /api/some_route {# 只允許白名單中的 IP 訪問該接口include /soft/nginx/IP/WhiteIP.conf;}}
}
這種方式可以非常方便地維護大量 IP 規則,并且提高了可讀性和可維護性。
Nginx跨域配置
在前后端分離架構中,前端應用和后端服務通常部署在不同的域名下,這就可能導致瀏覽器出現 跨域請求限制(CORS)。為了避免這一問題,我們可以在 Nginx 層面配置響應頭,直接支持跨域請求,而無需交由后端處理
location / {# 允許跨域請求的源,可以使用變量 $http_origin 指定具體域名,* 表示允許所有add_header 'Access-Control-Allow-Origin' *;# 允許攜帶 Cookie 發起跨域請求add_header 'Access-Control-Allow-Credentials' 'true';# 允許的跨域請求方法:GET、POST、OPTIONS、PUT 等add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT';# 允許請求中攜帶的頭部信息,* 表示允許所有頭部add_header 'Access-Control-Allow-Headers' *;# 允許客戶端訪問的響應頭(如分段請求相關字段)add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';# 必須配置!否則 POST 請求無法完成跨域# 瀏覽器在發送 POST 跨域請求前會先發送 OPTIONS 預檢請求,服務器接受后才會正式發起請求if ($request_method = 'OPTIONS') {add_header 'Access-Control-Max-Age' 1728000;add_header 'Content-Type' 'text/plain; charset=utf-8';add_header 'Content-Length' 0;# 對于 OPTIONS 請求返回 204 No Content,表示接受跨域請求return 204;}
}
配置項 | 作用說明 |
---|---|
Access-Control-Allow-Origin | 指定允許訪問的源(域名),建議不要使用 * ,應指定具體域名以提高安全性 |
Access-Control-Allow-Credentials | 是否允許發送 Cookie,設置為 true 時前端需配合設置 withCredentials: true |
Access-Control-Allow-Methods | 允許的 HTTP 方法,根據實際接口需求調整,如 GET, POST, OPTIONS 等 |
Access-Control-Allow-Headers | 允許的請求頭字段,例如 Authorization , Content-Type 等 |
Access-Control-Expose-Headers | 客戶端可訪問的響應頭字段,如 Content-Length , Content-Range 等 |
OPTIONS 處理塊 | 對于預檢請求必須返回 204 ,才能繼續進行正式請求 |
Nginx防盜鏈設計
“盜鏈”指的是外部網站直接引用當前網站上的資源(如圖片、視頻、CSS、JS 文件等)進行展示或下載的行為。
舉個例子:壁紙網站 X 擁有大量正版授權素材,而網站 Y 沒有購買這些資源,卻通過類似
的方式,直接調用 X 站的圖片資源并展示給用戶。這不僅消耗了 X 站的帶寬資源,也侵犯了其版權利益。
為了避免這種行為,我們可以借助 Nginx 的防盜鏈機制,對請求來源進行限制。
Nginx 的防盜鏈機制依賴于 HTTP 請求頭中的 Referer 字段。該字段用于標識當前請求是從哪個頁面發起的。可以在 Nginx 中使用 valid_referers 指令來定義哪些 Referer 是合法的,然后通過 $invalid_referer 變量判斷是否為非法請求。如果是非法請求,則返回 403 或重定向到提示圖片。
? valid_referers 支持的參數說明:
valid_referers none | blocked | server_names | string ...;
- none:表示接受沒有 Referer 字段的請求;
- blocked:表示允許 Referer 被防火墻或代理屏蔽的情況(即非標準協議請求);
- server_names:指定允許訪問的域名列表,作為白名單;
- string:可以是字符串、通配符或正則表達式,用于自定義允許的 Referer 地址。
# 在動靜分離的 location 中開啟防盜鏈機制
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css) {# 最后面的值在上線前可配置為允許的域名地址valid_referers blocked 192.168.12.129;if ($invalid_referer) {# 可以配置成返回一張禁止盜取的圖片# rewrite ^/ http://xx.xx.com/NO.jpg;# 也可直接返回 403 禁止訪問return 403;}root /soft/nginx/static_resources;expires 7d;
}
Nginx大文件傳輸配置
在某些業務場景中(如文件上傳、資源下載等),需要通過 Nginx 傳輸大文件。然而,在默認配置下,Nginx 對請求體大小、連接超時時間等都有一定限制,可能導致一些 “請求體過大”、“請求超時”、“連接被中斷” 等問題。
為了解決這些問題,我們可以在 Nginx 中進行一些針對性的配置調整。其中,以下幾個參數在傳輸大文件時尤為重要:
client_max_body_size
、client_header_timeout
、proxy_read_timeout
、proxy_send_timeout
這四個參數值都可以根據自己項目的實際情況來配置。
配置項 | 作用說明 |
---|---|
client_max_body_size | 設置請求體允許的最大體積,默認為 1MB,建議根據實際需求調大(如 100M) |
client_header_timeout | 等待客戶端發送一個請求頭的超時時間,默認為 60s |
client_body_timeout | 設置讀取請求體的超時時間,默認為 60s |
proxy_read_timeout | 設置請求被后端服務器讀取時,Nginx等待的最長時間,默認為 60s |
proxy_send_timeout | 設置后端向Nginx返回響應時的超時時間,默認為 60s |
?? 注意:這些參數應根據實際業務場景中的文件大小、網絡帶寬、傳輸速度等因素進行合理設置,避免因配置不當引發性能浪費或服務異常。
http {client_max_body_size 100M;client_header_timeout 300s;client_body_timeout 300s;server {listen 80;location /upload/ {proxy_pass http://backend_server;proxy_read_timeout 300s;proxy_send_timeout 300s;}}
}
通過以上配置,可以有效支持大文件的穩定傳輸,減少因超時或大小限制導致的傳輸失敗問題,提升系統的兼容性和穩定性。