1.先從各自使用的多路復用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沒有使用。
2.再看一下Apache常用的兩種并發策略:
? ? ??1)?perfork模式的工作原理:??
? ? ? ? ? ? ? ? ? ? 當Apache被啟動時,Apache會自動創建StartServers個進程,并且盡力將空閑進程數保持在MinSpareServers和MaxSpareServers之間。
????????????? ? ? ??如果空閑進程小于MinSpareServers,Apache將會以大約每秒1個的速度新建進程。
? ? ? ? ? ? ? ? ? ? 如果空閑進程小于MaxSpareServers,Apache將會刪除多余的空閑進程,釋放服務器資源。
? ? ? ? ? ? ? ? ? ??進程數的最大值由MaxClients控制,在Apache1.3中最大只能設置為256,但在Apache2.0中,可以通過在配置開頭增加ServerLimit項目來突破256的限制,此時必須MaxClients ?≤ ServerLimit ≤ 20000
? ? ? ? ? ? ? ? ? ??MaxRequestsPerChild用來控制每個進程在處理了多少次請求之后自動銷毀,這個參數可以設置為0表示無限(即不銷毀進程)
? ? ?2) worker模式的工作原理:
? ? ? ? ? ??由主控制進程生成“StartServers”個子進程,每個子進程中包含固定的ThreadsPerChild線程數,各個線程獨立地處理請求。
? ? ? ? ? ??同樣,為了不在請求到來時再生成線程,MinSpareThreads和MaxSpareThreads設置了最少和最多的空閑線程數;而MaxClients設置允許的最大線程總數。
? ? ? ? ? ??如果現有子進程中的線程總數不能滿足負載,控制進程將派生新的子進程。
? ? ? ? ? ?每個子線程處理服務請求次數由MaxRequestPerChild定義。 缺省的設置值為0,即響應無限此請求。
? ? ? ? ? ?默認生成3個子進程來處理請求。
??兩種策略的缺陷:
? ? ? ??perfork模式:每一個連接創建一個進程,每個進程內單線程。對于一個負載相對較高的網站來說,256的進程限制是不夠的,如果服務器已經達到256的極限,那么接下去的訪問就需要排隊,這也就是為什么某些服務器負載不高,但是訪問卻很慢的原因之一。
? ? ? ??worker模式:也是多進程處理,也會創建多個進程和多個線程,如果進程數達到管理員設置的閥值,則會拒絕新的請求。
? ? ? ?兩種模式都會創建多個進程或線程,而每個進程或線程都會為其分配cpu和內存(線程要比進程小的多,所以worker支持比perfork高的并發),并發過大會榨干服務器資源。
3.Nginx的工作原理:
? ? ??Nginx并不會為每一個的web請求創建新的進程,相反,管理員可以配置Nginx主進程的工作進程的數量(一個常見的做法是為每一個CPU配置一個工作進程)。所有這些進程都是單線程的。
? ? ? 每一個工作進程可以處理數千個并發的請求。它通過一個線程來異步非阻塞的完成了這些工作(epoll),而沒有使用多線程的編程模型。
?
? nginx的優勢:
? ? ? 采用單線程來異步非阻塞處理請求,不會為每個請求分配cpu和內存資源,節省了大量資源,同時也減少了大量的CPU的上下文切換。所以才使得Nginx支持更高的并發。
?