NGINX的整體架構的特點是由一組進程協同工作:
主進程:負責執行特權操作,如閱讀配置文件、綁定套接字、創建/通知協調(Signalling)子進程。
工作進程:負責接收和處理連接請求,讀取和寫入磁盤,并與上游服務器通信。當NGINX處于活躍狀態時,只有工作進程是忙碌的。
緩存加載器進程:負責將磁盤高速緩存加載到內存中。這個進程在啟動時運行后隨即退出。
緩存管理器進程:負責整理磁盤緩存的數據保證其不越界。這個進程會間歇性運行。
NGINX能夠實現高性能和可擴展性的關鍵取決于兩個基本的設計選型:
盡可能限制工作進程的數量,從而減少上下文切換帶來的開銷。默認和推薦配置是讓每個CPU內核對應一個工作進程,從而高效利用硬件資源。
工作進程采用單線程,并以非阻塞的方式處理多個并發連接。
NGINX的每個工作進程通過狀態機處理多個連接請求,這個狀態機被實現為非阻塞的工作方式:
每個工作進程需要處理若干套接字,包括監聽套接字或者連接套接字。
當監聽套接字收到新的請求時,會打開一個新的連接套接字來處理與客戶端的通信。
當一個事件到達連接套接字時,工作進程迅速完成響應,并轉而處理其他任何套接字新收到的事件。
Garrett說,NGINX選擇這樣的設計,使它從根本上區別于其他Web服務器。通常的Web服務器會選用將每個連接分配給獨立線程的模式,這使得多個連接的處理非常容易,因為每個連接可以被認為是包含多個步驟的一個線性序列,但這樣會產生上下文切換的開銷。事實上,工作線程大部分的時間處于阻塞的狀態,在等待客戶端或其它上游服務器。當試圖執行I/O等操作的并發連接數/線程數的規模超過一定閾值,或是內存消耗殆盡的時候,上下文切換的成本就顯現出來了。
從另一方面講,NGINX的設計是不讓工作進程阻止網絡流量,除非沒有任何工作要做。此外,每一個新的連接只消耗很少的資源,僅包括一個文件描述符和少量的工作進程內存。
總的來說,NGINX的這種工作模式在系統調優后,它的每個工作進程都能夠處理成百上千的HTTP并發連接。
深入NGINX:我們如何設計它的性能和擴展性
NGINX之所以能在性能上如此優越,是由于其背后的設計。許多web服務器和應用服務器使用簡單的線程的(threaded)、或基于流程的(process-based)架構,NGINX則以一種復雜的事件驅動(event-driven)的架構脫穎而出,這種架構能支持現代硬件上成千上萬的并發連接。
Inside NGINX infographic涉及了從高層次進程架構的挖掘,到NGINX的單進程處理多連接的圖解。本篇文章講解了這些工作細節。
新聞熱點
疑難解答