站長資訊網
        最全最豐富的資訊網站

        “小白”帶你們了解有關于Nginx的模塊與工作原理吧!!!

        NGINX以高性能的負載均衡器,緩存,和web服務器聞名,驅動了全球超過 40% 最繁忙的網站,因此

        有一定的參考價值,有需要的朋友可以參考一下,希望對大家有所幫助

        “小白”帶你們了解有關于Nginx的模塊與工作原理吧!!!

        一. Nginx的模塊與工作原理


        Nginx由內核和模塊組成,其中,內核的設計非常微小和簡潔,完成的工作也非常簡單,僅僅通過查找配置文件將客戶端請求映射到一個location block(location是Nginx配置中的一個指令,用于URL匹配),而在這個location中所配置的每個指令將會啟動不同的模塊去完成相應的工作。

        Nginx的模塊從結構上分為核心模塊、基礎模塊和第三方模塊:

        核心模塊:HTTP模塊、EVENT模塊和MAIL模塊

        基礎模塊:HTTP Access模塊、HTTP FastCGI模塊、HTTP Proxy模塊和HTTP Rewrite模塊,

        第三方模塊:HTTP Upstream Request Hash模塊、Notice模塊和HTTP Access Key模塊。

        用戶根據自己的需要開發的模塊都屬于第三方模塊。正是有了這么多模塊的支撐,Nginx的功能才會如此強大。

        Nginx的模塊從功能上分為如下三類。

        Handlers(處理器模塊)。此類模塊直接處理請求,并進行輸出內容和修改headers信息等操作。Handlers處理器模塊一般只能有一個。

        Filters (過濾器模塊)。此類模塊主要對其他處理器模塊輸出的內容進行修改操作,最后由Nginx輸出。

        Proxies (代理類模塊)。此類模塊是Nginx的HTTP Upstream之類的模塊,這些模塊主要與后端一些服務比如FastCGI等進行交互,實現服務代理和負載均衡等功能。

        圖1-1展示了Nginx模塊常規的HTTP請求和響應的過程。

        “小白”帶你們了解有關于Nginx的模塊與工作原理吧!!!

        Nginx本身做的工作實際很少,當它接到一個HTTP請求時,它僅僅是通過查找配置文件將此次請求映射到一個location block,而此location中所配置的各個指令則會啟動不同的模塊去完成工作,因此模塊可以看做Nginx真正的勞動工作者。通常一個location中的指令會涉及一個handler模塊和多個filter模塊(當然,多個location可以復用同一個模塊)。handler模塊負責處理請求,完成響應內容的生成,而filter模塊對響應內容進行處理。

        Nginx的模塊直接被編譯進Nginx,因此屬于靜態編譯方式。啟動Nginx后,Nginx的模塊被自動加載,不像Apache,首先將模塊編譯為一個so文件,然后在配置文件中指定是否進行加載。在解析配置文件時,Nginx的每個模塊都有可能去處理某個請求,但是同一個處理請求只能由一個模塊來完成。

        二. Nginx的進程模型


        在工作方式上,Nginx分為單工作進程和多工作進程兩種模式。在單工作進程模式下,除主進程外,還有一個工作進程,工作進程是單線程的;在多工作進程模式下,每個工作進程包含多個線程。Nginx默認為單工作進程模式。

        Nginx在啟動后,會有一個master進程和多個worker進程。

        1、master進程:管理進程

        master進程主要用來管理worker進程,具體包括如下4個主要功能:
        (1)接收來自外界的信號。
        (2)向各worker進程發送信號。
        (3)監控woker進程的運行狀態。
        (4)當woker進程退出后(異常情況下),會自動重新啟動新的woker進程。

        用戶交互接口:master進程充當整個進程組與用戶的交互接口,同時對進程進行監護。它不需要處理網絡事件,不負責業務的執行,只會通過管理worker進程來實現重啟服務、平滑升級、更換日志文件、配置文件實時生效等功能。

        重啟work進程:我們要控制nginx,只需要通過kill向master進程發送信號就行了。比如kill -HUP pid,則是告訴nginx,從容地重啟nginx,我們一般用這個信號來重啟nginx,或重新加載配置,因為是從容地重啟,因此服務是不中斷的。

        master進程在接收到HUP信號后是怎么做的呢?

        1)、首先master進程在接到信號后,會先重新加載配置文件,然后再啟動新的worker進程,并向所有老的worker進程發送信號,告訴他們可以光榮退休了。

        2)、新的worker在啟動后,就開始接收新的請求,而老的worker在收到來自master的信號后,就不再接收新的請求,并且在當前進程中的所有未處理完的請求處理完成后,再退出。

        直接給master進程發送信號,這是比較傳統的操作方式,nginx在0.8版本之后,引入了一系列命令行參數,來方便我們管理。比如,./nginx -s reload,就是來重啟nginx,./nginx -s stop,就是來停止nginx的運行。如何做到的呢?我們還是拿reload來說,我們看到,執行命令時,我們是啟動一個新的nginx進程,而新的nginx進程在解析到reload參數后,就知道我們的目的是控制nginx來重新加載配置文件了,它會向master進程發送信號,然后接下來的動作,就和我們直接向master進程發送信號一樣了。

        2、worker進程:處理請求

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

        worker進程之間是平等的,每個進程,處理請求的機會也是一樣的。當我們提供80端口的http服務時,一個連接請求過來,每個進程都有可能處理這個連接,怎么做到的呢?

        Nginx采用異步非阻塞的方式來處理網絡事件,類似于Libevent,具體過程如下:

        1)接收請求:首先,每個worker進程都是從master進程fork過來,在master進程建立好需要listen的socket(listenfd)之后,然后再fork出多個worker進程。所有worker進程的listenfd會在新連接到來時變得可讀,每個work進程都可以去accept這個socket(listenfd)。當一個client連接到來時,所有accept的work進程都會受到通知,但只有一個進程可以accept成功,其它的則會accept失敗。為保證只有一個進程處理該連接,Nginx提供了一把共享鎖accept_mutex來保證同一時刻只有一個work進程在accept連接。所有worker進程在注冊listenfd讀事件前搶accept_mutex,搶到互斥鎖的那個進程注冊listenfd讀事件,在讀事件里調用accept接受該連接。

        2)處理請求:當一個worker進程在accept這個連接之后,就開始讀取請求,解析請求,處理請求,產生數據后,再返回給客戶端,最后才斷開連接,這樣一個完整的請求就是這樣的了。

        我們可以看到,一個請求,完全由worker進程來處理,而且只在一個worker進程中處理。worker進程之間是平等的,每個進程,處理請求的機會也是一樣的。

        nginx的進程模型,可以由下圖來表示:

        “小白”帶你們了解有關于Nginx的模塊與工作原理吧!!!

        “小白”帶你們了解有關于Nginx的模塊與工作原理吧!!!

        三. Nginx為啥性能高-多進程IO模型


        參考http://mp.weixin.qq.com/s?__biz=MjM5NTg2NTU0Ng==&mid=407889757&idx=3&sn=cfa8a70a5fd2a674a91076f67808273c&scene=23&srcid=0401aeJQEraSG6uvLj69Hfve#rd

        1、nginx采用多進程模型好處

        首先,對于每個worker進程來說,獨立的進程,不需要加鎖,所以省掉了鎖帶來的開銷,同時在編程以及問題查找時,也會方便很多。

        其次,采用獨立的進程,可以讓互相之間不會影響,一個進程退出后,其它進程還在工作,服務不會中斷,master進程則很快啟動新的worker進程。當然,worker進程的異常退出,肯定是程序有bug了,異常退出,會導致當前worker上的所有請求失敗,不過不會影響到所有請求,所以降低了風險。

        2、nginx多進程事件模型:異步非阻塞

        雖然nginx采用多worker的方式來處理請求,每個worker里面只有一個主線程,那能夠處理的并發數很有限啊,多少個worker就能處理多少個并發,何來高并發呢?非也,這就是nginx的高明之處,nginx采用了異步非阻塞的方式來處理請求,也就是說,nginx是可以同時處理成千上萬個請求的。一個worker進程可以同時處理的請求數只受限于內存大小,而且在架構設計上,不同的worker進程之間處理并發請求時幾乎沒有同步鎖的限制,worker進程通常不會進入睡眠狀態,因此,當Nginx上的進程數與CPU核心數相等時(最好每一個worker進程都綁定特定的CPU核心),進程間切換的代價是最小的。

        而apache的常用工作方式(apache也有異步非阻塞版本,但因其與自帶某些模塊沖突,所以不常用),每個進程在一個時刻只處理一個請求因此,當并發數上到幾千時,就同時有幾千的進程在處理請求了。這對操作系統來說,是個不小的挑戰,進程帶來的內存占用非常大,進程的上下文切換帶來的cpu開銷很大,自然性能就上不去了,而這些開銷完全是沒有意義的。

        “小白”帶你們了解有關于Nginx的模塊與工作原理吧!!!

        為什么nginx可以采用異步非阻塞的方式來處理呢,或者異步非阻塞到底是怎么回事呢?具體請看:使用 libevent 和 libev 提高網絡應用性能——I/O模型演進變化史

        我們先回到原點,看看一個請求的完整過程:首先,請求過來,要建立連接,然后再接收數據,接收數據后,再發送數據。

        具體到系統底層,就是讀寫事件,而當讀寫事件沒有準備好時,必然不可操作,如果不用非阻塞的方式來調用,那就得阻塞調用了,事件沒有準備好,那就只能等了,等事件準備好了,你再繼續吧。阻塞調用會進入內核等待,cpu就會讓出去給別人用了,對單線程的worker來說,顯然不合適,當網絡事件越多時,大家都在等待呢,cpu空閑下來沒人用,cpu利用率自然上不去了,更別談高并發了。好吧,你說加進程數,這跟apache的線程模型有什么區別,注意,別增加無謂的上下文切換。所以,在nginx里面,最忌諱阻塞的系統調用了。不要阻塞,那就非阻塞嘍。非阻塞就是,事件沒有準備好,馬上返回EAGAIN,告訴你,事件還沒準備好呢,你慌什么,過會再來吧。好吧,你過一會,再來檢查一下事件,直到事件準備好了為止,在這期間,你就可以先去做其它事情,然后再來看看事件好了沒。雖然不阻塞了,但你得不時地過來檢查一下事件的狀態,你可以做

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 久久99精品久久久久子伦| 99久久精品九九亚洲精品| 久久成人国产精品二三区| 亚洲国产精品成人| 国产精品极品| 亚洲精品视频在线| 国产精品网站在线观看免费传媒| 亚洲精品乱码久久久久久不卡 | 国产成人久久精品一区二区三区| 亚洲国产精品ⅴa在线观看| 精品久久久久中文字幕一区| 99久久www免费人成精品| 久久国产精品国产自线拍免费| 国内精品久久久久影院日本| 无码精品久久久久久人妻中字| 四虎国产精品永久在线看| 精品人妻少妇一区二区三区在线 | 欧美精品v国产精品v日韩精品| 亚洲欧美精品午睡沙发| 日韩精品中文字幕第2页| 精品伦精品一区二区三区视频| 国产精品内射视频免费| 国产精品.XX视频.XXTV| 88国产精品无码一区二区三区| 99久久精品免费| 国产国拍亚洲精品福利| 国产福利电影一区二区三区,欧美国产成人精品一 | 国产精品亚洲综合专区片高清久久久 | 国产精品91视频| 国产精品美女久久久| 国产精品专区第二| 久久精品国产久精国产| 久久国产精品久久精品国产| 久久线看观看精品香蕉国产| 亚洲国语精品自产拍在线观看| 日本久久久精品中文字幕| 色花堂国产精品第一页| 99精品人妻少妇一区二区| 国产精品亚洲玖玖玖在线观看 | 国产亚洲福利精品一区| 在线观看91精品国产入口|