【Nginx】核心模块ngx_events_module

核心模块ngx_events_module是一个专门用于管理事件模块的模块。它的实现很简单,下面是该模块的定义:

ngx_module_t  ngx_events_module = {
    NGX_MODULE_V1,
    &ngx_events_module_ctx,                /* module context */
    ngx_events_commands,                   /* module directives */
    NGX_CORE_MODULE,                       /* module type */
    NULL,                                  /* init master */
    NULL,                                  /* init module */
    NULL,                                  /* init process */
    NULL,                                  /* init thread */
    NULL,                                  /* exit thread */
    NULL,                                  /* exit process */
    NULL,                                  /* exit master */
    NGX_MODULE_V1_PADDING
}; 

解析配置项的ngx_events_commands结构体数组定义如下:

// 定义了如何处理感兴趣的配置项
static ngx_command_t  ngx_events_commands[] = {
    {
        ngx_string("events"), /* 只对events块配置项感兴趣 */
        NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
        ngx_events_block,     /* 解析配置项的函数 */
        0,
        0,
        NULL
    },
    ngx_null_command
}; 

可以看到,核心模块ngx_events_module只对配置文件中的“events”块配置项感兴趣,并用ngx_events_block方法进行解析。ngx_events_block在后面讲解。

通用接口ngx_events_module_ctx定义如下:

static ngx_core_module_t  ngx_events_module_ctx = {
    ngx_string("events"),
    NULL,                  /* create_conf */
    ngx_event_init_conf    /* init_conf */
}; 

ngx_event_init_conf函数内貌似没有做什么特别的工作,所以我们可以忽略它,相当于该接口只是定义了该模块的名字而已。这是因为ngx_events_module并不解析配置项参数,只是在events块配置项出现后调用各个事件模块去解析events内的配置项,所以它自己并不需要实现create_conf方法和init_conf方法。

如何管理事件模块配置项

事件模块的通用接口是ngx_event_module_t,定义如下:

typedef struct {
    ngx_str_t              *name;   // 事件模块名字
    // 解析配置项之前调用,创建存储配置项参数的结构体
    void                 *(*create_conf)(ngx_cycle_t *cycle);
    // 解析完配置项后的回调函数
    char                 *(*init_conf)(ngx_cycle_t *cycle, void *conf);
    // 每个事件模块需要实现的10个抽象方法
    ngx_event_actions_t     actions;
} ngx_event_module_t;   // 事件模块通用接口

每个事件模块使用init_conf成员函数创建存储配置项的结构体并返回指向这个结构体的指针。这个指针放在了ngx_events_module核心模块创建的指针数组中,如下图所示:

这样,每一个进程的核心结构体ngx_cycle_t就能够和所有模块的存储配置项的结构体相关联了。那么每个事件模块调用create_conf方法所返回的指针又是怎样放进核心模块的数组中的呢?还是上面提到的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;
    ngx_event_max_module = 0;
    for (i = 0; ngx_modules[i]; i++)
    {
        if (ngx_modules[i]->type != NGX_EVENT_MODULE)
            continue;
        /* 1.初始化所有事件模块的ctx_index成员
         * 该成员表明了该模块在相同类型模块中的顺序,这会决定以后加载各事件模块的顺序
         */
        ngx_modules[i]->ctx_index = ngx_event_max_module++;
    }
    /* 分配一个存放指针的空间 */
    ctx = ngx_pcalloc(cf->pool, sizeof(void *));
    /* 2.ngx_event_max_module等于事件模块个数 */
    *ctx = ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *));
    *(void **) conf = ctx;  /* conf指向存储参数的结构体 */
    for (i = 0; ngx_modules[i]; i++)
    {
        if (ngx_modules[i]->type != NGX_EVENT_MODULE)
            continue;
        m = ngx_modules[i]->ctx;    /* 得到事件模块的通用接口 */
        if (m->create_conf)
            /* 3.调用所有事件模块的通用接口ngx_event_module_t中的create_conf方法 */
            (*ctx)[ngx_modules[i]->ctx_index] = m->create_conf(cf->cycle);
    }
    pcf = *cf;
    cf->ctx = ctx;
    cf->module_type = NGX_EVENT_MODULE;
    cf->cmd_type = NGX_EVENT_CONF;
    /* 4.针对所有事件模块调用各自的解析配置文件的方法
     * 当发现相应配置项后,就调用模块中ngx_command_t数组中的方法
     */
    rv = ngx_conf_parse(cf, NULL);  /* cf中保存有读到的配置项参数 */
    *cf = pcf;
    for (i = 0; ngx_modules[i]; i++)
    {
        if (ngx_modules[i]->type != NGX_EVENT_MODULE)
            continue;
        m = ngx_modules[i]->ctx;
        if (m->init_conf)
            /* 5.解析完配置项后,调用每个模块的init_conf方法对配置参数进行整合 */
            rv = m->init_conf(cf->cycle, (*ctx)[ngx_modules[i]->ctx_index]);
    }
    return NGX_CONF_OK;
} 

以上代码用ngx_pcalloc函数分配了两块内存,第一个ngx_pcalloc创建一个能够存放指针的空间,相当于图9-2上面那个数组中的第四个单元;而第二个ngx_pcalloc则创建了一个指针数组,存放指针的数量等于事件模块的数量,对应图9-2下面的那个数组。此函数执行完毕时,所有事件模块都在核心模块ngx_events_module的管理下成功读取配置项。

以上就是管理事件的核心模块ngx_events_module。事件驱动机制更多的工作是在ngx_event_core_module模块中完成,下次再写。

参考:

《深入理解Nginx》 P300-P305.

【Nginx】核心模块ngx_events_module,布布扣,bubuko.com

时间: 2024-08-10 01:53:01

【Nginx】核心模块ngx_events_module的相关文章

Nginx事件管理之核心模块ngx_events_module

1. ngx_events_module核心模块的功能介绍 ngx_events_module 模式是一个核心模块,它的功能如下: 定义新的事件类型 定义每个事件模块都需要实现的ngx_event_module_t接口 管理这些事件模块生成的配置项结构体,并解析事件类配置项,同时,在解析配置项时会调用其在ngx_command_t数组中定义的配置项结构体. 2. ngx_events_module的框架实现 2.1 ngx_events_module的配置项 static ngx_command

【Nginx核心模块】线程池模块

本节研究Nginx中线程池模块的相关实现: 总体说明 (1)线程池模块属于核心模块,因此其配置内存ngx_thread_pool_conf_t将会预先申请好:ngx_thread_pool_conf_t中主要管理各个线程池结构: (2)在ngx_thread_pool_init_worker和 ngx_thread_pool_exit_worker分别会创建每一个线程池和销毁每一个线程池: 线程池模块 ngx_module_t ngx_thread_pool_module = { NGX_MOD

Nginx核心模块内置变量

本文根据Nginx官网整理了Nginx的ngx_http_core_module模块的内置变量,可与Apache做对比参考.随后做了一次测试观察各变量的值,并附上测试结果. 1.变量列表 $arg_name    请求行中参数name的值. $args    请求行中的所有参数. $binary_remote_addr    客户端地址的二进制形式. $body_bytes_sent    发送给客户端的字节数,不包含响应头的内容,与Apache的mod_log_config模块中的%B兼容.

nginx 核心模块指令(一)

alias   root nginx配置下有两个指定目录的指令,root和alias location /img/ { alias /var/www/image/; } #若按照上述配置的话,则访问/img/目录里面的文件时,ningx会自动去/var/www/image/目录找文件 location /img/ { root /var/www/image; } #若按照这种配置的话,则访问/img/目录下的文件时,nginx会去/var/www/image/img/目录下找文件.] alias

Nginx核心模块

error_log 语法:error_log file [ debug | info | notice | warn | error | crit ]默认值:${prefix}/logs/error.log指定Nginx服务(与FastCGI)错误日志文件位置.每个字段的错误日志等级默认值: 1.main字段-error,2.HTTP字段-crit,3.server字段-crit 关闭日志功能:error_log /dev/null crit; include 语法:include file |

Nginx核心流程及模块介绍

Nginx核心流程及模块介绍 1. Nginx简介以及特点 Nginx简介: Nginx (engine x) 是一个高性能的web服务器和反向代理服务器,也是一个IMAP/POP3/SMTP服务器 俄罗斯程序员Igor Sysoev于2002年开始 Nginx是增长最快的Web服务器,市场份额已达33.3% 全球使用量排名第二2011年成立商业公司 Nginx社区分支: Openresty作者@agentzh(章宜春)开发的,最大特点是引入了ngx_lua模块,支持使用lua开发插件,并且集合

Nginx 事件模块

概述 Nginx 是以事件的触发来驱动的,事件驱动模型主要包括事件收集.事件发送.事件处理(即事件管理)三部分.在Nginx 的工作进程中主要关注的事件是 IO 网络事件 和 定时器事件.在生成的 objs 目录文件中,其中ngx_modules.c 文件的内容是 Nginx 各种模块的执行顺序,我们可以从该文件的内容中看到事件模块的执行顺序为以下所示:注意:由于是在 Linux 系统下,所以支持具体的 epoll 事件模块,接下来的文章结构按照以下顺序来写. extern ngx_module

【Nginx】Nginx事件模块

一.事件处理框架概述 事件处理框架所要解决的问题是如何收集.管理.分发事件.事件处理框架需要在不同的操作系统内核中选择一种事件驱动机制支持网络事件的处理. 步骤: 1.Nginx定义了一个核心模块ngx_events_module,该模块定义了事件类型的模块,为所有的事件模块解析events{}中的配置项,同时管理这些事件模块存储配置项的结构体 2.Nginx定义了一个非常重要的事件模块ngx_event_core_module,这个模块会决定使用哪种事件驱动机制,以及如何管理事件 3.Ngin

HTTP扫盲及nginx基础性模块常用指令整理

第一部分:HTTP基础知识 在介绍nginx常用模块中的指令时,先来回顾一下http的相关知识: 1.http的工作原理 http的工作原理大致是这样的: a).客户端与服务器先建立一个TCP连接: b).客户端通过已建立的TCP连接向服务端发送一个http请求报文: c).服务器收到请求报文后开始解析报文.定位所请求的资源,读取资源并封装成响应报文后发送给客户端: d).如果没有启用持久连接,服务器端主动断开tcp连接,客户端被动关闭:如果启用了持久连接,那该tcp连接保持一段时间后,在该时间