1. 程式人生 > >手把手教你用nginx開發自己的伺服器------利用nginx開發一個helloWorld程式(三)

手把手教你用nginx開發自己的伺服器------利用nginx開發一個helloWorld程式(三)

之前兩篇文章已經說明了過程,今天稍微把過程說細一點,畢竟知其然還要知其所以然嘛,整個呼叫的邏輯是怎完整的呢?

其實上兩篇文章看似簡單的將nginx處理一個請求的過程說出來了,但實際過程一點也不簡單,一個連線處理的過程,主要是複雜在準備階段(也就是各種回撥函式的掛載,上下文的準備,從各種池內申請資源等等),一個http連線的準備過程分為兩個部分,一個是http部分,一個event部分。

得益於nginx的模組化設計,用nginx做模組化開發很方便,但是也帶來了程式碼複雜,難以讀懂的問題,首先看一下http模組是怎麼準備的,回憶下上一篇文章我們提到的真正處理http請求的函式(或者說是handler,控制代碼)是ngx_http_wait_request_handler對吧。

rev->handler = ngx_http_wait_request_handler;

以這個函式為例,我們來看看http模組是怎麼將這個handler掛載好的,如下圖

                                              

ngx_http_block()則就是一個典型的nginx中的module函數了,當整個模組載入的時候就會呼叫這個函式(後續講nginx模組開發的時候我會細講呼叫過程,這裡就先把它記住吧)。

掛好了handler,什麼時候去呼叫這個handler呢?這就要靠nginx的event模組了,event模組實現的功能就是將用來accept的fd註冊到epoll中,等有client的請求到來,生成一個新的connfd,然後從連線池裡拿出一個連線,將這個連線初始化(也就是把剛剛我們的讀寫事件的回撥等東西寫進連線中),然後一併註冊到epoll中去,這樣,只要這個connfd就緒,就可以根據fd的讀寫狀態呼叫其相應讀寫事件的handler了。來看下event模組是怎麼初始化然後監聽用來accept_fd的:

                                                    

繞來繞去,不知道你昏沒有,我這個講的人都有點昏了,IO複用加回調機制確實有夠反人類的,為此go,python等引入了coroutine(協程)的概念,就是想取消掉這種反人類的東西,這就是後話了(不過最近看了c語言實現的一個協程,比回撥還要噁心的多。。。。)