nginx event模块启动分析

来源:互联网 发布:苹果52g网络 编辑:程序博客网 时间:2024/06/07 23:50

通过core模块ngx_events_module支持的events指令加载event二级模块;

执行events指令时,调用回调函数ngx_events_block;

该函数负责创建ngx_events_module的context,并将其保存在cycle->conf_ctx[ngx_events_module.index]处;

其类型类似 struct { void **conf_ctx; }; 示意图如下:


为event二级模块(即类型为NGX_EVENT_MODULE的模块)分配ctx_index,计算ngx_event_max_module;

创建context,为event二级模块创建大小为ngx_event_max_module的void *类型数组,用来保存它们的context;

为event二级模块调用create_conf回调函数创建context,并保存在相应槽位(下标为ngx_module_t::ctx_index);

保存当前ngx_conf_t现场;

修改conf->ctx,设置conf->module_type为NGX_EVNET_MODULE,设置conf->cmd_type为NGX_EVENT_CONF;

调用ngx_conf_parse(conf, NULL)解析加载events块的配置指令;

恢复当前ngx_conf_t现场;

为event二级模块调用init_conf回调函数;


ngx_event_core_module是event的核心模块:

worker_connections和connections(废弃)带一个int类型参数指定cycle::connexction_n,默认值为512;

use指令指出使用的event模型(epoll or select等);

mutil_accept默认为0,accept_mutex默认为1,accept_mutex_delay默认为500;

ngx_event_core_init_conf函数为参数ngx_event_conf_t赋默认值,其中最重要的是,配置文件未使用use指令明确指出使用的event模型时,该函数会按照kqueue、devpoll、epoll、rtsig、select、event_core(NULLs)顺序选择event模型;

ngx_epoll_module仅有两条指令epoll_events和worker_aio_requests分别设置ngx_epoll_conf_t::events和ngx_epoll_conf_t::aio_requests;

最后两个重要的函数调用为ngx_event_module_init和ngx_event_process_init;

ngx_event_module_init函数

该函数主进程调用一次;

初始化ngx_timer_resolution;

master调用该函数时,会创建一段共享内存;

初始化ngx_accept_mutex共享锁;

共享内存内还保存着一些统计信息(ngx_accept_mutex,ngx_connection_counter,ngx_temp_number,ngx_stat_accepted,ngx_stat_handled,ngx_stat_requests,ngx_stat_active,ngx_stat_reading,ngx_stat_writing,ngx_stat_waiting);

ngx_event_process_init函数

该函数在子进程启动时调用一次;

配置文件中指定了master、accept_mutex且worker_processors大于1时,才设置ngx_use_accept_mutex;

创建ngx_posted_events_mutex;

调用ngx_event_timer_init初始化定时器,创建ngx_event_timer_mutex;

根据ngx_event_conf_t::use找出所使用的event模块,调用其actions.init(cycle, ngx_timer_resolution)回调函数;

初始化定时器,使用ITIMER_REAL类型timer,每个ngx_timer_resolution毫秒调用一次信号回调函数ngx_timer_signal_handler;

初始化cycle->connections,cycle->read_events和cycle->write_events,这些数组大小为cycle->connection_n;

将cycle->connections串联成链表,赋值cycle->free_connections和cycle->free_connection_n;

遍历cycle->listening数组,为其分配connection,设置rev->handler = ngx_event_accept,如果ngx_use_accept_mutex没有设置时,通过调用ngx_add_event(rev, NGX_READ_EVENT, 0)将listening fd加入到event模型中;

当listening socket可读时,调用ngx_event_accept函数accept新connection;

使用epoll模型时,调用actions.init(cycle, ngx_timer_resolution)其实是调用ngx_epoll_init函数

该函数创建epoll,初始化event_list;

设置ngx_io = ngx_os_io;

设置ngx_event_actions = ngx_epoll_module_ctx.actions;

设置ngx_event_flags = NGX_USE_CLEAR_EVENT | NGX_USE_GREEDY_EVENT | NGX_USE_EPOLL_EVENT;

ngx_io是nginx抽象出的io回调函数集合:

 25 typedef struct { 26     ngx_recv_pt        recv; 27     ngx_recv_chain_pt  recv_chain; 28     ngx_recv_pt        udp_recv; 29     ngx_send_pt        send; 30     ngx_send_chain_pt  send_chain; 31     ngx_uint_t         flags; 32 } ngx_os_io_t;
ngx_event_actions是nginx抽象出来的event模型回调函数集合:

220 typedef struct {221     ngx_int_t  (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);222     ngx_int_t  (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);223224     ngx_int_t  (*enable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);225     ngx_int_t  (*disable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);226227     ngx_int_t  (*add_conn)(ngx_connection_t *c);228     ngx_int_t  (*del_conn)(ngx_connection_t *c, ngx_uint_t flags);229230     ngx_int_t  (*process_changes)(ngx_cycle_t *cycle, ngx_uint_t nowait);231     ngx_int_t  (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer,232                    ngx_uint_t flags);233234     ngx_int_t  (*init)(ngx_cycle_t *cycle, ngx_msec_t timer);235     void       (*done)(ngx_cycle_t *cycle);236 } ngx_event_actions_t;

0 0
原创粉丝点击