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的状态机,因为这个状态机使得每个阶段的状态耦合的不那么紧密,每次状态处理完毕,该状态的处理函数只需要保存本次处理的结果,然后进入状态机处理函数中,由它来选择处理的走向。