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_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
};

ngx_events_module 模块只对一个块配置项感兴趣,也就是 nginx.conf 中必须有的 events{} 配置项。

2.2 核心模块的通用接口

static ngx_core_module_t  ngx_events_module_ctx = {
    ngx_string("events"),
    NULL,
    ngx_event_init_conf
};

这里,ngx_events_module_ctx 只是实现了init_conf方法,而没有实现create_conf方法,这是因为ngx_events_module模块

并不会解析配置项的参数,只是在出现 "events" 配置项后会调用各事件模块去解析 events{} 块内的配置项。init_conf方

法仅是检测是否能获取到ngx_events_module模块的保存在cycle->conf_ctx数组中的配置项结构体,该结构体保存着所有事件

模块的配置项。

static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
{
    if (ngx_get_conf(cycle->conf_ctx, ngx_events_module) == NULL) {
        ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
                      "no \"events\" section in configuration");
        return NGX_CONF_ERROR;
    }

    return NGX_CONF_OK;
}

2.3 模块的定义

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_module模块除了对 events 配置项的解析外,没有做其他任何事情。

3. ngx_events_module的配置项管理

3.1 如何管理所有事件模块的配置项

每一个事件模块都必须实现ngx_event_module_t接口,这个接口中允许每个事件模块建立自己的配置项结构体,用于存储自己

感兴趣的配置项在nginx.conf中对应的参数。ngx_event_module_t 中的 create_conf 方法就是用于创建这个结构体的方法,

事件模块只需要在这个方法中分配内存即可。

每一个事件模块产生的配置结构体指针都会被放到 ngx_events_module 模块创建的指针数组中。而 ngx_cycle_t 核心结构体

中的 conf_ctx 成员,它指向一个指针数组,这个指针数组中就依次存放着所有的 Nginx 模块关于配置项方面的指针。因

此,核心模块 ngx_events_module 管理所有事件模块的总配置项结构体就按 ngx_events_module 模块在全部 Nginx 模块中

的排序号放入到 ngx_cycle_t 核心结构体的成员 conf_ctx 指针数组中的对应下标处。

ngx_cycle_t 结构体中 conf_ctx 的结构示意图

3.2 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 */

    /* 计算出编译进 Nginx 的所有事件模块的总个数 */
    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;
    }

    /* conf 其实就是核心模块 ngx_events_module 在 ngx_cycle_t 核心结构体的成员 conf_ctx 指针数组
     * 相应位置的指针 */
    *(void **) conf = ctx;

    /* 调用所有事件模块的 create_conf 方法 */
    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;

    /* 开始解析 events{} 配置块 */
    rv = ngx_conf_parse(cf, NULL);

    *cf = pcf;

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

    /* 解析配置项完成后,调用各事件模块的 init_conf 方法 */
    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;
}

原文地址:https://www.cnblogs.com/jimodetiantang/p/8947152.html

时间: 2024-11-05 14:47:22

Nginx事件管理之核心模块ngx_events_module的相关文章

【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 mast

Backbone事件管理——Backbone.Events模块API结构

模块Backbone.Events的事件管理是通过Backbone提供的Events API来实现的,该API在1.0版本之前仅仅提供了几个基本的方法,如on.off.trigger.once分别执行对事件的绑定.解除绑定.执行事件.执行一次事件的操作.从1.0版本以后,又添加了几个实用方法,如listenTo.listenToOnce.stopListening,分别执行添加一个事件的侦察对象.添加一个仅执行一次的事件侦察对象和移除已添加的事件侦察对象,其完整的结构如图3-1所示. Backb

【Nginx】Nginx事件模块

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

Nginx 事件模块

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

Node.js【5】核心模块

笔记来自<Node.js开发指南>BYVoid编著 第4章 Node.js核心模块 4.1.全局对象 Node.js中的全局对象是global,所有全局变量(除了global本身以外)都是global对象的属性.我们在Node.js中能够直接访问到对象通常都是global的属性,如console.process等. 永远使用var定义变量以避免引入全局变量,因为全局变量会污染命名空间,提高代码的耦合风险. process用于描述当前Node.js进程状态的对象,提供了一个与操作系统的简单接口.

nginx事件模块 -- 第一篇

微信公众号:郑尔多斯关注可了解更多的Nginx知识.任何问题或建议,请公众号留言;关注公众号,有趣有内涵的文章第一时间送达! 事件机制 下面是我们对nginx事件相关的配置,如下: 1events {2    worker_connections  1024;3    use epoll;4} 我们明确的使用了epoll机制,在nginx中,和事件相关的模块一共有三个,分别为ngx_events_module,ngx_event_core_module,ngx_epoll_module.本篇文章

【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的Push_stream_module推送模块管理WebSocket长连接会不会限制WebSocket的双向通信的能力

最近项目在用nginx的Push_stream_module推送模块去实现服务器端向客户端信息的推送,本来只想实现这个单向通信的需求的,可是给客户端推送完消息之后,如果想让客户端给一个反馈,就没办法监听获取到客户端的反馈事件,并及时作出反应.后来知道push_stream_module管理长连接是基于pub/sub模式的,而且好像模块中也没有给出类似websocket中onmessage的API,是不是就是限制了webSocket全双工的通信能力,这点好像nodejs的socket.io做的就更

nginx事件模块 -- 第二篇

微信公众号:郑尔多斯关注可了解更多的Nginx知识.任何问题或建议,请公众号留言;关注公众号,有趣有内涵的文章第一时间送达! 事件机制 上一篇文件我们简单的介绍了ngx_event_block()函数的功能,这个函数用于解析events指令,引入事件机制.其实真正的工作是在ngx_event_core_module中完成的,这个模块可以解析use,work_connections等指令,这些指令用于控制nginx事件机制的一些参数.上一篇文章中我们也提到过执行ngx_event_block()函