Nginx事件处理模型是Nginx事件处理的核心,充分体现了最简业务原则和分段处理的架构理念。
作为Web服务器,Nignx每一个用户请求至少对于一个TCP连接,一个TCP连接至少需要一个读事件和一个写事件(分段原则的体现,即使很简单很明确的需求也会分段处理。)。在这里我们必须理解Nginx事件的定义和连接的定义。事件定义的基本数据结构是ngx_event_t,连接定义的基本数据结构是ngx_connect_t。
1.事件定义
Nginx事件定义有两个基础事件和AIO事件,每个事件最核心的部分是handler回调方法,handler将由事件消费者实现,它决定事件的最终处理方式。Nginx事件驱动模型有很多种,所以ngx_event_s事件定义中很多字段也都是有针对性的,需要在特定事件驱动模式下才有意义,我们只需要掌握关于TCP处理的最基础的就可以,其他的在学习具体的事件驱动模式的时候,慢慢掌握。
/*基础事件定义*/
struct ngx_event_s {void *data;/*指向数据的指针*/unsigned write:1;/*事件可写,即TCP连接(事件处理可以理解为TCP请求处理)状态可以发送网络报文*/unsigned accept:1;/*是否可以接受新的连接,由核心框架中的worker进程直接控制*//* 过期事件是否需要在事件驱动模块处理,结合前面的ngx_posted_accept_events理解*/unsigned instance:1;/** the event was passed or would be passed to a kernel;* in aio mode - operation was posted.*/unsigned active:1;/*事件禁用在kqueue或者rtsig中有效,在epoll事件中无效*/unsigned disabled:1;/* AIO 处理模式,事件处于可处理状态*/unsigned ready:1;unsigned oneshot:1;/*在AIO模式下标示有请求事件处理*//* aio operation is complete */unsigned complete:1;/*在AIO模式下事件处理完成*/unsigned eof:1;unsigned error:1;unsigned timedout:1;unsigned timer_set:1;unsigned delayed:1;unsigned deferred_accept:1;/* the pending eof reported by kqueue, epoll or in aio chain operation */unsigned pending_eof:1;unsigned posted:1;unsigned closed:1;/* worker进程退出标志位,管理进程中的资源处理状态to test on worker exit */unsigned channel:1;unsigned resolver:1;unsigned cancelable:1;#if (NGX_HAVE_KQUEUE)unsigned kq_vnode:1;/* the pending errno reported by kqueue */int kq_errno;
#endif/** kqueue only:* accept: number of sockets that wait to be accepted* read: bytes to read when event is ready* or lowat when event is set with NGX_LOWAT_EVENT flag* write: available space in buffer when event is ready* or lowat when event is set with NGX_LOWAT_EVENT flag** iocp: TODO** otherwise:* accept: 1 if accept many, 0 otherwise* read: bytes to read when event is ready, -1 if not known*/int available;ngx_event_handler_pt handler;#if (NGX_HAVE_IOCP)ngx_event_ovlp_t ovlp;
#endifngx_uint_t index;ngx_log_t *log;ngx_rbtree_node_t timer; /*超时处理机制, 使用红黑树管理*//* the posted queue */ngx_queue_t queue;/* event事件处理队列 */#if 0/* the threads support *//** the event thread context, we store it here* if $(CC) does not understand __thread declaration* and pthread_getspecific() is too costly*/void *thr_ctx;#if (NGX_EVENT_T_PADDING)/* event should not cross cache line in SMP */uint32_t padding[NGX_EVENT_T_PADDING];
#endif
#endif
};
2.连接定义
Nginx的连接分为主动连接和被动连接。主动连接是指Nginx服务器主动向客户端或者其他服务器建立的连接,被动连接是指客户端向Nginx服务器发送的连接。分别对应于ngx_connection_t和ngx_peer_connection_t,ngx_connection_t在之前的章节中介绍过,这里主要介绍ngx_peer_connection_s,ngx_peer_connection_s自有定义主要定义了远端服务器信息和服务器的管理信息,详细见注释。
struct ngx_peer_connection_s {ngx_connection_t *connection;/*TCP连接的基础信息*/struct sockaddr *sockaddr;/*远端服务器地址*/socklen_t socklen;/*远端服务器地址长度*/ngx_str_t *name;/*远端服务器名称*/ngx_uint_t tries;/*连接失败后重试次数*/ngx_msec_t start_time;ngx_event_get_peer_pt get;/**/ngx_event_free_peer_pt free;ngx_event_notify_peer_pt notify;void *data;#if (NGX_SSL || NGX_COMPAT)ngx_event_set_peer_session_pt set_session;ngx_event_save_peer_session_pt save_session;
#endifngx_addr_t *local;int type;int rcvbuf;ngx_log_t *log;unsigned cached:1;unsigned transparent:1;unsigned so_keepalive:1;unsigned down:1;/* ngx_connection_log_error_e */unsigned log_error:2;NGX_COMPAT_BEGIN(2)NGX_COMPAT_END
};