搜尋
首頁運維Nginxnginx效能為什麼好

nginx效能為什麼好

Jun 12, 2019 am 10:11 AM
nginx效能

nginx效能為什麼好

nginx在啟動後,在unix系統中會以daemon的方式在背景執行,後台程式包含一個master行程和多個worker行程。我們也可以手動地關掉後台模式,讓nginx在前台運行,並且透過配置讓nginx取消master進程,從而可以使nginx以單一進程方式運行。

很顯然,生產環境下我們肯定不會這麼做,所以關閉後台模式,一般是用來調試用的,在後面的章節裡面,我們會詳細地講解如何調試nginx。

所以,我們可以看到,nginx是以多進程的方式來工作的,當然nginx也是支援多執行緒的方式的,只是我們主流的方式還是多進程的方式,也是nginx的預設方式。 nginx採用多進程的方式有諸多好處,所以我就主要講解nginx的多進程模式吧。

剛剛講到,nginx在啟動後,會有一個master進程和多個worker進程。 master進程主要用來管理worker進程,包含:接收來自外界的訊號,向各worker進程發送訊號,監控worker進程的運作狀態,當worker進程退出後(異常情況下),會自動重新啟動新的worker進程。

而基本的網路事件,則是放在worker進程中來處理了。多個worker進程之間是對等的,他們同等競爭來自客戶端的請求,各進程相互之間是獨立的。一個請求,只可能在一個worker進程中處理,一個worker進程,不可能處理其它進程的請求。 worker進程的數量是可以設定的,一般我們會設定與機器cpu核數一致,這裡面的原因與nginx的進程模型以及事件處理模型是分不開的。

在nginx啟動後,如果我們要操作nginx,要怎麼做呢?

從上文我們可以看到,master來管理worker進程,所以我們只需要與master進程通訊就行了。 master進程會接收來自外界發來的訊號,再根據訊號做不同的事情。所以我們要控制nginx,只需要透過kill向master進程發送訊號就行了。例如kill -HUP pid,則是告訴nginx,從容地重啟nginx,我們一般用這個訊號來重啟nginx,或重新載入配置,因為是從容地重啟,因此服務是不中斷的。 master行程在接收HUP訊號後是怎麼做的呢?

首先master進程在接到訊號後,會先重新載入設定文件,然後再啟動新的worker進程,並向所有舊的worker進程發送訊號,告訴他們可以光榮退休了。

新的worker在啟動後,就開始接收新的請求,而舊的worker在收到來自master的訊號後,就不再接收新的請求,並且在目前進程中的所有未處理完的請求處理完成後,再退出。

當然,直接給master進程發送訊號,這是比較老的操作方式,nginx在0.8版本之後,引入了一系列命令列參數,來方便我們管理。例如,./nginx -s reload,就是來重啟nginx,./nginx -s stop,就是來停止nginx的運作。

如何做到的呢?

我們還是拿reload來說,我們看到,執行指令時,我們是啟動一個新的nginx進程,而新的nginx進程在解析到reload參數後,就知道我們的目的是控制nginx來重新載入設定檔了,它會向master進程發送訊號,然後接下來的動作,就跟我們直接向master進程發送訊號一樣了。

現在,我們知道了當我們在操作nginx的時候,nginx內部做了些什麼事情,那麼,worker進程又是如何處理請求的呢?我們前面有提到,worker進程之間是平等的,每個進程,處理請求的機會也是一樣的。當我們提供80埠的http服務時,一個連接請求過來,每個行程都有可能處理這個連接,怎麼做到的呢?

首先,每個worker行程都是從master行程fork過來,在master行程裡面,先建立好需要listen的socket(listenfd)之後,再fork出多個worker行程。所有worker進程的listenfd會在新連接到來時變得可讀,為確保只有一個進程處理該連接,所有worker進程在註冊listenfd讀取事件前搶accept_mutex,搶到互斥鎖的那個進程註冊listenfd讀取事件,在讀取事件裡呼叫accept接受該連線。

當一個worker進程在accept這個連接之後,就開始讀取請求,解析請求,處理請求,產生資料後,再返回給客戶端,最後才斷開連接,這樣一個完整的請求就是這樣的了。我們可以看到,一個請求,完全由worker進程來處理,而且只在一個worker進程中處理。

多執行緒模型 VS 多進程模型,這是個問題!

那麼,nginx採用這種進程模型有什麼好處呢?當然,好處一定會很多了。首先,對於每個worker進程來說,獨立的進程,不需要加鎖,所以省掉了鎖帶來的開銷,同時在程式設計以及問題查找時,也會方便很多。其次,採用獨立的進程,可以讓互相之間不會影響,一個進程退出後,其它進程還在工作,服務不會中斷,master進程則很快啟動新的worker進程。當然,worker進程的異常退出,肯定是程式有bug了,異常退出,會導致目前worker上的所有請求失敗,不過不會影響到所有請求,所以降低了風險。當然,好處還有很多,大家可以慢慢體會。

上面講了很多關於nginx的進程模型,接下來,我們來看看nginx是如何處理事件的。

有人可能要問了,nginx採用多worker的方式來處理請求,每個worker裡面只有一個主線程,那能夠處理的並發數很有限啊,多少個worker就能處理多少個並發,何來高並發呢?非也,這就是nginx的高明之處,nginx採用了非同步非阻塞的方式來處理請求,也就是說,nginx是可​​以同時處理成千上萬個請求的。

想想apache的常用工作方式(apache也有異步非阻塞版本,但因其與自帶某些模組衝突,所以不常用),每個請求會獨佔一個工作線程,當並發數上到幾千時,就同時有幾千的線程在處理請求了。這對作業系統來說,是個不小的挑戰,執行緒帶來的記憶體佔用非常大,執行緒的上下文切換帶來的cpu開銷很大,自然效能就上不去了,而這些開銷完全是沒有意義的。

同步阻塞 VS 非同步非阻塞

為什麼nginx可以採用非同步非阻塞的方式來處理呢,或是非同步非阻塞到底是怎麼回事呢?我們先回到原點,看看一個請求的完整過程。首先,請求過來,要建立連接,然後再接收數據,接收數據後,再發送數據。具體到系統底層,就是讀寫事件,而當讀寫事件沒有準備好時,必然不可操作,如果不用非阻塞的方式來調用,那就得阻塞調用了,事件沒有準備好,那就只能等了,等事件準備好了,你再繼續吧。阻塞呼叫會進入核心等待,cpu就會讓出去給別人用了,對單線程的worker來說,顯然不合適,當網路事件越多時,大家都在等待呢,cpu空閒下來沒人用,cpu利用率自然上不去了,更別談高並發了。

好吧,你說加進程數,這跟apache的執行緒模型有什麼差別,注意,別增加無謂的上下文切換。所以,在nginx裡面,最忌諱阻塞的系統呼叫了。不要阻塞,那就非阻塞嘍。非阻塞就是,事件還沒準備好,馬上回到EAGAIN,告訴你,事件還沒準備好呢,你慌什麼,過會再來吧。好吧,你過一會,再來檢查一下事件,直到事件準備好了為止,在這期間,你就可以先去做其它事情,然後再來看看事件好了沒。雖然不阻塞了,但你得不時地過來檢查一下事件的狀態,你可以做更多的事情了,但帶來的開銷也是不小的。所以,才會有了非同步非阻塞的事件處理機制,具體到系統呼叫就是像select/poll/epoll/kqueue這樣的系統呼叫。

它們提供了一種機制,讓你可以同時監控多個事件,調用他們是阻塞的,但可以設定超時時間,在超時時間之內,如果有事件準備好了,就返回。這個機制正好解決了我們上面的兩個問題,拿epoll為例(在後面的例子中,我們多以epoll為例子,以代表這一類函數),當事件沒準備好時,放到epoll裡面,事件準備好了,我們就去讀寫,當讀寫返回EAGAIN時,我們將它再次加入到epoll裡面。這樣,只要有事件準備好了,我們就去處理它,只有當所有事件都沒準備好時,才在epoll裡面等著。這樣,我們就可以並發處理大量的並發了,當然,這裡的並發請求,是指未處理完的請求,線程只有一個,所以同時能處理的請求當然只有一個了,只是在請求間進行不斷地切換而已,切換也是因為非同步事件未準備好,而主動讓出的。這裡的切換是沒有任何代價,你可以理解為循環處理多個準備好的事件,事實上就是這樣的。

與多線程相比,這種事件處理方式是有很大的優勢的,不需要創建線程,每個請求佔用的內存也很少,沒有上下文切換,事件處理非常的輕量級級。並發數再多也不會導致無謂的資源浪費(上下文切換)。更多的並發數,只是會佔用更多的記憶體而已。我之前有對連線數進行過測試,在24G記憶體的機器上,處理的並發請求數達到200萬。現在的網頁伺服器基本上都採用這種方式,這也是nginx效能高效的主要原因。

我們之前說過,推薦設定worker的個數為cpu的核數,在這裡就很容易理解了,更多的worker數,只會導致進程來競爭cpu資源了,從而帶來不必要的上下文切換。

而且,nginx為了更好的利用多核心特性,提供了cpu親緣性的綁定選項,我們可以將某一個進程綁定在某一個核上,這樣就不會因為進程的切換帶來cache的失效。像這種小的優化在nginx中非常常見,同時也說明了nginx作者的苦心孤詣。例如,nginx在做4個位元組的字串比較時,會將4個字元轉換成一個int型,再作比較,以減少cpu的指令數等等。

現在,知道了nginx為什麼會選擇這樣的行程模型與事件模型了。對於一個基本的web伺服器來說,事件通常有三種類型,網路事件、訊號、定時器。從上面的講解中知道,網路事件透過非同步非阻塞可以很好的解決掉。如何處理訊號與定時器?

首先,訊號的處理。

對nginx來說,有一些特定的訊號,代表著特定的意義。訊號會中斷掉程式目前的運行,改變狀態後,繼續執行。如果是系統調用,則可能會導致系統調用的失敗,需要重入。關於訊號的處理,大家可以學習一些專業書籍,這裡不多說。對於nginx來說,如果nginx正在等待事件(epoll_wait時),如果程式收到訊號,在訊號處理函數處理完後,epoll_wait會回傳錯誤,然後程式可再次進入epoll_wait呼叫。

另外,再來看看定時器。由於epoll_wait等函數在呼叫的時候是可以設定一個超時時間的,所以nginx借助這個超時時間來實現定時器。 nginx裡面的定時器事件是放在一顆維護定時器的紅黑樹裡面,每次在進入epoll_wait前,先從該紅黑樹裡面拿到所有定時器事件的最小時間,在計算出epoll_wait的超時時間後進入epoll_wait。

所以,當沒有事件產生,也沒有中斷訊號時,epoll_wait會超時,也就是說,計時器事件到了。這時,nginx會檢查所有的逾時事件,將他們的狀態設為超時,然後再去處理網路事件。由此可以看出,當我們寫nginx程式碼時,在處理網路事件的回呼函數時,通常做的第一個事情就是判斷超時,然後再去處理網路事件。

更多Nginx相關知識,訪問Nginx使用教學欄位! 

以上是nginx效能為什麼好的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
NGINX的優點:速度,效率和控制NGINX的優點:速度,效率和控制May 12, 2025 am 12:13 AM

NGINX受歡迎的原因是其在速度、效率和控制方面的優勢。 1)速度:採用異步、非阻塞處理,支持高並發連接,靜態文件服務能力強。 2)效率:內存使用低,負載均衡功能強大。 3)控制:通過靈活的配置文件管理行為,模塊化設計便於擴展。

NGINX與Apache:社區,支持和資源NGINX與Apache:社區,支持和資源May 11, 2025 am 12:19 AM

NGINX和Apache在社區、支持和資源方面的差異如下:1.NGINX的社區雖然規模較小,但活躍度和專業性高,官方支持通過NGINXPlus提供高級功能和專業服務。 2.Apache擁有龐大且活躍的社區,官方支持主要通過豐富的文檔和社區資源提供。

NGINX單元:應用程序服務器簡介NGINX單元:應用程序服務器簡介May 10, 2025 am 12:17 AM

NGINXUnit是一個開源的應用服務器,支持多種編程語言和框架,如Python、PHP、Java、Go等。 1.它支持動態配置,可以在不重啟服務器的情況下調整應用配置。 2.NGINXUnit支持多語言應用,簡化了多語言環境的管理。 3.通過配置文件,可以輕鬆部署和管理應用,如運行Python和PHP應用。 4.它還支持高級配置,如路由和負載均衡,幫助管理和擴展應用。

使用NGINX:優化網站性能和可靠性使用NGINX:優化網站性能和可靠性May 09, 2025 am 12:19 AM

NGINX可通过以下方式提升网站性能和可靠性:1.作为Web服务器处理静态内容;2.作为反向代理服务器转发请求;3.作为负载均衡器分配请求;4.作为缓存服务器减轻后端压力。通过配置优化如启用Gzip压缩和调整连接池,NGINX能显著提高网站性能。

NGINX的目的:服務Web內容等NGINX的目的:服務Web內容等May 08, 2025 am 12:07 AM

nginxserveswebcontentandactsasareverseproxy,loadBalancer和more.1)效率高效的servesstaticContentLikeHtmlandImages.2)itfunctionsasareverseproxybalancer,and andginxenhanceperforfforfforfforfforfforffrenfcaching.4)

NGINX單元:簡化應用程序部署NGINX單元:簡化應用程序部署May 07, 2025 am 12:08 AM

NGINXUnit通過動態配置和多語言支持簡化應用部署。 1)動態配置無需重啟服務器即可修改。 2)支持多種編程語言,如Python、PHP、Java。 3)採用異步非阻塞I/O模型,提升高並發處理性能。

NGINX的影響:Web服務器及其他NGINX的影響:Web服務器及其他May 06, 2025 am 12:05 AM

NGINX起初解決C10K問題,現已發展為處理負載均衡、反向代理和API網關的全能選手。 1)它以事件驅動和非阻塞架構聞名,適合高並發。 2)NGINX可作為HTTP和反向代理服務器,支持IMAP/POP3。3)其工作原理基於事件驅動和異步I/O模型,提升了性能。 4)基本用法包括配置虛擬主機和負載均衡,高級用法涉及復雜負載均衡和緩存策略。 5)常見錯誤包括配置語法錯誤和權限問題,調試技巧包括使用nginx-t命令和stub_status模塊。 6)性能優化建議包括調整worker參數、使用gzip壓縮和

NGINX故障排除:診斷和解決常見錯誤NGINX故障排除:診斷和解決常見錯誤May 05, 2025 am 12:09 AM

Nginx常見錯誤的診斷與解決方法包括:1.查看日誌文件,2.調整配置文件,3.優化性能。通過分析日誌、調整超時設置和優化緩存及負載均衡,可以有效解決404、502、504等錯誤,提高網站穩定性和性能。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能