Nginx 之三:nginx服務器模塊、web請求處理機制及事件驅動模型、進程功能和進程間通信


一:Nginx的模塊化結構設計:

1、核心模塊:指的是nginx服務器運行當中必不可少的模塊,這些模塊提供了最基本最核心的服務,比如權限控制、進程管理、錯誤日志、事件驅動、正則表達式解析等,nginx的源碼模塊位於/root/nginx-1.8.1/src目錄:

[root@Server1 src]# pwd
/root/nginx-1.8.1/src
[root@Server1 src]# ls
core   #核心模塊
event #事件模塊
http #http模塊
mail #郵件模塊
misc #其他模塊
os #系統模塊

2、標准HTTP模塊:默認即被編譯到了Nginx當中,除非使用--with-out-module_name參數聲明不編譯,如:

ngx_http_core  #配置端口、URL分析、服務器響應錯誤處理,別名控制以及其他HTTP核心事物。
ngx_http_auth_basic_module #基於http的認證
ngx_http_access_module #基於IP地址的訪問控制策略
ngx_http_autoindex_module #處理以“/”結尾的請求並自動生成目錄列表。
ngx_http_browser_module #解析HTTP請求頭中的”User-Agent“ 的值。
ngx_http_charset_module#指定網頁的編碼。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

3、可選HTTP模塊:

ngx_http_perl_module #在nginx 的配置文件中可以使用perl腳本。
ngx_http_flv_module  #支持flash多媒體信息文件傳輸。
ngx_http_gzip_module #支持時時壓縮
ngx_http_image_filter_module #支持JPEG,GIF和PNG的圖片的尺寸和旋轉方向
ngx_http_ssl_module  #支持對HTTPS/SSL的支持
ngx_http_sub_module  #支持使用指定的字符串替換相應信息的中的信息

4、郵件模塊;默認沒有編譯,使用的場景也不多。

ngx_mail_auth_http_module.c
ngx_mail.c
ngx_mail_core_module.c
ngx_mail.h
ngx_mail_handler.c
ngx_mail_imap_handler.c
ngx_mail_imap_module.c
ngx_mail_imap_module.h
ngx_mail_parse.c
ngx_mail_pop3_handler.c
ngx_mail_pop3_module.c
ngx_mail_pop3_module.h
ngx_mail_proxy_module.c
ngx_mail_smtp_handler.c
ngx_mail_smtp_module.c
ngx_mail_smtp_module.h
ngx_mail_ssl_module.c
ngx_mail_ssl_module.h

5、第三方模塊:

echo-nginx-module #支持在配置文件中使用echo、sleep、time即exec等類似shell命令。
memc-nginx-module #對標准http模塊ngx_http_memcached_module的擴展,支持set、add、delete等命令
lua-nginx-module #支持lua腳本語言

6、安裝 echo-nginx-module 模塊:

6.1:模塊地址: https://github.com/openresty/echo-nginx-module.git

6.2:進到在nginx源碼目錄下,執行編譯安裝echo-nginx-module模塊:

cd nginx-1.8.1
./configure   --prefix=/usr/local/nginx/ --add-module=/home/tianqi/echo-nginx-module-master
make
make install

6.3:配置nginx.conf:

server {
        listen       80;
        server_name  hfnginx.chinacloudapp.cn;
        location / {
            root   html;
            index  index.html index.htm;
            echo $remote_addr;
            echo $remote_port;
            echo "zhangjie";
        }

6.4:訪問測試:

6.5:Nginx模塊組織工作圖:

 

二:web請求處理機制:

1、多進程方式:服務器沒接受到一個客戶端請求就有服務器的主進程生成一個子進程響應客戶端,直到用戶關閉連接,這樣的優勢是處理速度快,子進程之間相互獨立,但是如果訪問過大會導致服務器資源耗盡而無法提供請求。

2、多線程方式:與多進程方式類似,但是每收到一個客戶端請求會有服務進程派生出一個線程來個客戶方進行交互,一個線程的開銷遠遠小於一個進程,因此多線程方式在很大程度減輕了web服務器對系統資源的要求,但是多線程也有自己的缺點,即當多個線程位於同一個進程內工作的時候,可以相互訪問同樣的內存地址空間,所以他們相互影響,一旦主進程掛掉則所有子線程都不能工作了,IIS服務器使用了多線程的方式,需要間隔一段時間就重啟一次才能穩定。

 

三:同步和異步、阻塞與非阻塞:

1、同步與異步:主要是針對應用程序與內核的交互方式而言的:

同步:進程發出數據后,等內核返回響應以后才繼續下一個請求,即如果內核一直不返回數據,那么進程就一直等,直到天荒地老,死機error。

異步:進程發出數據后,不等內核返回響應,接着處理下一個請求,Nginx是異步的。

2、阻塞與非阻塞:

可以理解為內核與IO設備的交互方式,當內核收到進程請求IO數據時候的處理方式:

也可以簡單理解為內核需要做一件事能不能立即得到返回應答,如果不能立即獲得返回,需要等待,那就阻塞了,否則就可以理解為非阻塞。

阻塞:IO調用不能立即返回結果,即一個進程發起的IO請求不能得到立即滿足時,進程就要一直等到內核響應,內核要把數據從IO設備復制到內核空間,再返回給進程,這是阻塞。

非阻塞:IO調用可以立即返回結果,一個進程發起的IO進程不能立即滿足時,不在等待,而是一遍一遍的輪訓查看IO是否完成。

詳細區別如下圖所示:

 

3、混合總結:

3.1:同步阻塞:程序進程向內核發送IO請求后一直等待內核響應,如果內核處理請求的IO操作不能立即返回,則進程將一直等待並不再接受新的請求,並由進程輪訓查看IO是否完成,完成后進程將IO結果返回給Client,在IO沒有返回期間進程不能接受其他客戶的請求,而且是有進程自己去查看IO是否完成,這種方式簡單,但是比較慢,用的比較少。

3.2:同步非阻塞:,進程向內核發送請IO求后一直等待內核響應,如果內核處理請求的IO操作不能立即返回IO結果,進程將不再等待,而且繼續處理其他請求,但是仍然需要進程隔一段時間就要查看內核IO是否完成。

3.3:異步阻塞:event-diver,進程向內核發送IO調用后,不用等待內核響應,可以繼續接受其他請求,內核收到進程請求后進行的IO如果不能立即返回,就由內核等待結果,直到IO完成后內核再通知進程,此方式比較占用內核,因此也很少使用。

3.4:異步非阻塞:AIO,進程向內核發送IO調用后,不用等待內核響應,可以繼續接受其他請求,內核調用的IO如果不能立即返回,內核會繼續處理其他事物,直到IO完成后將結果通知給內核,內核在將IO完成的結果返回給進程,期間進程可以接受新的請求,內核也可以處理新的事物,因此相互不影響,可以實現較大的同時並實現較高的IO復用,因此異步非阻塞使用最多的一種通信方式。

 

 四:Nginx支持的事件驅動模型:

 1、select:

select庫是在linux和windows平台都基本支持的 事件驅動模型庫,並且在接口的定義也基本相同,只是部分參數的含義略有差異,最大並發限制1024,只最早期的事件驅動模型。

2、poll:

 在Linux 的基本驅動模型,windows不支持此驅動模型,是select的升級版,取消了最大的並發限制,在編譯nginx的時候可以使用--with-poll_module和--without-poll_module這兩個指定是否編譯select庫。

3、epoll:

epoll是庫是Nginx服務器支持的最高性能的事件驅動庫之一,是公認的非常優秀的事件驅動模型,它和select和poll有很大的區別,epoll是poll的升級版,但是與poll的效率有很大的區別.
epoll的處理方式是創建一個待處理的事件列表,然后把這個列表發給內核,返回的時候在去輪訓檢查這個表,以判斷事件是否發生,epoll支持一個進程打開的最大事件描述符的上限是系統可以打開的文件的最大數,同時epoll庫的IO效率不隨描述符數目增加而線性下降,因為它只會對內核上報的“活躍”的描述符進行操作。

4、rtsig:

不是一個常用事件驅動,最大隊列1024,不是很常用

5、kqueue:

用於支持BSD系列平台的高校事件驅動模型,主要用在FreeBSD 4.1及以上版本、OpenBSD 2.0級以上版本,NetBSD級以上版本及Mac OS X 平台上,該模型也是poll庫的變種,因此和epoll沒有本質上的區別,都是通過避免輪訓操作提供效率。

 6、/dev/poll:

用於支持unix衍生平台的高效事件驅動模型,主要在Solaris 平台、HP/UX,該模型是sun公司在開發Solaris系列平台的時候提出的用於完成事件驅動機制的方案,它使用了虛擬的/dev/poll設備,開發人員將要見識的文件描述符加入這個設備,然后通過ioctl()調用來獲取事件通知,因此運行在以上系列平台的時候請使用/dev/poll事件驅動機制。

7、eventport:

該方案也是sun公司在開發Solaris的時候提出的事件驅動庫,只是Solaris 10以上的版本,該驅動庫看防止內核崩潰等情況的發生。

 

五:Nginx 進程的功能和進程間的通信:

1、主進程(woker process)的功能:

讀取Nginx 配置文件並驗證其有效性和正確性
建立、綁定和關閉socket連接
按照配置生成、管理和結束工作進程
接受外界指令,比如重啟、升級及退出服務器等指令
不中斷服務,實現平滑升級,重啟服務並應用新的配置
開啟日志文件,獲取文件描述符
不中斷服務,實現平滑升級,升級失敗進行回滾處理
編譯和處理perl腳本

2、工作進程(woker process)的功能:

接受處理客戶的請求
將請求以此送入各個功能模塊進行處理
IO調用,獲取響應數據
與后端服務器通信,接收后端服務器的處理結果
緩存數據,訪問緩存索引,查詢和調用緩存數據
發送請求結果,響應客戶的請求
接收主程序指令,比如重啟、升級和退出等

3、Ninx進程間的通信:

3.1:主進程和工作進程之間的通信:

    工作進程是有主進程生成的,主進程使用fork()函數,在Nginx服務器啟動過程中主進程根據配置文件決定啟動工作進程的數量,然后建立一張全局的工作表用於存放當前未退出的所有的工作進程,主進程生成工作進程后會將新生成的工作進程加入到工作進程表中,並建立一個單向的管道並將其傳遞給工作進程,該管道與普通的管道不同,它是由主進程指向工作進程的單項通道,包含了主進程想工作進程發出的指令、工作進程ID、工作進程在工作進程表中的索引和必要的文件描述符等信息。
    主進程與外界通過信號機制進行通信,當接收到需要處理的信號時,它通過管道向相關的工作進程發送正確的指令,每個工作進程都有能力捕獲管道中的可讀事件,當管道中有可讀事件的時候,工作進程就會從管道中讀取並解析指令,然后采取相應的執行動作,這樣就完成了主進程與工作進程的交互。

 3.2:工作進程與工作進程之間的通信:

    工作進程之間的通信原理基本上和主進程與工作進程之間的通信是一樣的,只要工作進程之間能夠取得彼此的信息,建立管道即可通信,但是由於工作進程之間是完全隔離的,因此一個進程想要直到另外一個進程的狀態信息就只能通過主進程來設置了。
    為了實現工作進程之間的交互,主進程在生成工作進程只之后,在工作進程表中進行遍歷,將該新進程的ID以及針對該進程建立的管道句柄傳遞給工作進程中的其他進程,為工作進程之間的通信做准備,當工作進程1向工作進程2發送指令的時候,首先在主進程給它的其他工作進程工作信息中找到2的進程ID,然后將正確的指令寫入指向進程2的管道,工作進程2捕獲到管道中的事件后,解析指令並進行相關操作,這樣就完成了工作進程之間的通信。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM