1.什么是 Nginx?
Nginx 是一個高性能的 Web 服務器和反向代理服務器。它輕量、高效,被廣泛用于現代 Web 開發中。
2.為什么前端需要了解 Nginx??★ 了解
-
本地開發:可以模擬生產環境
-
部署前端項目:作為靜態文件服務器
-
解決跨域問題:配置代理
-
性能優化:啟用壓縮、緩存等
3.基本使用場景??★ 基礎
1. 作為靜態文件服務器
這是最簡單的用法,用來托管你的 HTML、CSS、JS 等靜態文件。
示例配置:
server {listen 80;server_name localhost;location / {root /path/to/your/project;index index.html;}
}
2. 解決跨域問題(開發環境)
在開發時,前端經常需要請求后端 API,可能會遇到跨域問題。Nginx 可以配置代理:
server {listen 80;server_name localhost;location / {root /path/to/your/project;index index.html;}location /api/ {proxy_pass http://backend-server:port/;}
}
3. 配置 HTTPS
現代網站基本都使用 HTTPS,Nginx 可以輕松配置:
server {listen 443 ssl;server_name yourdomain.com;ssl_certificate /path/to/cert.pem;ssl_certificate_key /path/to/key.pem;location / {root /path/to/your/project;index index.html;}
}
4.Nginx 核心配置?★ 基礎
一、基礎結構
# 全局塊(影響整個Nginx運行的配置)
user nginx; # 運行用戶
worker_processes auto; # 工作進程數(通常設為CPU核心數)
error_log /var/log/nginx/error.log warn; # 錯誤日志路徑和級別# 事件塊(連接處理配置)
events {worker_connections 1024; # 每個worker的最大連接數use epoll; # Linux高性能事件模型
}# HTTP塊(核心配置區域)
http {include /etc/nginx/mime.types; # 文件擴展名與MIME類型映射default_type application/octet-stream; # 默認MIME類型# 其他HTTP全局配置...# Server塊(虛擬主機配置)server {listen 80; # 監聽端口server_name example.com; # 域名# Location塊(URI路由配置)location / {root /var/www/html; # 根目錄index index.html; # 默認文件}}
}
二、核心功能配置
1. 靜態資源服務
server {location /static/ {alias /data/static/; # 路徑映射(注意末尾斜線)expires 30d; # 緩存時間access_log off; # 關閉訪問日志}location ~* \.(jpg|png|gif)$ {root /data/images;# 圖片防盜鏈valid_referers none blocked *.example.com;if ($invalid_referer) {return 403;}}
}
2. 反向代理
location /api/ {proxy_pass http://backend_server/; # 末尾斜線會去除/api前綴# 關鍵代理頭設置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_connect_timeout 75s;proxy_read_timeout 300s;# 緩沖區優化proxy_buffer_size 4k;proxy_buffers 8 16k;
}
3. 負載均衡
upstream backend {least_conn; # 最少連接算法server 10.0.0.1:8080 weight=5;server 10.0.0.2:8080;server backup.example.com:8080 backup;# 健康檢查(需nginx-plus或第三方模塊)# health_check interval=5s;
}
4. HTTPS配置
server {listen 443 ssl http2;server_name example.com;ssl_certificate /etc/ssl/certs/example.com.crt;ssl_certificate_key /etc/ssl/private/example.com.key;# 安全增強配置ssl_protocols TLSv1.2 TLSv1.3;ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';ssl_prefer_server_ciphers on;ssl_session_cache shared:SSL:10m;ssl_session_timeout 10m;# HSTS頭(強制HTTPS)add_header Strict-Transport-Security "max-age=63072000" always;
}
三、高級配置技巧
1. 路徑重寫
location /old/ {rewrite ^/old/(.*)$ /new/$1 permanent; # 301重定向
}# 條件重寫
if ($http_user_agent ~* "bot") {rewrite ^(.*)$ /bot-page.html break;
}
2. 訪問控制
location /admin/ {allow 192.168.1.0/24; # 允許內網IPdeny all; # 拒絕其他所有auth_basic "Restricted"; # 基礎認證auth_basic_user_file /etc/nginx/.htpasswd;
}
3. 性能優化
# 全局配置
sendfile on; # 零拷貝傳輸
tcp_nopush on; # 優化數據包發送
keepalive_timeout 65; # 長連接超時# Gzip壓縮
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1k;
gzip_comp_level 6;
4. 日志定制
log_format main '$remote_addr - $remote_user [$time_local] ''"$request" $status $body_bytes_sent ''"$http_referer" "$http_user_agent"';access_log /var/log/nginx/access.log main buffer=32k flush=5m;
四、調試與維護
1. 配置檢查
nginx -t # 測試配置文件語法
nginx -T # 測試并打印有效配置
2. 常用命令
nginx -s reload # 平滑重載配置
nginx -s reopen # 重新打開日志文件
kill -USR2 `cat /var/run/nginx.pid` # 熱升級
3. 變量參考
變量 | 說明 |
---|---|
| 請求的主機名 |
| 完整請求URI |
| 查詢字符串 |
| 客戶端UA信息 |
| 后端響應時間 |
5.Nginx location 匹配規則詳解??★ 重要
location
?指令是 Nginx 配置中最核心的部分之一,它決定了如何處理不同的 URI 請求。下面我將全面講解 location 的匹配規則和使用方法。
4.1、location 語法基礎???★ 重要
基本語法:
location [修飾符] 匹配模式 {# 配置指令
}
4.2、匹配規則優先級???★ 重要
Nginx 的 location 匹配遵循以下優先級順序:
匹配類型 | 符號 | 優先級 | 匹配規則 | 是否繼續搜索其他 location |
---|---|---|---|---|
精確匹配 |
| 1 | URI 必須完全一致 | ? 立即停止 |
前綴優先匹配 |
| 2 | URI 以指定模式開頭(最長匹配原則) | ? 不再檢查正則 |
正則匹配 |
| 3 | 區分大小寫的正則匹配(按配置文件順序) | ?? 按順序繼續 |
正則匹配 |
| 3 | 不區分大小寫的正則匹配(按配置文件順序) | ?? 按順序繼續 |
普通前綴匹配 | 無符號 | 4 | URI 以指定模式開頭(遵循最長匹配原則) | ?? 會繼續檢查正則 |
通用匹配 |
| 5 | 匹配所有請求 | ? 最終兜底 |
🔍 匹配流程說明(重點)???★ 重要
-
先檢查精確匹配?(
=
) → 命中則立即停止 -
檢查所有普通前綴匹配?→ 記錄最長匹配項
-
如果最長匹配有?
^~
?→ 直接使用,停止搜索 -
否則暫存這個結果,繼續后續檢查
-
-
按順序檢查正則匹配?(
~
/~*
) → 第一個命中的正則立即生效 -
如果前面都未命中?→ 使用之前暫存的普通前綴匹配
-
最終回退?→ 使用?
location /
/* * 注意的是,nginx的匹配優先順序按照上面的順序進行優先匹配,而且注意的是一旦某一個匹配命/中直接退出,不再進行往下的匹配剩下的普通匹配會按照最長匹配長度優先級來匹配,就是誰匹配的越多就用誰 */ server {# 1. 精確匹配(最高優先級)location = /login {return 401 "請先登錄";}# 2. 前綴優先匹配(第二優先級)location ^~ /static/ {root /data;}# 3. 正則匹配(第三優先級)location ~ /user/\d+ {proxy_pass http://backend;}# 4. 普通前綴匹配(第四優先級)location /documents/ {alias /docs/;}# 5. 通用匹配(最低優先級)location / {try_files $uri $uri/ =404;} }
4.3、匹配類型詳解???★ 重要
1. 精確匹配 (=)???★ 重要
location = /exact/match {# 只有當請求URI完全等于"/exact/match"時才會匹配
}
特點:
-
完全匹配時才生效
-
匹配成功后立即停止搜索其他location
-
效率最高
2. 前綴匹配 (^~)???★ 重要
location ^~ /static/ {# 匹配以/static/開頭的URI
}
特點:
-
匹配前綴后不再檢查正則表達式
-
比正則匹配優先級高
3. 正則匹配 (~ 和 ~*)???★ 重要
location ~ \.php$ {# 區分大小寫的正則匹配.php結尾的URI
}location ~* \.(jpg|png|gif)$ {# 不區分大小寫的正則匹配圖片文件
}
特點:
-
~
?區分大小寫 -
~*
?不區分大小寫 -
按配置文件中出現的順序匹配
4. 普通前綴匹配???★ 重要
location /prefix {# 匹配以/prefix開頭的URI
}
特點:
-
遵循最長匹配原則
-
如果最長匹配不是^~或=,還會檢查正則匹配
5. 通用匹配 (/)???★ 重要
location / {# 匹配所有請求
}
特點:
-
最低優先級
-
當沒有其他location匹配時使用
4.4、匹配示例分析
server {location = / {# 精確匹配首頁}location ^~ /images/ {# 匹配/images/下的所有文件}location ~* \.(gif|jpg|jpeg)$ {# 匹配所有圖片文件}location /documents/ {# 匹配/documents/下的文件}location / {# 通用匹配}
}
6.History 模式(前端路由支持)???★ 重要
問題背景:
Vue/React 等 SPA 項目使用?history.pushState
?時,刷新頁面會導致 404(因為服務器沒有對應的真實路徑)。
Nginx 解決方案:
server {listen 80;server_name yourdomain.com;location / {root /path/to/your/spa;index index.html;# 關鍵配置:所有非靜態文件請求都返回 index.htmltry_files $uri $uri/ /index.html;}
}
原理:
-
try_files
?會按順序檢查請求路徑是否存在 -
如果都不存在,最終返回?
/index.html
,由前端處理路由
7.跨域處理(CORS)???★ 重要
問題背景:
前端訪問不同域名/端口的 API 時,瀏覽器會阻止請求。
Nginx 解決方案:
location /api/ {# 代理到真實后端proxy_pass http://backend-server:8080/;# 添加跨域頭add_header 'Access-Control-Allow-Origin' '$http_origin';add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';add_header 'Access-Control-Allow-Headers' 'Content-Type,Authorization';add_header 'Access-Control-Allow-Credentials' 'true';# 預檢請求處理if ($request_method = 'OPTIONS') {return 204;}
}
8.緩存控制???★ 重要
1. 靜態資源緩存
2. 禁用緩存(適合 HTML 文件)
3. 代理緩存(反向代理場景)
9.反向代理???★ 重要
典型場景:
-
前端請求?
/api
?轉發到后端服務 -
負載均衡多臺服務器
基礎配置
location /api/ {proxy_pass http://backend-server:8080/; # 末尾/會去除/api前綴# 常用代理頭設置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_connect_timeout 60s;proxy_read_timeout 60s;
}
負載均衡示例
upstream backend {server 10.0.0.1:8000 weight=3; # 權重3server 10.0.0.2:8000;server 10.0.0.3:8000 backup; # 備用服務器
}location / {proxy_pass http://backend;
}
10.關鍵點總結
功能 | 核心指令/配置 | 注意事項 |
---|---|---|
History模式 | try_files $uri $uri/ /index.html | 需要前端路由配合 |
跨域 | add_header 'Access-Control-*' | 復雜請求需處理 OPTIONS 預檢 |
緩存 | expires ?+?Cache-Control | 靜態/動態資源策略不同 |
反向代理 | proxy_pass ?+?proxy_set_header | 注意路徑末尾/ 是否保留前綴 |
實際使用時,建議通過?nginx -t
?測試配置后再重載服務。
11.以目錄去區分多個history單文件???★ 重要
因為不可能每一個項目開啟一個域名,僅僅指向通過增加路徑來劃分多個網站,比如:
-
www.taobao.com/tmall/login
訪問天貓的登錄頁面 -
www.taobao.com/alipay/login
訪問支付寶的登錄頁面server {listen 80;server_name taobao.com;index index.html index.htm;# 通過正則來匹配捕獲 [tmall|alipay]中間的這個路徑location ~ ^/([^\/]+)/(.*)$ {try_files $uri $uri/ /$1/dist/index.html =404;} }
12.負載均衡???★ 重要
基于upstream做負載均衡,中間會涉及一些相關的策略比如ip_hash
、weight
upstream backserver{ # 哈希算法,自動定位到該服務器 保證唯一ip定位到同一部機器 用于解決session登錄態的問題ip_hash; server 127.0.0.1:9090 down; (down 表示單前的server暫時不參與負載) server 127.0.0.1:8080 weight=2; (weight 默認為1.weight越大,負載的權重就越大) server 127.0.0.1:6060; server 127.0.0.1:7070 backup; (其它所有的非backup機器down或者忙的時候,請求backup機器)
}
13.灰度部署???★ 重要
如何根據headers頭部來進行灰度,下面的例子是用cookie來設置,如何獲取頭部值在nginx中可以通過$http_xxx
來獲取變量
upstream stable {server xxx max_fails=1 fail_timeout=60;server xxx max_fails=1 fail_timeout=60;}
upstream canara {server xxx max_fails=1 fail_timeout=60;
}server {listen 80;server_name xxx;# 設置默認set $group "stable";# 根據cookie頭部設置接入的服務if ($http_cookie ~* "tts_version_id=canara"){set $group canara;}if ($http_cookie ~* "tts_version_id=stable"){set $group stable;}location / {proxy_pass http://$group;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;index index.html index.htm;}
}
14.優雅降級???★ 重要
常用于ssr的node服務掛了返回500錯誤碼然后降級到csr的cos桶或者nginx中,優雅降級主要用error_page
參數來進行降級指向備用地址。
upstream ssr {server xxx max_fails=1 fail_timeout=60;server xxx max_fails=1 fail_timeout=60;}
upstream csr {server xxx max_fails=1 fail_timeout=60;server xxx max_fails=1 fail_timeout=60;
}location ^~ /ssr/ {proxy_pass http://ssr;# 開啟自定義錯誤捕獲 如果這里不設置為on的話 會走向nginx處理的默認錯誤頁面proxy_intercept_errors on;# 捕獲500系列錯誤 如果500錯誤的話降級為下面的csr渲染error_page 500 501 502 503 504 = @csr_location# error_page 500 501 502 503 504 = 200 @csr_location# 注意這上面的區別 等號前面沒有200 表示 最終返回的狀態碼已 @csr_location為準 加了200的話表示不管@csr_location返回啥都返回200狀態碼
}location @csr_location {# 這時候地址還是帶著/ssr/的要去除rewrite ^/ssr/(.*)$ /$1 break;proxy_pass http://csr;rewrite_log on;
}
15.webp根據瀏覽器自動降級為png???★ 重要
這套方案不像常見的由nginx把png轉為webp的方案,而是先經由圖床系統(node服務)上傳兩份圖片:
-
一份是原圖png
-
一份是png壓縮為webp的圖片(使用的是imagemin-webp)
然后通過nginx檢測頭部是否支持webp來返回webp圖片,不支持的話就返回原圖即可。這其中還做了錯誤攔截,如果cos桶丟失webp圖片及時瀏覽器支持webp也要降級為png
http {include /etc/nginx/mime.types;default_type application/octet-stream;# 設置日志格式log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"''"$proxy_host" "$upstream_addr"';access_log /var/log/nginx/access.log main;sendfile on;keepalive_timeout 65;# 開啟gzipgzip on;gzip_vary on;gzip_proxied any;gzip_comp_level 6;gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;# 負載均衡 這里可以是多個cos桶地址即可upstream static_env {server xxx;server xxx;}# map 設置變量映射 第一個變量指的是要通過映射的key值 Accpet 第二個值的是變量別名map $http_accept $webp_suffix {# 默認為 空字符串default "";# 正則匹配如果Accep含有webp字段 設置為.webp值"~*webp" ".webp";}server {listen 8888;absolute_redirect off; #取消絕對路徑的重定向#網站主頁路徑。此路徑僅供參考,具體請您按照實際目錄操作。root /usr/share/nginx/html;location / {index index.html index.htm;proxy_set_header Host $host;try_files $uri $uri/ /index.html;add_header Cache-Control 'no-cache, max-age=0';}# favicon.icolocation = /favicon.ico {log_not_found off;access_log off;}# robots.txtlocation = /robots.txt {log_not_found off;access_log off;}# location ~* \.(png|jpe?g)$ {# Pass WebP support header to backend# 如果header頭部中支持webpif ($webp_suffix ~* webp) {# 先嘗試找是否有webp格式圖片rewrite ^/(.*)\.(png|jpe?g)$ /$1.webp break;# 找不到的話 這里捕獲404錯誤 返回原始錯誤 注意這里的=號 代表最終返回的是@static_img的狀態嗎error_page 404 = @static_img;}proxy_intercept_errors on;add_header Vary Accept;proxy_pass http://static_env;proxy_set_header Host $http_host;expires 7d;access_log off;}location @static_img {#set $complete $schema $server_addr $request_uri;rewrite ^/.+$ $request_uri break;proxy_pass http://static_env;proxy_set_header Host $http_host;expires 7d;}# assets, medialocation ~* \.(?:css(\.map)?|js(\.map)?|gif|svg|jfif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {proxy_pass http://static_env;proxy_set_header Host $http_host;expires 7d;access_log off;}error_page 500 502 503 504 /50x.html;location = /50x.html {root /usr/share/nginx/html;}}
}
16.nginx常用指令???★ 基礎
Nginx 主程序參數
指令 | 說明 | 示例 |
---|---|---|
| 顯示幫助信息 |
|
| 顯示版本信息 |
|
| 顯示版本和配置參數 |
|
| 測試配置文件語法 |
|
| 測試配置并打印有效配置 |
|
| 測試配置時不顯示非錯誤信息 |
|
| 發送信號到主進程 |
|
| 設置前綴路徑 |
|
| 指定配置文件 |
|
| 設置全局指令 |
|
進程管理信號(-s 參數)
信號 | 說明 | 示例 |
---|---|---|
| 立即停止 |
|
| 優雅停止 |
|
| 重載配置 |
|
| 重新打開日志 |
|
Windows 實用命令
命令 | 說明 | 示例 |
---|---|---|
| 強制終止所有 Nginx 進程 | - |
| 檢查 Nginx 進程 | - |
| 創建 Windows 服務 | - |
| 啟動 Nginx 服務 | - |
| 停止 Nginx 服務 | - |
環境管理命令
命令 | 說明 |
---|---|
| 設置環境變量 |
| 添加 PATH |
調試命令
命令 | 說明 |
---|---|
| 輸出錯誤到日志 |
| 指定錯誤日志路徑 |
注:
-
所有命令需在 CMD 中執行
-
建議在 Nginx 安裝目錄下操作
-
修改配置后務必測試語法:
nginx -t
-
服務管理命令需管理員權限