nginx事件处理框架及源码解析

本文详细解析了nginx的事件处理框架,包括系统事件和定时器事件的分类,事件处理的核心代码位于ngx_event.c和ngx_event.h。文章介绍了ngx_events_module作为所有事件模块的基础,以及ngx_event_core_module作为最核心的模块,负责规定事件模块规范、选择IO多路复用机制、配置指令和初始化环境。此外,还讨论了事件模块接口、系统事件模块选择、以及worker进程的初始化和事件处理函数ngx_process_events_and_timers的工作流程。
摘要由CSDN通过智能技术生成

nginx的中的事件可以分为两类:系统事件和定时器事件。系统事件指的是由操作系统通知给nginx的事件,例如各种IO多路复用api(select,epoll_wait等)返回的事件,定时器事件是指由nginx的定时器模型产生的超时事件。由于事件处理机制与生俱来的复杂性,为了方便管理,降低开发难度,nginx的事件处理框架将事件的管理抽象成一系列的接口,这些接口屏蔽了事件处理的底层细节,外部只需要关心自己的事件处理逻辑,并调用这些接口就可以将自身的处理逻辑融入到事件处理框架中。而nginx的工作进程运行时,实际上就是在循环地处理各种事件。

nginx的事件处理框架相关的核心代码位于ngx_event.c和ngx_event.h文件中,可以划分成三个部分:

1. ngx_events_module模块实现

2. ngx_event_core_module模块实现

3. 事件接口实现


ngx_events_module是NGX_CORE_MODULE类型,它定义了一个新的模块类型:NGX_EVENT_MODULE,即事件模块。它是nginx所有事件模块的基础,它只有一个块指令:events,如下所示:

static ngx_command_t  ngx_events_commands[] = {

    { ngx_string("events"),
      NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
      ngx_events_block,
      0,
      0,
      NULL },

      ngx_null_command
};


从定义可以看出,events是一个全局块指令,指令的回调函数是ngx_events_block,因此可以知道,nginx的事件相关的配置(events配置块里的配置)都是在ngx_events_block里实现加载的。ngx_events_block的代码如下:

static char *
ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    char                 *rv;
    void               ***ctx;
    ngx_uint_t            i;
    ngx_conf_t            pcf;
    ngx_event_module_t   *m;

    if (*(void **) conf) {
        return "is duplicate";
    }

    /* count the number of the event modules and set up their indices */

    ngx_event_max_module = ngx_count_modules(cf->cycle, NGX_EVENT_MODULE);

    ctx = ngx_pcalloc(cf->pool, sizeof(void *));
    if (ctx == NULL) {
        return NGX_CONF_ERROR;
    }

    *ctx = ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *));
    if (*ctx == NULL) {
        return NGX_CONF_ERROR;
    }

    *(void **) conf = ctx;

    for (i = 0; cf->cycle->modules[i]; i++) {
        if (cf->cycle->modules[i]->type != NGX_EVENT_MODULE) {
            continue;
        }

        m = cf->cycle->modules[i]->ctx;

        if (m->create_conf) {
            (*ctx)[cf->cycle->modules[i]->ctx_index] =
                                                     m->create_conf(cf->cycle);
            if ((*ctx)[cf->cycle->modules[i]->ctx_index] == NULL) {
                return NGX_CONF_ERROR;
            }
        }
    }

    pcf = *cf;
    cf->ctx = ctx;
    cf->module_type = NGX_EVENT_MODULE;
    cf->cmd_type = NGX_EVENT_CONF;

    rv = ngx_conf_parse(cf, NULL);

    *cf = pcf;

    if (rv != NGX_CONF_OK) {
        return rv;
    }

    for (i = 0; cf->cycle->modules[i]; i++) {
        if (cf->cycle->modules[i]->type != NGX_EVENT_MODULE) {
            continue;
        }

        m = cf->cycle->modules[i]->ctx;

        if (m->init_conf) {
            rv = m->init_conf(cf->cycle,
                              (*ctx)[cf->cycle->modules[i]->ctx_index]);
            if (rv != NGX_CONF_OK) {
                return rv;
            }
        }
    }

    return NGX_CONF_OK;
}


结合http框架核心之ngx_http.c源码分析这篇文章中对于ngx_http_block函数的分析,可以看出它的作用于ngx_http_block类似,就是统计所有类型为NGX_EVENT_MODULE的模块数量,初始化它们的配置上下文,然后解析并执行模块指令,最后将解析结果保存在对应的上下文中。

ngx_event_core_module是NGX_EVENT_MODULE类型模块中的最核心的模块。它所做的事情可以归纳为以下几个:

1. 规定了编写事件模块的统一规范,并且在这个规范的基础上实现了nginx的事件处理框架

2. 选择使用何种IO多路复用机制作为框架的底层实现

3. 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值