<dt draggable='71sttmr'></dt>

                      1. 文章熱詞:Nginx,Apache

                        日期:2019-03-05 17:25 by 楊國偉 1461 0 收藏
                        我要分享

                        摘要:Nginx才短短幾年,就拿下了web服務器大筆江山,衆所周知,Nginx在處理大并發靜态請求方面,效率明顯高于httpd,甚至能輕松解決C10K問題。

                        Nginx才短短幾年,就拿下了web服務器大筆江山,衆所周知,Nginx在處理大并發靜态請求方面,效率明顯高于httpd,甚至能輕松解決C10K問題。

                        在高并發連接的情況下,Nginx是Apache服務器不錯的替代品。Nginx同時也可以作爲7層負載均衡服務器來使用。根據我的測試結果,Nginx 0.7.14 + PHP 5.2.6 (FastCGI) 可以承受3萬以上的并發連接數,相當于同等環境下Apache的10倍。

                        一般來說,4GB内存的服務器+Apache(prefork模式)一般隻能處理3000個并發連接,因爲它們将占用3GB以上的内存,還得爲系統預留1GB的内存。我曾經就有兩台Apache服務器,因爲在配置文件中設置的MaxClients爲4000,當Apache并發連接數達到3800時,導緻服務器内存和Swap空間用滿而崩潰。

                        20180411053952290.jpg

                        而這台 Nginx 0.7.14 + PHP 5.2.6 (FastCGI) 服務器在3萬并發連接下,開啓的10個Nginx進程消耗150M内存(15M*10=150M),開啓的64個php-cgi進程消耗1280M内存(20M*64=1280M),加上系統自身消耗的内存,總共消耗不到2GB内存。如果服務器内存較小,完全可以隻開啓25個php-cgi進程,這樣php-cgi消耗的總内存數才500M。

                        在3萬并發連接下,訪問Nginx 0.7.14 + PHP 5.2.6 (FastCGI) 服務器的PHP程序,仍然速度飛快。

                        爲什麽Nginx在處理高并發方面要優于httpd,我們先從兩種web服務器的工作原理以及工作模式說起。

                        apache三種工作模式

                        我們都知道Apache有三種工作模塊,分别爲prefork、worker、event。

                        prefork:多進程,每個請求用一個進程響應,這個過程會用到select機制來通知。

                        worker:多線程,一個進程可以生成多個線程,每個線程響應一個請求,但通知機制還是select不過可以接受更多的請求。

                        event:基于異步I/O模型,一個進程或線程,每個進程或線程響應多個用戶請求,它是基于事件驅動(也就是epoll機制)實現的。

                        4.2 prefork的工作原理

                        如果不用“--with-mpm”顯式指定某種MPM,prefork就是Unix平台上缺省的MPM.它所采用的預派生子進程方式也是 Apache1.3中采用的模式。prefork本身并沒有使用到線程,2.0版使用它是爲了與1.3版保持兼容性;另一方面,prefork用單獨的子進程來處理不同的請求,進程之間是彼此獨立的,這也使其成爲最穩定的MPM之一。

                        4.3 worker的工作原理

                        相對于prefork,worker是2.0版中全新的支持多線程和多進程混合模型的MPM。由于使用線程來處理,所以可以處理相對海量的請求,而系統資源的開銷要小于基于進程的服務器。但是,worker也使用了多進程,每個進程又生成多個線程,以獲得基于進程服務器的穩定性,這種MPM的工作方 式将是Apache2.0的發展趨勢。

                        4.4 event 基于事件機制的特性

                        一個進程響應多個用戶請求,利用callback機制,讓套接字複用,請求過來後進程并不處理請求,而是直接交由其他機制來處理,通過epoll機制來通知請求是否完成;在這個過程中,進程本身一直處于空閑狀态,可以一直接收用戶請求。可以實現一個進程程響應多個用戶請求。支持持海量并發連接數,消耗更少的資源。

                        如何提高Web服務器的并發連接處理能力

                        有幾個基本條件:

                        1.基于線程,即一個進程生成多個線程,每個線程響應用戶的每個請求。

                        2.基于事件的模型,一個進程處理多個請求,并且通過epoll機制來通知用戶請求完成。

                        3.基于磁盤的AIO(異步I/O)

                        4.支持mmap内存映射,mmap傳統的web服務器,進行頁面輸入時,都是将磁盤的頁面先輸入到内核緩存中,再由内核緩存中複制一份到web服務器上,mmap機制就是讓内核緩存與磁盤進行映射,web服務器,直接複制頁面内容即可。不需要先把磁盤的上的頁面先輸入到内核緩存去。

                        剛好,Nginx 支持以上所有特性。所以Nginx官網上說,Nginx支持50000并發,是有依據的。

                        Nginx優異之處

                        傳統上基于進程或線程模型架構的web服務通過每進程或每線程處理并發連接請求,這勢必會在網絡和I/O操作時産生阻塞,其另一個必然結果則是對内存或CPU的利用率低下。生成一個新的進程/線程需要事先備好其運行時環境,這包括爲其分配堆内存和棧内存,以及爲其創建新的執行上下文等。這些操作都需要占用CPU,而且過多的進程/線程還會帶來線程抖動或頻繁的上下文切換,系統性能也會由此進一步下降。另一種高性能web服務器/web服務器反向代理:Nginx(Engine X),nginx的主要着眼點就是其高性能以及對物理計算資源的高密度利用,因此其采用了不同的架構模型。受啓發于多種操作系統設計中基于“事件”的高級處理機制,nginx采用了模塊化、事件驅動、異步、單線程及非阻塞的架構,并大量采用了多路複用及事件通知機制。在nginx中,連接請求由爲數不多的幾個僅包含一個線程的進程worker以高效的回環(run-loop)機制進行處理,而每個worker可以并行處理數千個的并發連接及請求。

                        Nginx 工作原理

                        Nginx會按需同時運行多個進程:一個主進程(master)和幾個工作進程(worker),配置了緩存時還會有緩存加載器進程(cache loader)和緩存管理器進程(cache manager)等。所有進程均是僅含有一個線程,并主要通過“共享内存”的機制實現進程間通信。主進程以root用戶身份運行,而worker、cache loader和cache manager均應以非特權用戶身份運行。

                        在高連接并發的情況下,Nginx是Apache服務器不錯的替代品

                        Nginx 安裝非常的簡單 , 配置文件非常簡潔(還能夠支持perl語法),Bugs 非常少的服務器: Nginx 啓動特别容易, 并且幾乎可以做到7*24不間斷運行,即使運行數個月也不需要重新啓動. 你還能夠 不間斷服務的情況下進行軟件版本的升級 。

                        Nginx 的誕生主要解決C10K問題

                        最後我們從各自使用的多路複用IO模型來分析:

                        select模型:(apache使用,由于受模塊等限制,用的不多)

                        單個進程能夠 監視的文件描述符的數量存在最大限制

                        select()所維護的 存儲大量文件描述符的數據結構 ,随着文件描述符數量的增長,其在用戶态和内核的地址空間的複制所引發的開銷也會線性增長

                        由于網絡響應時間的延遲使得大量TCP連接處于非活躍狀态,但調用select()還是會對 所有的socket進行一次線性掃描 ,會造成一定的開銷

                        poll:poll是unix沿用select自己重新實現了一遍,唯一解決的問題是poll 沒有最大文件描述符數量的限制

                        epoll模型:(nginx使用)

                        epoll帶來了兩個優勢,大幅度提升了性能:

                        基于事件的就緒通知方式 ,select/poll方式,進程隻有在調用一定的方法後,内核才會對所有監視的文件描述符進行掃描,而epoll事件通過epoll_ctl()注冊一個文件描述符,一旦某個文件描述符就緒時,内核會采用類似call back的回調機制,迅速激活這個文件描述符,epoll_wait()便會得到通知

                        調用一次epoll_wait()獲得就緒文件描述符時,返回的并不是實際的描述符,而是一個代表就緒描述符數量的值,拿到這些值去epoll指定的一個數組中依次取得相應數量的文件描述符即可,這裏使用内存映射(mmap)技術, 避免了複制大量文件描述符帶來的開銷

                        當然epoll也有一定的局限性, epoll隻有Linux2.6才有實現 ,而其他平台都沒有,這和apache這種優秀的跨平台服務器,顯然是有些背道而馳了。

                        簡單來說epoll是select的升級版,單進程管理的文件描述符沒有最大限制。但epoll隻有linux平台可使用。作爲跨平台的Apache沒有使用


                        上一篇:前任3——經典語錄

                        下一篇:常用正規表達式


                        評論


                        wz:
                        03月12日 10:42
                        @Mr. Yang 回複測試

                        Mr. Yang:
                        03月05日 20:31

                        測試