一、概述
Nginx一個具有高性能的【HTTP】和【反向代理】的【WEB服務器】,同時也是一個電子郵件代理服務器。正向代理服務的是客戶端(比如VPN),反向代理服務的是服務端。Nginx是多進程的,有一個Master進程控制多個Worker進程。速度快、并發高、熱部署。
1、優點
- 速度快,并發高,在5萬左右。采用多進程,io多路復用技術。像Tomcat是一個重量級的服務器,并發在200左右
- 配置簡單,擴展性強
- 高可靠性,有master進程和worker進程,其中master進行單獨用于管理worker進程
- 熱部署
- 成本低,BSD許可證(可以修改源碼并且可以用來賺錢)
2、常用模塊
- 靜態資源部署
- Rewrite地址重寫,使用正則表達式
- 反向代理
- 負載均衡
- web緩存
- 用戶認證模塊
3、核心組成
- nginx:二進制可執行文件
- nginx.conf:核心配置文件
- error.log:錯誤的日志記錄
- access.log:訪問日志記錄
- nginx.pid:記錄nginx的Master進程id
二、配置
# nginx.config文件
# 全局配置部分
#-----------------------------# 定義工作進程數量(建議設置為CPU核心數或自動檢測)
# 值:數字 或 auto
worker_processes 4; # user指令:用于配置運行Nginx服務器的worker進程的用戶和用戶組。使用user指令啟動的時候,可以指定Linux系統的用戶和用戶組,然后訪問Nginx的時候,只能訪問到該用戶擁有權限的目錄,進行權限訪問控制。# daemon:是否已守護進程運行,默認為on# pid:用于指定存放master進程id的文件路徑# error_log:用于配置Nginx錯誤日志存放的路徑# include:可以引入其他的配置文件,可以放在任何位置,放在全局塊中可以引入全局塊指令# 事件模塊配置(控制連接處理模型)
#-----------------------------
events {# 每個Worker進程允許的最大并發連接數(包含活動連接和空閑連接)。默認 512。設置值不能超過操作系統支持打開的最大句柄數量# 總最大連接數 = worker_processes * worker_connectionsworker_connections 40960; # accept_mutex:用來設置Nginx網絡連接序列化,默認為on。用來解決驚群問題,就是一個請求發送過來,所有的worker進程都會喚醒來搶奪這個請求,設置為on開啟序列化,意為每次來請求,只會喚醒一個worker進程來處理請求。根據實際需求來配置,因為可能會同時發送過來多個請求# muli accept:用來設置是否允許woker進行同時接受多個網絡連接。默認為off,可以打開提高速度# use:設置Nginx服務器使用哪種事件驅動來處理網絡消息。默認值根據操作系統來確定。推薦使用epoll使用io多路復用。
}# HTTP核心模塊配置
#-----------------------------
http {# 根據User-Agent判斷設備類型(用于后續條件判斷)# 定義變量 $device_type,默認值為desktop,匹配移動設備則設為mobilemap $http_user_agent $device_type {default desktop; # 默認值~*android|iphone|ipad|ipod mobile; # 正則匹配(不區分大小寫)}# 包含MIME類型定義文件(默認路徑為nginx目錄下的conf/mime.types)# 我們都知道瀏覽器中可以顯示的內容有HTML、XML、GIF等種類繁多的文件、媒體等資源,瀏覽器為了區分這些資源,就需要使用MIME Type。所以說MIME Type是網絡資源的媒體類型。Nginx作為web服務器,也需要能夠識別前端請求的資源類型。default_type 來指定相應給前端的類型, application/octet-stream會下載下來響應include mime.types; # access_log:用來設置用戶訪問日志的目錄、格式等相關屬性# log_format:用來指定日志的輸出格式# 默認響應類型(當無法識別文件類型時使用)# 注意:application/wasm 是WebAssembly的MIME類型,需確認是否需要此設置default_type application/wasm; # 啟用高效文件傳輸模式(零拷貝技術)。用來設置Nginx服務器是否使用Linux操作系統的sendfile()傳輸文件,該屬性可以大大提高Nginx處理靜態資源的性能。默認off# 讀取文件流程是客戶端請求,用戶區、內核區、磁盤、網卡中進行多次拷貝,效率較低,四次拷貝,sendfile是操作系統底層函數。開啟可以提升效率,不需要多次拷貝,可以指定讀取到哪個socket,直接響應給客戶端。服務端的數據要返回給客戶端。那么有兩種模式,一種是實時發送,即`tcp_nodelay`,默認on,來了一個數據就直接發送給客戶端,這樣實時性很高,但是消耗性能。第二種就是開辟一個緩沖區,即`tcp_nopush`,默認off,依賴sendfile,數據將緩沖區填滿之后再一起發送,實時性弱一點,但是性能高。兩個配置看起來是互斥的,但是Linux2.5.9之后進行了優化,所有建議三者都打開,配置在http塊。sendfile on; # 客戶端保持連接的超時時間(單位:秒)。用來設置長連接的超時時間。如何客戶端向服務端發送多個請求,每個請求都需要重新創建一次連接,效率相對來說比較多,使用keepalive模式,可以告訴服務器端在處理完一個請求后保持這個TCP連接的打開狀態,若接收到來自這個客戶端的其他請求,服務端就會利用這個未被關閉的連接,而不需要重新創建一個新連接,提升效率,但是這個連接也不能一直保持,這樣的話,連接如果過多,也會是服務端的性能下降,這個時候就需要我們進行設置其的超時時間。默75秒keepalive_timeout 65; # keepalive_requests:用來設置一個keep-alive連接使用的次數,達到次數就關閉這個連接# 從ISO8601時間格式中提取日期(用于日志文件名)map $time_iso8601 $logdate {'~^(?<ymd>\d{4}-\d{2}-\d{2})' $ymd; # 正則捕獲年月日default 'date-not-found'; # 匹配失敗時的默認值}# 訪問日志配置(按日期分割日志)access_log logs/access-$logdate.log; # 客戶端請求相關配置#-----------------------------client_max_body_size 50m; # 允許客戶端上傳的最大文件大小(重要!涉及文件上傳需設置)client_body_buffer_size 60k; # 客戶端請求體緩沖區大小client_body_timeout 60; # 客戶端請求體讀取超時時間(秒)client_header_buffer_size 64k; # 客戶端請求頭緩沖區大小client_header_timeout 60; # 客戶端請求頭讀取超時時間(秒)# 錯誤頁面配置#-----------------------------error_page 400 /error/400.html; # 錯誤碼映射到指定URIerror_page 403 /error/403.html;error_page 404 /error/404.html;error_page 500 /error/500.html;# ...(其他錯誤碼配置,需確保/error目錄下存在對應HTML文件)# 高級連接配置#-----------------------------keepalive_requests 1000; # 單個Keep-Alive連接允許的最大請求數large_client_header_buffers 4 64k; # 大型請求頭的緩沖區數量和大小reset_timedout_connection on; # 關閉超時未響應的連接以釋放資源send_timeout 60; # 響應發送超時時間(秒)# 文件傳輸優化sendfile_max_chunk 512k; # 單次sendfile調用的最大傳輸量(避免Worker進程阻塞)# 服務器名哈希表優化server_names_hash_bucket_size 256; # 服務器名哈希表桶大小(域名較長時需要增加)# 包含虛擬主機配置文件(通常用于分站點管理)include vhosts/*.conf;
}# 系統資源限制(需放在全局塊,不能放在http塊內)
#-----------------------------
worker_rlimit_nofile 100000; # Worker進程能打開的最大文件描述符數量(需配合系統ulimit設置)
# includ.config文件
# ======================================================
# Nginx Server 塊配置詳解
# 此配置用于處理域名為 dbgmarkets.co 的 HTTP/HTTPS 請求
# 實現功能:SSL 加密、動靜分離、API 代理、設備類型適配、Gzip 壓縮
# ======================================================# server塊的匹配優先級是:準確匹配、通配符在前的匹配、通配符在后的匹配、正則表達式的匹配、默認的server匹配
server {# --------------------------# 監聽端口與協議配置# --------------------------listen 80; # 監聽 IPv4 的 HTTP 80 端口listen 443 ssl http2 default_server; # 監聽 IPv4 的 HTTPS 443 端口,啟用 HTTP/2,設為默認主機listen [::]:443 ssl http2 default_server; # 監聽 IPv6 的 HTTPS 443 端口# 說明:# - default_server: 當請求未匹配其他 server_name 時,并且請求的為指定監聽的端口,則由此塊處理。沒有指定默認server,第一個server就是默認的server# - http2: 啟用 HTTP/2 協議提升性能# - ssl: 啟用 SSL/TLS 加密# --------------------------# 域名與基礎設置# --------------------------server_name dbgmarkets.co; # 匹配的域名(精確匹配,不含 www 等子域名)。用于指定訪問的ip或域名。多個域名間用空格分隔。有三種模式,精確匹配,通配符*匹配(不能寫在中間,只能出現在首段和尾端,否者會失效),正則表達式匹配(必須使用~作為開始標識)。其中正則表達式,可以使用括號和$N方式在return中獲取對應訪問的值absolute_redirect off; # 關閉絕對路徑重定向(返回相對路徑,適用于反向代理后方場景)# --------------------------# Gzip 壓縮配置(優化傳輸效率)# --------------------------# 在http塊中。gzip設置為on。gzip_types 設置要壓縮的類型,默認只會壓縮text/html類型。# gzip_comp_level:有1到9個級別。1壓縮最快,壓縮程度低,建議設置為6,基本已經極限。# gzip_vary:默認off。開啟之后,會在響應頭上面添加Vary:Accept-Encoding# gzip_buffers number size:設置壓縮時緩沖區的數量和大小。默認即可# gzip_disable "正則表達式" : 會匹配瀏覽器的user-agnet,匹配到的就不進行壓縮# gzip_min_length:當資源小于這個指定大小后,就不進行壓縮了。默認20b# gzip_proxied:默認off。指的是作為反向代理服務器,對于后端返回的數據是否進行壓縮。# gzip_static:默認off這個是在還沒有讀取時就壓縮文件,然后直接讀取對應文件的.gz文件,有的話就直接使用這個文件,沒有的話在讀取源文件,使用頭信息Content-Encoding:gzip和Vary:Accept-Encoding告訴瀏覽器進行了文件壓縮。gzip on; # 啟用 Gzip 壓縮gzip_min_length 1k; # 只壓縮大于 1KB 的文件gzip_comp_level 9; # 壓縮級別 1-9(9 最高壓縮率,CPU 消耗較大)gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml; # 壓縮指定 MIME 類型gzip_vary on; # 添加 "Vary: Accept-Encoding" 頭gzip_disable "MSIE [1-6]\."; # 為舊版 IE 瀏覽器禁用壓縮# --------------------------# SSL/TLS 安全配置# --------------------------ssl_certificate C:/crm/nginx-1.20.2/ssl/dbgmarkets_co/dbgmarkets_co.crt; # SSL 證書路徑(Windows 格式)ssl_certificate_key C:/crm/nginx-1.20.2/ssl/dbgmarkets_co/dbgmarkets_co.key; # SSL 私鑰路徑ssl_session_cache shared:SSL:1m; # SSL 會話緩存(1MB 內存,減少握手開銷)ssl_session_timeout 10m; # SSL 會話超時時間(10 分鐘)ssl_ciphers HIGH:!aNULL:!MD5; # 加密套件配置(HIGH 安全級別,禁用 aNULL/MD5)ssl_prefer_server_ciphers on; # 優先使用服務端加密套件# 注意:建議添加 ssl_protocols TLSv1.2 TLSv1.3; 以禁用老舊協議# --------------------------# 靜態資源服務配置# --------------------------# root 實際返回的資源是root路徑+location路徑# alias 實際返回的資源只是alias的路徑root C:/crm/web/dist; # 靜態文件根目錄(前端構建產物存放路徑)# 示例:請求 /css/style.css 將映射到 C:/crm/web/dist/css/style.css# --------------------------# 公共代理頭設置# --------------------------proxy_set_header X-Forwarded-Proto $scheme; # 傳遞客戶端協議(http/https)proxy_set_header X-Real-IP $remote_addr; # 傳遞客戶端真實 IPclient_max_body_size 15M; # 允許客戶端上傳最大 15MB 文件(如文件上傳功能)# --------------------------# 路由處理:根路徑(/)# --------------------------location / {# 設備類型判斷(根據全局 map 映射的 $device_type 變量)if ($device_type = mobile) { # 如果是移動設備proxy_pass http://127.0.0.1:3001; # 代理到本地的 3001 端口(移動端服務)break; # 終止后續處理}index index.html; # 默認訪問文件try_files $uri $uri/ /index.html; # 前端 SPA 路由支持(找不到文件時返回 index.html)# 流程:嘗試訪問真實文件 → 查找目錄 → 回退到 index.html}# --------------------------# 路由處理:API 接口(/api)# --------------------------# location /api 匹配所有以/api開頭的請求# =/api 精確匹配,只匹配/api的請求# ~^/api\w$ 正則表達式匹配,~標識使用正則表達式,^開頭,$結尾。其中使用~*標識正則表達式不區分大小寫# ^~/api 匹配第一個以/api開頭的請求。默認的匹配順序是匹配所有的條件,返回最后一個匹配到的,這個^~標識表示匹配到這個表達式之后,就不再向后匹配,直接返回結果location /api {# 解決跨域問題# add_header Access-Control-Allow-Origin 訪問的ip地址端口號# add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE# 代理到本地的 81 端口(后端 API 服務)proxy_pass http://127.0.0.1:81; # 關鍵代理頭設置# WebSocket 協議升級支持proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; # 傳遞原始域名# 補充:通常還需添加 X-Forwarded-For 頭記錄客戶端 IP 鏈}# --------------------------# 錯誤頁面配置# --------------------------# 5xx 錯誤統一返回 50x.html。error_page 500 =200 /error.html 使用=可以將返回的狀態碼500改為200error_page 500 502 503 504 /50x.html; # 注意:需確保 root 目錄存在 50x.html 文件
}# rewrit 指令
# set指令。`set $key value`。設置變量鍵值對。$key可以直接使用。Nginx有預定的變量,如$args就是所有請求參數,$host獲取到的是訪問的服務器地址
# `if (){}`指令。條件如果是一個變量,不為空或0就是true。也可以使用=和!=判斷,不需要引號。也可以使用正則表達式判斷,變量和表達式之間用空格和~隔開,然后匹配上為true,其中~區分大小寫,~*不區分大小寫,!~表示取反。還可以使用內置參數和變量結合判斷,如`-f $request_filename`用來判斷這個文件是否存在。
# break;指令,終止當前作用域,并且會重定向到當前indx文件。
# `rewrite 正則表達式 地址 [命令]`。命令:last:匹配到后會拿這個地址去所有塊中尋找,然后轉發;break:匹配到后,會拿這個地址去本塊中尋找;redirect:重定向到指定地址,臨時重定向302;permanent:永久重定向,301
# `rewrite_log on;`開啟后,會以notice級別輸出到error日志中。所以需要 `error_log error.log notice;`
# `return code url`:直接返回指定的code,跳轉到對應的url上。