Nginx里面的事件處理與其他服務器所做的事件處理模型其實大同小異---都是封裝了一個事件通知的結構體,然后會對每個平臺上常用的事件觸發器做封裝(epoll/select/poll/...),根據編譯時配置來決定選擇哪個事件處理器,當然,這個選擇也可以在配置文件中指定。
封裝事件處理的結構體在ngx_event_s中定義,其中的handler是處理事件的函數指針。
對于監聽socket而言,這個handler函數指針指向的是函數ngx_event_accept函數。顯然,這個函數是用于接收新連接。
當接收新的連接之后,對連接socket而言,這個函數指針指向ngx_http_init_request
函數。假如這個函數執行成功,handler函數指針會改為指向ngx_http_process_request_line函數。其他的以此類推,我沒有繼續跟進這些與http具體業務相關的處理函數。
所以,可以看到,在處理一個連接請求的每個階段,都對應的是不同的handler函數,在每個handler函數中,會在執行成功之后修改handler函數指針指向下一個階段的處理函數。
與之前分析過的
lighhtpd的狀態機相比,Nginx里面的handler函數之間,耦合關系更緊密一些,也就是說,在狀態處理的每個階段,都需要知道下一個階段是由哪個函數進行處理。我個人更喜歡lighttpd的狀態機,因為這個狀態機使得每個階段的狀態耦合的不那么緊密,每次狀態處理完畢,該狀態的處理函數只需要保存本次處理的結果,然后進入狀態機處理函數中,由它來選擇處理的走向。