接上篇,这篇主要来看nginx的网络部分的初始化 首先是ngx_http_optimize_servers函数,这个函数是在ngx_http_block中被调用的,它的主要功能就是创建listening结构,然后初始化。这里ngx_listening_t表示一个正在监听的句柄以及它的上下文。
然后就来看真正做事的ngx_http_add_listening函数。这里我们只关注最重要的部分, 就是设置listen 的handler,要注意这个handler并不是accept handler,而是当accpet完之后,处理accept到的句柄的操作.
可是我们注意到在上面的函数中并没有创建listen socket句柄,而且也没有将句柄挂载到事件驱动中,这些动作都是在后面进行的,我们慢慢来看。 ngx_http_block结束后,也就是继续ngx_init_cycle下面的处理, 下面这部分就是创建socket,然后设置flag,最终绑定到listen结构体中.
当这些都结束后,就该挂载listen 句柄到事件处理器里面了。这个动作是在 ngx_worker_process_init中进行的,这个函数是在子进程被fork出来之后马上被调用的。而在这个函数中会执行所有模块的init_process方法.
而nginx的event模块包含一个init_process,也就是ngx_event_process_init.这个函数就是nginx的驱动器,他初始化事件驱动器,连接池,定时器,以及挂在listen 句柄的回调函数。
这个函数比较长,我们来一段段的看。
下面这段是初始化定时器以及event module(epoll etc).
下面这段是初始化连接池,以及对应的读写事件的初始化。
下面这段初始化listen 事件 ,创建socket句柄,绑定事件回调,然后加入到事件驱动中,这里比较关键的就是如果使用了ngx_use_accept_mutex,则现在不会将事件加入到epoll中,而是等到在ngx_process_events_and_timers中将句柄加入,这是因为nginx为了防止惊群,采取了串行化处理accpet,也就是同时只有一个listen句柄会休眠在epoll_wait上等待连接。
然后就是ngx_trylock_accept_mutex代码,这个我以前已经分析过了,这里就不详细分析了,只要知道它会获得一把锁,然后调用ngx_enable_accept_events将listen 事件加入到事件驱动框架中. 在接下来就是进程初始化的操作了,初始化完进程,然后休眠在epoll_wait上等待连接的到来,这部分代码我在前面的nginx进程模型里面有分析. (责任编辑:IT) |