科普文:一文搞懂nginx原理和實戰

1. Nginx簡介與核心架構

圖片

1.1 Nginx簡介

????????Nginx (engine x) 是一個高性能的 HTTP 和反向代理服務器,也是一個 IMAP/POP3/SMTP 郵件代理服務器。

????????由 Igor Sysoev 于2004年首次發布,其設計目標是解決 C10K 問題,即在一臺服務器上同時處理一萬個并發連接。

???????Nginx 以其高并發處理能力、低資源消耗和模塊化設計而聞名,廣泛應用于 Web 服務器、反向代理、負載均衡等場景。

1.1.1 主要特性
  • 高并發處理能力:Nginx 使用異步、非阻塞事件驅動架構,能夠高效地處理大量并發連接。

  • 低資源消耗:相對于傳統的進程或線程模型,Nginx 使用更少的內存和 CPU 資源。

  • 模塊化設計:Nginx 的功能通過模塊實現,用戶可以根據需求加載不同的模塊。

  • 高可擴展性:通過第三方模塊和 Lua 腳本,Nginx 能夠輕松擴展其功能。

  • 豐富的功能:支持 HTTP/2、反向代理、負載均衡、緩存、SSL/TLS、WebSocket 等。

1.1.2 工作流程
  • 當有新的 HTTP 請求到達時,master 進程會將其分發給一個工作進程。

  • 工作進程處理請求,根據配置文件進行請求的處理,包括反向代理、負載均衡、靜態文件服務等。

  • 處理完成后,工作進程將響應返回給客戶端。

1.1.3 工作模式

????????Nginx有兩種工作模式,分別為單進程工作模式多進程工作模式

????????單進程工作模式:除了一個主進程外,還有一個工作進行。這個工作進程是單線程的。默認的工作模式

????????多進程工作模式:除了一個主進程外,還有一個工作進行,每一個進程包含多個線程。

1.1.4 nginx目錄結構

????????安裝完Nginx后,我們先來熟悉一下Nginx的目錄結構,重點目錄/文件如下:

  • conf/nginx.conf ---- nginx配置文件
  • html ---- 存放靜態文件 (html、CSS、Js等)
  • logs ---- 日志目錄,存放日志文件
  • sbin/nginx ---- 二進制文件,用于啟動、停止Nginx服務
1.1.5 nginx常用命令
1. ./nginx -t #檢查配置文件的語法的正確性,并嘗試打開配置文件中所引用到的文件。
2. ./nginx -c /home/xx/nginx.conf #指定一個配置文件,來代替缺省的。
3. ./nginx -v #nginx 的版本。
4. ./nginx -s reload #reload 會重新加載配置文件,Nginx服務不會中斷。而且reload時會測試conf語法等。
5. ./nginx #啟動nginx。
6. ./nginx -s stop #stop 會立即停止服務,這種方法比較強硬,無論進程是否在工作,都直接停止進程。
7. ./nginx -s quit #quit 較stop相比就比較溫和一些了,需要進程完成當前工作后再停止。

1.2 核心架構

????????Nginx 的核心架構設計是其高性能和高可用性的關鍵。核心架構包括模塊化設計、事件驅動模型、Master-Worker 進程模型和高效的請求處理流程。

1.2.1 模塊化設計

????????Nginx 采用模塊化設計,核心功能和擴展功能都通過模塊實現。模塊分為核心模塊、標準 HTTP 模塊和第三方模塊。用戶可以根據需要啟用或禁用模塊,靈活配置 Nginx 的功能。

? ? ? ? nginx從功能上分為如下四類:

**Core(核心模塊):**構建nginx基礎服務、管理其他模塊。**Handlers(處理器模塊):**此類模塊直接處理請求,主要負責處理客戶端請求并產生待響應內容。**Filters (過濾器模塊):**此類模塊主要對其他處理器模塊輸出的內容進行修改。**Upstraem (反代理類模塊):**此類模塊是實現反向代理的功能。
**load-balancer(負載均衡模塊)😗*實現特定的算法,從服務器中選擇一個合適的服務器進行相應請求

各模塊之間的http處理流程:
1)客戶端發送HTTP請求
2) Nginx從配置文件選擇一個合適的模塊 , (如果有)負載均衡模塊就根據相應的算法選擇一個合適的服務器
3)處理模塊對客戶端的請求進行處理,并把輸出緩沖放到第一個過濾模塊上
4) 第一個過濾模塊處理后輸出給第二個過濾模塊,依此類推
5) 最后把響應發給客戶端。
  • 核心模塊:包括 HTTP 模塊、事件模塊、解析器模塊等。實現 Nginx 的基本功能,如事件處理、內存管理、配置解析等。

    • Nginx 的 worker 進程分為核心模塊和功能性模塊。

    • 核心模塊主要負責維持一個運行循環(run-loop),在其中執行網絡請求處理的不同階段的模塊功能,如網絡讀寫、存儲讀寫、內容傳輸、外出過濾,以及將請求發往上游服務器等。

      • HTTP 模塊處理 HTTP 請求和響應,包括 HTTP 頭部解析、HTTP 請求方法解析、URI 解析等。

      • 事件模塊負責處理底層的事件通知機制,如 Epoll、Kqueue 等。

      • 解析器模塊負責解析 Nginx 配置文件。

    • Nginx 的代碼采用了模塊化設計,這使得我們可以根據需要選擇和修改功能模塊,然后編譯成具有特定功能的服務器。

  • 標準 HTTP 模塊:提供 HTTP 服務的功能,如靜態文件服務、反向代理、負載均衡等。

  • 第三方模塊:由社區或開發者提供,擴展 Nginx 的功能,如 Lua 模塊、Redis 模塊等。

# 配置示例:啟用和配置 HTTP 模塊
http {server {listen 80;server_name example.com;location / {root /var/www/html;index index.html index.htm;}location /proxy {proxy_pass http://backend_server;}}
}
1.2.2 事件驅動模型

????????Nginx 使用異步、非阻塞事件驅動模型,能夠高效地處理并發連接。基于異步及非阻塞的事件驅動模型是Nginx 實現高并發、高性能的關鍵。

????????事件驅動模型基于 epoll(Linux)、kqueue(FreeBSD)等高效的 I/O 多路復用機制,實現事件的高效分發和處理。????????

????????這種模型使得 Nginx 能夠高效地處理大量并發請求,而不會因為阻塞等待而降低性能。

  • 異步非阻塞:所有 I/O 操作都通過事件通知機制完成,不會阻塞進程。

    • Nginx 采用了事件驅動的模型,主要利用了操作系統提供的異步 I/O 機制。

    • 當有新的連接建立或者數據可讀寫時,Nginx 不會阻塞等待,而是通過事件通知機制處理這些事件,從而提高了處理效率。

  • 高效的事件分發:通過 epoll、kqueue 等機制,Nginx 能夠快速分發和處理大量并發連接的事件。

// 示例:基于 epoll 的事件循環
for (;;) {int n = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);for (int i = 0; i < n; i++) {if (events[i].events & EPOLLIN) {// 處理讀事件} else if (events[i].events & EPOLLOUT) {// 處理寫事件}}
}
1.2.3 Master-Worker 進程模型

????????Nginx 采用 Master-Worker 進程模型,確保高并發處理能力和高可靠性。Master 進程負責管理 Worker 進程,處理信號和管理共享資源。Worker 進程處理實際的請求,互不干擾,提高了并發處理能力和穩定性。

  • Master 進程:啟動、停止 Worker 進程,處理信號(如重新加載配置),管理共享資源(如緩存)。

  • Worker 進程:處理客戶端請求,每個 Worker 進程獨立處理不同的連接,避免相互影響。

# 配置示例:設置 Worker 進程數量
worker_processes auto;events {worker_connections 1024;
}
1.2.4 請求處理流程

????????Nginx 的請求處理流程高度優化,能夠高效地處理 HTTP 請求。主要流程包括接收請求、解析請求、選擇處理模塊、生成響應和發送響應。

  • 接收請求:通過事件驅動模型接收客戶端請求。

  • 解析請求:解析 HTTP 請求頭,生成請求上下文。

  • 選擇處理模塊:根據配置選擇相應的模塊處理請求,如靜態文件服務、反向代理等。

  • 生成響應:調用處理模塊生成響應數據。

  • 發送響應:通過事件驅動模型發送響應給客戶端。

# 配置示例:靜態文件服務和反向代理
http {server {listen 80;server_name example.com;location / {root /var/www/html;index index.html index.htm;}location /proxy {proxy_pass http://backend_server;}}
}

1.3 Nginx配置文件結構

...              #全局塊events {         #events塊...
}http      #http塊
{...   #http全局塊server        #server塊{ ...       #server全局塊location [PATTERN]   #location塊{...}location [PATTERN] {...}}server{...}...     #http全局塊
}

????????1、全局塊:配置影響nginx全局的指令。一般有運行nginx服務器的用戶組,nginx進程pid存放路徑,日志存放路徑,配置文件引入,允許生成worker process數等。

????????2、events塊:配置影響nginx服務器或與用戶的網絡連接。有每個進程的最大連接數,選取哪種事件驅動模型處理連接請求,是否允許同時接受多個網路連接,開啟多個網絡連接序列化等。

????????3、http塊:可以嵌套多個server,配置代理,緩存,日志定義等絕大多數功能和第三方模塊的配置。如文件引入,mime-type定義,日志自定義,是否使用sendfile傳輸文件,連接超時時間,單連接請求數等。

????????4、server塊:配置虛擬主機的相關參數,一個http中可以有多個server。

????????5、location塊:配置請求的路由,以及各種頁面的處理情況。

示例:

########### 每個指令必須有分號結束。#################
#user administrator administrators;  #配置用戶或者組,默認為nobody nobody。
#worker_processes 2;  #允許生成的進程數,默認為1
#pid /nginx/pid/nginx.pid;   #指定nginx進程運行文件存放地址
error_log log/error.log debug;  #制定日志路徑,級別。這個設置可以放入全局塊,http塊,server塊,級別以此為:debug|info|notice|warn|error|crit|alert|emerg
events {accept_mutex on;   #設置網路連接序列化,防止驚群現象發生,默認為onmulti_accept on;  #設置一個進程是否同時接受多個網絡連接,默認為off#use epoll;      #事件驅動模型,select|poll|kqueue|epoll|resig|/dev/poll|eventportworker_connections  1024;    #最大連接數,默認為512
}
http {include       mime.types;   #文件擴展名與文件類型映射表default_type  application/octet-stream; #默認文件類型,默認為text/plain#access_log off; #取消服務日志    log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定義格式access_log log/access.log myFormat;  #combined為日志格式的默認值sendfile on;   #允許sendfile方式傳輸文件,默認為off,可以在http塊,server塊,location塊。sendfile_max_chunk 100k;  #每個進程每次調用傳輸數量不能大于設定的值,默認為0,即不設上限。keepalive_timeout 65;  #連接超時時間,默認為75s,可以在http,server,location塊。upstream mysvr {   server 127.0.0.1:7878;server 192.168.10.121:3333 backup;  #熱備}error_page 404 https://www.baidu.com; #錯誤頁server {keepalive_requests 120; #單連接請求上限次數。listen       4545;   #監聽端口server_name  127.0.0.1;   #監聽地址       location  ~*^.+$ {       #請求的url過濾,正則匹配,~為區分大小寫,~*為不區分大小寫。#root path;  #根目錄#index vv.txt;  #設置默認頁proxy_pass  http://mysvr;  #請求轉向mysvr 定義的服務器列表deny 127.0.0.1;  #拒絕的ipallow 172.18.5.54; #允許的ip           } }
}需要注意的有以下幾點:1、1.$remote_addr 與$http_x_forwarded_for 用以記錄客戶端的ip地址; 2.$remote_user :用來記錄客戶端用戶名稱; 3.$time_local : 用來記錄訪問時間與時區;4.$request : 用來記錄請求的url與http協議;5.$status : 用來記錄請求狀態;成功是200, 6.$body_bytes_s ent :記錄發送給客戶端文件主體內容大小;7.$http_referer :用來記錄從那個頁面鏈接訪問過來的; 8.$http_user_agent :記錄客戶端瀏覽器的相關信息;2、驚群現象:一個網路連接到來,多個睡眠的進程被同事叫醒,但只有一個進程能獲得鏈接,這樣會影響系統性能。3、每個指令必須有分號結束。
1.3.1、localtion 路由匹配規則

????????什么是location? :?nginx根據用戶請求的URI來匹配對應的location模塊,匹配到哪個location,請求將被哪個location塊中的配置項所處理。

????????location配置語法:location [修飾符] pattern {…}

常見匹配規則如下:

修飾符作用
無修飾符的前綴匹配,匹配前綴是 你配置的(比如說你配的是 /aaa) 的url
=精確匹配
~正則表達式模式匹配,區分大小寫
~*正則表達式模式匹配,不區分大小寫
^~^~類型的前綴匹配,類似于無修飾符前綴匹配,不同的是,如果匹配到了,那么就停止后續匹配
/通用匹配,任何請求都會匹配到(只要你域名對,所有請求通吃!)
1.3.2、前綴匹配(無修飾符)

首先我提前創建了prefix_match.html文件,之后改一下nginx.conf文件(給前綴是 /prefixmatch 的請求返回 /etc/nginx/locatest/prefix_match.html 這個文件) ,如下:

image.png

然后在宿主機hosts中配置域名 172.30.128.65?http://www.locatest.com?映射后,觀察到nginx服務器返回內容如下:

image.png

curl http://www.locatest.com/prefixmatch     ? 301
curl http://www.locatest.com/prefixmatch?    ? 301
curl http://www.locatest.com/PREFIXMATCH     ? 404
curl http://www.locatest.com/prefixmatch/    ? 200
curl http://www.locatest.com/prefixmatchmmm  ? 404
curl http://www.locatest.com/prefixmatch/mmm ? 404
curl http://www.locatest.com/aaa/prefixmatch/? 404

可以看到?域名/prefixmatch?和域名/prefixmatch??返回了301 ,原因在于prefixmatch映射的 /etc/nginx/locatest/ 是個目錄,而不是個文件所以nginx提示我們301,這個我們不用管沒關系,總之我們知道:域名/prefixmatch域名/prefixmatch??和域名/prefixmatch/?這三個url通過我們配置的?無修飾符前綴匹配規則?都能匹配上就行了。

ps:為了方便,我們下邊的幾個location規則演示不再跳轉靜態文件了,而是直接return一句話。

1.3.3、精確匹配( = )

為了演示精確匹配,我們再給nginx.conf文件增加一個location配置,如下標紅處:

image.png

實際效果如下:

image.png

http://www.locatest.com/exactmatch      ? 200
http://www.locatest.com/exactmatch?    ? 200
http://www.locatest.com/exactmatch/     ? 404
http://www.locatest.com/exactmatchmmmm  ? 404
http://www.locatest.com/EXACTMATCH      ? 404

可以看出來精確匹配就是精確匹配,差一個字也不行!

1.3.4、前綴匹配( ^~ )

我們上邊說了不帶任何修飾符的前綴匹配(5.1小節),這里我們看下 修飾符是 ^~的 前綴匹配和不帶修飾符的前綴匹配有啥區別,先在ngnx.conf文件增加個location并配好如下:

image.png

curl效果如下:

image.png

curl http://www.locatest.com/exactprefixmatch     ? 200
curl http://www.locatest.com/exactprefixmatch/    ? 200
curl http://www.locatest.com/exactprefixmatch?    ? 200
curl http://www.locatest.com/exactprefixmatchmmm  ? 200
curl http://www.locatest.com/exactprefixmatch/mmm ? 200
curl http://www.locatest.com/aaa/exactprefixmatch ? 404
curl http://www.locatest.com/EXACTPREFIXMATCH     ? 404

可以看到帶修飾符(^~)的前綴匹配 像:域名/exactprefixmatchmmm?和域名/exactprefixmatch/mmm?是可以匹配上的,而不帶修飾符的前綴匹配這兩個類型的url是匹配不上的直接返回了404 ,其他的和不帶修飾符的前綴匹配似乎都差不多。

1.3.5、正則匹配(~ 區分大小寫)

ps:正則表達式的匹配,需要你對正則語法比較熟悉,熟悉語法后寫匹配規則也就得心應手了。

添加個location并配置,如下:( ^表示開頭,$表示結尾)

image.png

實際效果如下:

image.png

curl http://www.locatest.com/regexmatch      ? 200
curl http://www.locatest.com/regexmatch/     ? 404
curl http://www.locatest.com/regexmatch?     ? 200
curl http://www.locatest.com/regexmatchmmm   ? 404
curl http://www.locatest.com/regexmatch/mmm  ? 404
curl http://www.locatest.com/REGEXMATCH      ? 404
curl http://www.locatest.com/aaa/regexmatch  ? 404
curl http://www.locatest.com/bbbregexmatch   ? 404

可以看到~修飾的正則是區分大小寫的。接下來我們看下 不區分大小寫的匹配。

1.3.6、正則匹配(~* 不區分大小寫)

改下location 在修飾符~后加個

image.png

看下實際效果:

image.png

可以看到這次 curl?http://www.locatest.com/REGEXMATCH?是可以匹配上的,說明 ~?確實是不區分大小寫的。

1.3.7、通用匹配( / )

通用匹配使用一個 / 表示,可以匹配所有請求,一般nginx配置文件最后都會有一個通用匹配規則,當其他匹配規則均失效時,請求會被路由給通用匹配規則處理,如果沒有配置通用匹配,并且其他所有匹配規則均失效時,nginx會返回404錯誤。

image.png

通用匹配實際效果:

image.png

可以看到通用匹配很好理解,只要你域名寫對了,那么所有的url都會被匹配上,來者不拒的感覺。

1.3.8、關于location 匹配優先級

上邊我們說了6種location匹配規則,那么如果存在多個到底走哪個location呢?這就的說說location的匹配優先級了。先來看下nginx官網和stackoverflow上的資料如下:

image.png

image.png

綜上資料我們對location匹配優先級的總結如下:?1. 優先走精確匹配,精確匹配命中時,直接走對應的location,停止之后的匹配動作。 2.?無修飾符類型的前綴匹配和?^~ 類型的前綴匹配命中時,收集命中的匹配,對比出最長的那一條并存起來(最長指的是與請求url匹配度最高的那個location)。 3.?如果步驟2中最長的那一條匹配是^~類型的前綴匹配,直接走此條匹配對應的location并停止后續匹配動作;如果步驟2最長的那一條匹配不是^~類型的前綴匹配(也就是無修飾符的前綴匹配),則繼續往下匹配 5. 按location的聲明順序,執行正則匹配,當找到第一個命中的正則location時,停止后續匹配。 6. 都沒匹配到,走通用匹配( / )(如果有配置的話),如果沒配置通用匹配的話,上邊也都沒匹配上,到這里就是404了。

如果非要給修飾符排個序的話就是醬樣子:?=?>?^~?>?正則?>?無修飾符的前綴匹配?>?/

ok關于location就到這里,location是一個很重要的點,學好這個才知道nginx到底是咋匹配url的。

2. Nginx反向代理與負載均衡

????????Nginx 作為高性能的代理服務器,其代理原理是其設計的核心之一。無論是針對 HTTP 還是其他協議(如 FastCGI、Memcache、Redis 等)的網絡請求或響應,Nginx 都采用了代理機制來實現數據的轉發和處理。

????????Nginx 的代理原理主要基于以下幾個關鍵點:

????????接收請求:當 Nginx 接收到客戶端的請求時,根據配置文件中的代理設置,確定是否需要進行代理轉發。如果需要代理轉發,則根據配置選擇合適的代理方式。

????????建立連接:Nginx 會與目標服務器建立連接,可以是與遠程服務器建立 TCP 連接,也可以是與本地應用程序之間建立的 Unix Socket 連接,取決于代理目標的具體情況。

????????數據傳輸:一旦連接建立成功,Nginx 會將客戶端的請求數據轉發給目標服務器,并且在接收到目標服務器的響應后,再將響應數據返回給客戶端。這個過程可以是全雙工的,意味著 Nginx 可以同時接收客戶端請求和目標服務器響應,然后進行相應的轉發和處理。

????????代理緩存:為了進一步提高性能,Nginx 還支持代理緩存功能。它可以將經常請求的數據緩存在本地,避免每次請求都要向后端服務器發起請求,從而減少響應時間和網絡負載。

????????負載均衡:對于需要代理轉發的請求,Nginx 還支持負載均衡功能,可以根據一定的策略將請求分發到多個后端服務器上,以實現負載均衡和高可用性。

2.1 反向代理基礎

????????反向代理服務器在客戶端和服務器之間充當中介,接收客戶端的請求并將其轉發給后端服務器,然后將后端服務器的響應返回給客戶端。Nginx 作為反向代理服務器的優勢在于其高并發處理能力、靈活的配置和豐富的功能。

2.1.1 反向代理的優勢
  • 隱藏后端服務器:反向代理隱藏了后端服務器的真實 IP 和端口,提升了安全性。

  • 負載均衡:反向代理可以將請求分發到多臺后端服務器,實現負載均衡。

  • 緩存:反向代理服務器可以緩存后端服務器的響應,減少后端服務器的壓力,提高響應速度。

  • SSL 終止:反向代理服務器可以處理 SSL/TLS 加密,減輕后端服務器的負擔。

2.1.2 反向代理配置示例
http {upstream backend {server backend1.example.com;server backend2.example.com;}server {listen 80;server_name example.com;location / {proxy_pass http://backend;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;}}
}下面是一個整體的參考:nginx 配置反向代理轉發proxy_pass#=======================================location 帶/結尾=======================================
# 請求url http://127.0.0.1:8080/proxy/index.html
location /proxy/ {proxy_pass http://127.0.0.1:8080/;
}
# 代理地址以 "/" 結尾,代理轉發的url地址為:http://127.0.0.1:8080/index.htmllocation /proxy/ {proxy_pass http://127.0.0.1:8080;
}
# 代理地址不以 "/" 結尾,代理轉發的url地址為:http://127.0.0.1:8080/proxy/index.htmllocation /proxy/ {proxy_pass http://127.0.0.1:8080/tomcat/;
}
# 代理地址以 "tomcat/" 結尾,代理轉發的url地址為:http://127.0.0.1:8080/tomat/index.htmllocation /proxy/ {proxy_pass http://127.0.0.1:8080/tomcat;
}
# 代理地址以 "tomcat" 代理轉發的url地址為:http://127.0.0.1:8080/proxytomcat/index.html#=======================================location 不帶/結尾=======================================
location /proxy {proxy_pass http://127.0.0.1:8080/tomcat;
}
# 代理地址以 "tomcat" 代理轉發的url地址為:http://127.0.0.1:8080/tomcat/index.htmllocation /proxy {proxy_pass http://127.0.0.1:8080/;
}
# 代理地址以 "/" 代理轉發的url地址為:http://127.0.0.1:8080//index.htmllocation /proxy {proxy_pass http://127.0.0.1:8080;
}
# 代理地址不以 "/" 代理轉發的url地址為:http://127.0.0.1:8080/proxy/index.html#=======================================alias與root=======================================
location /test/ {alias /www/abc/;
}
# 使用alias,當訪問/test/時,會到/www/abc/目錄下找文件location /test/ {root /www/abc;
}
# 使用root,當訪問/test/時,會到/www/abc/test/目錄下找文件(如果沒有test目錄會報403)#================================多層nginx代理@Websocket服務=======================================
location /secure/socket {add_header backendIP $upstream_addr;add_header backendCode $upstream_status;proxy_redirect off;proxy_connect_timeout 6000;proxy_read_timeout 6000; proxy_send_timeout 6000;proxy_set_header Host 192.168.9.101:8087;proxy_pass http://localhost:8080/websocket/web;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade"; proxy_set_header token $arg_username; 
}
#================================多層nginx代理@Java服務=======================================
#主機127.0.0.1下的nginx配置,port=8081
location /local/app/ {proxy_pass http://10.9.103.36:8081/;
}
#主機10.9.103.36下的nginx配置,port=8081
location /chat/ {proxy_pass http://10.186.253.117:8081/;
}
#================================多層nginx代理@HTML資源=======================================
#主機10.9.103.35下的nginx配置,port=8083
location ^~ /html/chat/ {#符號^~:一旦匹配到,就不繼續匹配(靜態資源匹配)proxy_pass http://10.9.103.36:8081/;
}#主機10.9.103.36下的nginx配置,port=8081(下圖為html資源目錄結構)
location /mystatic {root html;index index.html index.htm;
}

2.2 負載均衡策略

????????Nginx 支持多種負載均衡策略,能夠根據不同的需求選擇合適的策略將請求分發到后端服務器。

名稱說明
輪詢默認方式
weight權重方式
ip_hash依據ip分配方式
least conn依據最少連接方式
url hash依據url分配方式
fair依據響應時間方式
2.2.1 輪詢 (Round Robin)

????????輪詢是 Nginx 的默認負載均衡策略,將請求依次分發到每臺后端服務器。該策略簡單高效,適用于后端服務器性能均衡的情況。

upstream backend {server backend1.example.com;server backend2.example.com;
}
2.2.2 最少連接 (Least Connections)

????????最少連接策略將請求分發到當前活動連接數最少的服務器,適用于后端服務器性能不均衡的情況。

upstream backend {least_conn;server backend1.example.com;server backend2.example.com;
}
2.2.3 IP 哈希 (IP Hash)

????????IP 哈希策略根據客戶端 IP 計算哈希值,將同一客戶端的請求分發到同一臺服務器,適用于需要會話保持的場景。

upstream backend {ip_hash;server backend1.example.com;server backend2.example.com;
}
2.2.4 權重 (Weight)

????????權重策略為每臺服務器設置權重,權重越高,服務器接收到的請求越多,適用于后端服務器性能不均衡且需要手動調整分配比例的情況。

upstream backend {server backend1.example.com weight=3;server backend2.example.com weight=1;
}

2.3 配置實例

????????下面提供幾個反向代理和負載均衡的實際配置示例,以幫助理解和應用這些概念。

2.3.1 基本反向代理配置
server {listen 80;server_name example.com;location / {proxy_pass http://backend1.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;}
}
2.3.2 動靜分離配置

????????動靜分離是指將動態請求和靜態請求分別處理,以提高效率。Nginx 可以將靜態文件請求直接由 Nginx 處理,而將動態請求轉發給后端服務器。

server {listen 80;server_name example.com;location / {proxy_pass http://backend1.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;}location /static/ {root /var/www/html;expires 30d;}
}
2.3.3 負載均衡配置
upstream backend {server backend1.example.com;server backend2.example.com;
}server {listen 80;server_name example.com;location / {proxy_pass http://backend;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;}
}

2.4 健康檢查

????????Nginx 還可以對后端服務器進行健康檢查,確保請求不會分發到不可用的服務器。通過配置?ngx_http_upstream_module?模塊,可以實現簡單的健康檢查功能。

upstream backend {server backend1.example.com;server backend2.example.com;server backend3.example.com down;
}server {listen 80;server_name example.com;location / {proxy_pass http://backend;}
}

????????在此配置中,backend3.example.com?被標記為?down,Nginx 將不會將請求分發到這臺服務器。更高級的健康檢查可以通過第三方模塊如?ngx_http_upstream_check_module?實現。

2.5 高級反向代理配置

2.5.1 緩存配置

????????Nginx 可以作為緩存服務器,通過緩存后端服務器的響應,減少后端服務器的負擔,提升響應速度。

proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;server {listen 80;server_name example.com;location / {proxy_cache my_cache;proxy_pass http://backend;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;}
}
2.5.2 SSL 終止

????????Nginx 可以處理 SSL/TLS 加密,解密客戶端請求后將其轉發給后端服務器,減輕后端服務器的加密負擔。

server {listen 443 ssl;server_name example.com;ssl_certificate /etc/nginx/ssl/nginx.crt;ssl_certificate_key /etc/nginx/ssl/nginx.key;location / {proxy_pass http://backend;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;}
}

2.6 HTTPS配置


#user  nobody;
worker_processes  1;#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;#pid        logs/nginx.pid;events {worker_connections  1024;
}http {include       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"';#access_log  logs/access.log  main;sendfile        on;#tcp_nopush     on;#keepalive_timeout  0;keepalive_timeout  65;#gzip  on;server {listen       443 ssl;server_name  mt.hello.com;#ssl          on;ssl_certificate     ../ssl/nj.crt;ssl_certificate_key ../ssl/nj.key;ssl_session_cache shared:SSL:1m;ssl_session_timeout 5m;ssl_ciphers HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers on;location /chat/ {proxy_pass http://jd.hello.com:8089;}}server {listen 80;#填寫綁定證書的域名server_name mt.hello.com;#強制將http的URL重寫成httpsrewrite ^(.*) https://$server_name$1 permanent; }server {listen       8081;server_name  mt.hello.com;location /chat/ {proxy_pass http://jd.hello.com:8089;}location /proxy/nginx/ {if ($host = 'mt.hello.com') {rewrite ^(.*)$ http://jd.hello.com/$1 permanent;}proxy_pass http://jd.hello.com:8089/;}location /proxy/ {if ($host = 'mt.hello.com') {rewrite ^(.*)$ http://www.baidu.com permanent;}proxy_pass http://jd.hello.com:8089/;}location /error/ {if ($host = 'jd.hello.com') {return 404;}proxy_pass http://jd.hello.com:8089/;}error_page 404 /404.html;error_page 500 502 503 504 /50x.html;location =/50x.html{root html;}location =/404.html{root html;}location /mystatic {root html;index index.html index.htm;}}}

3. Nginx性能優化

????????Nginx 以其高性能和高并發處理能力著稱,但在實際應用中,合理的性能優化策略仍能顯著提升其性能。本文將詳細探討 Nginx 的性能優化方法,包括配置優化、系統優化、緩存機制和高并發優化。

3.1 配置優化

????????Nginx 的配置對其性能有著至關重要的影響。合理的配置可以減少資源消耗,提高處理效率。

3.1.1 Worker 進程配置

????????Nginx 的?worker_processes?參數決定了處理請求的工作進程數量。一般建議將其設置為等于服務器的 CPU 核心數,以充分利用多核 CPU 的并行處理能力。

????????worker_cpu_affinity:將Nginx?作進程綁定到指定的CPU核?,默認Nginx是不進?進程綁定的。

# worker_processes auto;  #auto?表示自動檢測 CPU 核心數,并設置相應數量的工作進程。# 找到以下兩行,修改為合適的值
StartServers       8     # 初始啟動的進程數
MaxRequestWorkers  150   # 最大的并發請求處理數user  nginx nginx;                 # 啟動Nginx?作進程的??和組
worker_processes  [number | auto]; # 啟動Nginx?作進程的數量
worker_cpu_affinity 00000001 00000010 00000100 00001000;
# 將Nginx?作進程綁定到指定的CPU核?,默認Nginx是不進?進程綁定的,
# 綁定并不是意味著當前nginx進程獨 占以?核?CPU,但是可以保證此進程不會運?在其他核?上,
# 這就極?減少了nginx的?作進程在不同的cpu核 ?上的來回跳轉,減少了CPU對進程的資源分配與回收以及內存管理等,
#因此可以有效的提升nginx服務器的性 能。 此處CPU有四顆核心。也可寫成:
#worker_cpu_affinity 0001 0010 0100 1000;#cpu的親和能偶使nginx對于不同的work工作進程綁定到不同的cpu上面去。就能夠減少在work間不#斷切換cpu,把進程通常不會在處理器之間頻繁遷移,進程遷移的頻率小,來減少性能損耗。
#每個 worker 的線程可以把一個 cpu 的性能發揮到極致。所以 worker 數和服務器的 cpu 數相#等是最為適宜的。設少了會浪費 cpu,設多了會造成 cpu 頻繁切換上下文帶來的損耗
3.1.2 Worker 連接數配置

??worker_connections?參數決定了每個工作進程可以處理的最大連接數。為了提高并發處理能力,建議將其設置為盡可能大的值。

events {worker_connections 1024;
}

????????這個配置表示每個工作進程最多可以處理 1024 個并發連接。

3.1.3 緩存配置

????????Nginx 提供多種緩存機制,可以緩存后端服務器的響應,減少后端服務器的壓力,提高響應速度。常用的緩存機制包括 FastCGI 緩存和代理緩存。

proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;server {listen 80;server_name example.com;location / {proxy_cache my_cache;proxy_pass http://backend;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;}
}

????????這個配置創建了一個緩存區域?my_cache,并在反向代理時啟用了緩存。

3.2 系統優化

????????除了 Nginx 的配置優化,對操作系統的優化也能顯著提高 Nginx 的性能。

3.2.1 文件描述符限制

????????Nginx 處理大量并發連接時,需要打開大量的文件描述符。默認的文件描述符限制可能不足,需通過修改系統配置提高限制。

# 臨時修改
ulimit -n 65535# 永久修改,編輯 /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
3.2.2 TCP 連接優化

????????調整 TCP 連接參數,可以減少網絡延遲,提高并發處理能力。

# 調整內核參數,編輯 /etc/sysctl.conf
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30# 應用配置
sysctl -p

3.3 緩存機制

????????緩存是提升 Nginx 性能的重要手段。通過緩存機制,Nginx 可以將后端服務器的響應存儲在本地,減少后端服務器的負載。

3.3.1 FastCGI 緩存

????????FastCGI 緩存用于緩存 FastCGI 應用程序的響應,例如 PHP。

fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=fastcgi_cache:10m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";server {location ~ \.php$ {fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;fastcgi_index index.php;include fastcgi_params;fastcgi_cache fastcgi_cache;fastcgi_cache_valid 200 60m;fastcgi_cache_use_stale error timeout invalid_header updating;}
}
3.3.2 代理緩存

????????代理緩存用于緩存反向代理的響應,減少后端服務器的負載。

proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;server {location / {proxy_cache my_cache;proxy_pass http://backend;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;}
}

3.4 高并發優化

????????Nginx 在處理高并發連接時,通過異步非阻塞的事件驅動模型,能夠高效地處理大量并發連接。以下是一些針對高并發場景的優化策略。

3.4.1 啟用 keepalive

? ?keepalive?可以保持客戶端和服務器之間的連接,提高連接重用率,減少連接建立和釋放的開銷。

upstream backend {server backend1.example.com;server backend2.example.com;keepalive 32;
}server {location / {proxy_pass http://backend;proxy_http_version 1.1;proxy_set_header Connection "";}
}
3.4.2 調整緩沖區大小

????????調整 Nginx 的緩沖區大小,可以提高大文件傳輸的效率,減少內存碎片。

http {server {client_body_buffer_size 16K;client_header_buffer_size 1k;large_client_header_buffers 4 16k;output_buffers 1 32k;postpone_output 1460;}
}
3.4.3 啟用 Gzip 壓縮

????????啟用 Gzip 壓縮,可以減少傳輸的數據量,提高響應速度。

http {gzip on;gzip_types text/plain application/xml;gzip_min_length 1000;gzip_comp_level 5;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/40434.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/40434.shtml
英文地址,請注明出處:http://en.pswp.cn/web/40434.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

The Sandbox 人物化身每月獎勵: 七月版來了!

人物化身的持有者可以從 The Sandbox 領取自己的隊服&#xff01; 視頻&#xff1a;https://youtu.be/tSo5FPL7DhE 我們又推出了人物化身所有者月度獎勵&#xff01;在七月&#xff0c;我們將通過 The Sandbox 隊服來弘揚體育競技精神。穿上這些時尚的元宇宙隊服&#xff0c;代…

Java:HashMap底層原理

一、前言 在Java 7及之前的版本中&#xff0c;HashMap的底層數據結構主要是數組加鏈表&#xff0c;在Java 8中&#xff0c;HashMap的底層數據結構是數組鏈表紅黑樹的組合。 二、底層數據結構 1. 數組 初始化和擴容&#xff1a;HashMap首先會初始化一個指定長度的數組&#xf…

單機多網卡互通——問題跟蹤+工具分析

一、背景 想搭建soft ROCE(RXE)與實體ROCE設備互聯的測試環境&#xff0c;為了節省機器以及使用方便&#xff0c;預想在配備ROCE卡的主機上&#xff0c;用另一個網卡綁定soft ROCE&#xff0c;然后互通。 [ETH1 ROCE] <--------------------> [ETH2 RXE] 二、問題跟…

Appium元素定位(全網詳細講解)(二)

1.appium inspector&#xff08;定位元素的工具&#xff09;使用方法 詳細介紹&#xff1a; 詳細解釋&#xff1a; 圖標名稱說明1Show Element Handles是否顯示元素句柄2Select Elements選擇元素定位3Tap/Swipe By Coordinates按坐標點擊/滑動4Download Screenshot下載屏幕截…

2024機器遺忘(Machine Unlearning)技術分類-思維導圖

1 介紹 機器遺忘&#xff08;Machine Unlearning&#xff09;是指從機器學習模型中安全地移除或"遺忘"特定的數據點或信息。這個概念源于數據隱私保護的需求&#xff0c;尤其是在歐盟通用數據保護條例&#xff08;GDPR&#xff09;等法規中提出的"被遺忘的權利…

【漏洞復現】飛企互聯-FE企業運營管理平臺——SQL注入

聲明&#xff1a;本文檔或演示材料僅供教育和教學目的使用&#xff0c;任何個人或組織使用本文檔中的信息進行非法活動&#xff0c;均與本文檔的作者或發布者無關。 文章目錄 漏洞描述漏洞復現測試工具 漏洞描述 飛企互聯-FE企業運營管理平臺是一個基于云計算、智能化、大數據…

【8】相關補充

【8】相關補充 文章目錄 前言一、不同模型在測試集上的精度二、實驗記錄三、SNP位點篩選及其它python腳本四、總結五、后續安排總結 前言 存放一些有關這個項目研究的補充。 三葉青圖像識別研究簡概 一、不同模型在測試集上的精度 存放了不同識別模型在測試集上精度評估展示…

Java中的時間日期處理與時區管理

Java中的時間日期處理與時區管理 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 在現代軟件開發中&#xff0c;時間日期處理和時區管理是至關重要的部分。Jav…

Android HWASAN使用與實現原理

一、背景 為了提前檢測出Android User Sapce的app或native進程的內存錯誤問題&#xff0c;幫助研發定位與分析這些問題&#xff0c;基于Android 14版本上對HWASAN做了調研分析。 二、ASAN介紹 HWASAN是在ASAN的基礎上做了拓展&#xff0c;因此在介紹HWASAN之前先了解下ASAN.…

ES8.13.0 java client請求響應報錯status: 200, [es/search] Failed to decode response

最近在做商城項目使用ES8.13.0做商品復雜的檢索功能時&#xff0c;遇到一個報錯如下&#xff1a; 2024-07-05 10:47:53.994 ERROR 10708 --- [nio-7500-exec-1] com.tfq.exception.RRExceptionHandler : co.elastic.clients.transport.TransportException: node: http://1…

WBCE CMS v1.5.2 遠程命令執行漏洞(CVE-2022-25099)

前言 CVE-2022-25099 是一個影響 WBCE CMS v1.5.2 的嚴重安全漏洞&#xff0c;具體存在于 /languages/index.php 組件中。該漏洞允許攻擊者通過上傳精心構造的 PHP 文件在受影響的系統上執行任意代碼。 技術細節 受影響組件&#xff1a;/languages/index.php受影響版本&…

如何在 Odoo 16 中向新視圖添加字段

例如,讓我們看看如何在新視圖或新操作窗口中創建“many2one”字段。 請考慮下面的屏幕截圖,它表示不包含任何字段的新視圖類型或客戶端操作窗口。 我們現在可以將與“res.partner”關聯的“多對一”字段引入到我們的新視圖或客戶端操作窗口中。 為了實現這一點,在 XML 模板…

ShardingSphere

ShardingSphere 是一個開源的分布式數據庫中間件生態系統&#xff0c;由 Apache 基金會孵化和維護。它的主要目標是幫助開發者解決分庫分表、分布式事務和數據加密等分布式數據庫應用中的常見問題。ShardingSphere 提供了多種組件&#xff0c;如 Sharding-JDBC、Sharding-Proxy…

Using a text embedding model locally with semantic kernel

題意&#xff1a;在本地使用帶有語義核&#xff08;Semantic Kernel&#xff09;的文本嵌入模型 問題背景&#xff1a; Ive been reading Stephen Toubs blog post about building a simple console-based .NET chat application from the ground up with semantic-kernel. Im…

idea中maven全局配置

配置了就不需要每次創建項目都來設置maven倉庫了。 1.先把項目全關了 2. 進入全局設置 3.設置maven的倉庫就可以了

SpringBoot實現多數據源切換

1. 概述 隨著項目規模的擴大和業務需求的復雜化&#xff0c;單一數據源已經不能滿足實際開發中的需求。在許多情況下&#xff0c;我們需要同時操作多個數據庫&#xff0c;或者需要將不同類型的數據存儲在不同的數據庫中。這時&#xff0c;多數據源場景成為必不可少的解決方案。…

【CentOS7.6】docker部署EMQX教程,本地鏡像直接導入(附下載鏈接),沒法在云服務器上魔法拉取鏡像的快來

總覽 先把下載鏈接放在這里吧&#xff0c;這是 EMQX 的 tar 包&#xff0c;能夠直接導入 CentOS 的 docker&#xff1a; 鏈接&#xff1a;https://pan.baidu.com/s/1rSGSLoVvj83ai6d5oolg8Q?pwd0108 提取碼&#xff1a;0108 一、安裝配置教程 1.將 EMQX-latest.tar 包導入…

服務器重裝系統時數據丟失?有哪些方法可以避免

為了避免在服務器重裝系統時數據丟失&#xff0c;可以采取以下預防措施&#xff1a; 1. 數據備份&#xff1a;在重裝系統之前&#xff0c;備份所有重要的數據和配置文件。備份可以通過以下方式進行&#xff1a; - 使用外部存儲設備(如USB硬盤、NAS等)進行備份。 - 利用備份軟件…

學習成績總是上不去?中學生把握好這5個環節,助你提高成績

在中學時代&#xff0c;考試我們并不陌生。每隔一段時間&#xff0c;學校就會安排我們參加考試。學生時代&#xff0c;我們參加的考試有很多。對于中學生來說&#xff0c;考試成績是我們一直關心的事情。很多學生非常努力的學習&#xff0c;成績卻上不去。這是非常可惜的&#…

[圖解]企業應用架構模式2024新譯本講解19-數據映射器1

1 00:00:01,720 --> 00:00:03,950 下一個我們要講的就是 2 00:00:04,660 --> 00:00:07,420 數據映射器這個模式 3 00:00:09,760 --> 00:00:13,420 這個也是在數據源模式里面 4 00:00:13,430 --> 00:00:14,820 用得最廣泛的 5 00:00:16,250 --> 00:00:19,170…