簡體   English   中英

nginx:它的多線程但使用多個進程?

[英]nginx : Its Multithreaded but uses multiple processes?

我試圖理解是什么讓Nginx這么快,我有幾個問題。

據我所知,Apache會生成一個新進程來為每個請求提供服務,或者生成一個新線程來為每個請求提供服務。 由於每個新線程共享虛擬地址空間,因此如果有多個並發請求進入,則內存使用率會不斷攀升。

Nginx通過只有一個監聽進程(Master),一個執行線程AND 2或3(數字是可配置的)工作進程來解決這個問題。 此主進程/線程正在運行事件循環。 有效地等待任何傳入的請求。 當請求進入時,它會將請求提供給其中一個工作進程。

如果我的上述理解不正確,請糾正我

如果以上是正確的,那么我有幾個問題:

1.)工作進程是否會產生多個線程並且會遇到與apache相同的問題?

2.)或者nginx是快速的,因為它的基於事件的架構在它下面使用非阻塞IO。 也許工作進程產生的線程只做非阻塞IO,是嗎?

3.)“完全”是什么“基於事件的架構”,有人可以真正簡化它,對於像我這樣的soemone來理解。 它是否僅適用於非阻塞io或其他類似的東西?

我得到了c10k的參考,我試圖通過它,但我不認為它是基於事件的拱。 對於非阻塞IO來說似乎更多。

Apache使用多個線程為每個請求提供自己的執行線程。 這對於避免在使用同步I / O時阻塞是必要的。

Nginx僅使用異步I / O,這使得阻止非問題。 nginx使用多個進程的唯一原因是充分利用多核,多CPU和超線程系統。 即使支持SMP,內核也無法在多個CPU上調度單個執行線程。 每個邏輯CPU至少需要一個進程或線程。

所以不同的是,nginx 需要足夠的工作進程來獲得SMP的全部好處,而Apache的架構需要為每個請求創建一個新線程(每個線程都有大約8MB左右的堆棧)。 顯然,在高並發性的情況下,Apache將使用更多的內存,並且在維護大量線程時會遇到更大的開銷。

從概念的角度來看,這並不是很復雜。 我會盡力清楚,但我必須做一些簡化。

基於事件的服務器(如nginxlighttpd )使用事件監視系統周圍的包裝器。 例如。 lighttpd使用libevent來抽象更高級的高速事件監控系統(參見libev )。

服務器使用每個連接的簡單狀態機跟蹤它具有的所有非阻塞連接(寫入和讀取)。 當有新數據可用或何時可以寫入更多數據時,事件監視系統會通知服務器進程。 就像你知道套接字編程一樣,它就像是類固醇上的select() 然后,服務器進程只使用sendfile()等高級函數發送請求的文件,或者使用套接字將請求轉換為CGI進程進行通信(此套接字將使用事件監視系統監視,如其他網絡連接。)

這個鏈接作為關於nginx內部的很多很好的信息,以防萬一。 我希望它有所幫助。

Apache不會為每個請求生成新線程。 它維護一個線程緩存或一組預分叉進程,並將請求分配給它。 並發請求的數量受到子/線程數的限制,但是apache並沒有為每個請求產生一個新的線程/子進程,這會非常慢(即使有線程,每次請求的創建和拆除都會太慢) )

Nginx使用主工作者模型。 主進程處理加載配置和創建/銷毀/維護工作程序。 就像apache一樣,它開始時已經運行了許多預先分叉的進程,每個進程都是一個worker(其中一個是“master”進程)。 每個工作進程共享一組偵聽套接字。 每個工作進程都接受連接並處理它們,但每個工作程序可以同時處理數千個連接,這與apache不同,apache每個worker只能處理1個連接。

nginx實現這一目標的方式是通過“多路復用”。 它不使用libevent,它使用專門為nginx設計的自定義事件循環,並隨着nginx軟件的開發而在開發中增長。 多路復用通過使用循環來通過在一個數據/新連接/每個循環迭代的每個連接/對象上操作的塊來“遞增”通過程序塊來工作。 它都基於后端,如Epoll()kqueue()和select()。 您應該閱讀哪些內容

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM