nginx源码分析(6)——建立连接
对于web server来说,必须能够监听到客户端的连接才能与之通信,这篇文章就看一下nginx是如何实现连接的建立。监听到新的连接实际上就是监听socket上的读事件,此时监听socket的已完成连接队列是非空的,可以非阻塞的调用accpet获取新到的连接。在nginx中每个socket都会被封装成一个连接结构,就是ngx_connection_t类型。每个ngx_connection_t结构具有读写事件read和write,它们是ngx_event_t类型的,有一个handler回调函数指针,在发生读写事件时被调用。在监听socket初始化一文中介绍了socket的初始化,主要是获取监听地址、端口等信息。在事件模型中介绍了nginx事件模型的初始化,在ngx_event_process_init函数中为每个监听socket分配连接,并将这些连接的read的handler初始化为ngx_event_accept,也就是说说在监听到连接时会调用,用于初始化连接等,最后将其添加到事件循环中。
在事件循环中,已经介绍过为了防止惊群(新到的一个连接会唤醒所有阻塞的worker进程),只有获取accept锁的worker进程才能accept新的连接,接下来才会去调用ngx_event_accept函数处理。下面就看看具体过程。
1. ngx_event_accept ngx_add_timer(rev, c->listening->post_accept_timeout); /* * 将新建的连接的描述符添加到事件循环 */ if (ngx_handle_read_event(rev, 0) != NGX_OK) {#if (NGX_STAT_STUB) (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);#endif ngx_http_close_connection(c); return; } 设置timer,最后将新建的socket描述符添加到事件循环,但是在使用epoll时添加到事件循环的工作已经在ngx_add_conn中完成,所以这个函数不会做任何操作。 上面就是nginx建立连接的处理过程,主要是初始化连接的属性,并设置了读事件的handler,用于处理请求,下面一篇介绍nginx的请求处理。