zoukankan      html  css  js  c++  java
  • nginx事件模块 第一篇

    微信公众号:郑尔多斯
    关注可了解更多的Nginx知识。任何问题或建议,请公众号留言;
    关注公众号,有趣有内涵的文章第一时间送达!

    事件机制

    下面是我们对nginx事件相关的配置,如下:

    1events {
    2    worker_connections  1024;
    3    use epoll;
    4}

    我们明确的使用了epoll机制,在nginx中,和事件相关的模块一共有三个,分别为ngx_events_modulengx_event_core_modulengx_epoll_module
    本篇文章介绍ngx_events_module模块。

    ngx_events_module

    该模块是nginx中引入事件机制的模块,我们可以从ngx_events.c文件中找到与ngx_events_module相关的配置,如下:

     1static ngx_command_t  ngx_events_commands[] = {
    2
    3    { ngx_string("events"),
    4      NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
    5      ngx_events_block,
    6      0,
    7      0,
    8      NULL },
    9
    10      ngx_null_command
    11};
    12
    13
    14static ngx_core_module_t  ngx_events_module_ctx = {
    15    ngx_string("events"),
    16    NULL,
    17    ngx_event_init_conf
    18};
    19
    20
    21ngx_module_t  ngx_events_module = {
    22    NGX_MODULE_V1,
    23    &ngx_events_module_ctx,                /* module context */
    24    ngx_events_commands,                   /* module directives */
    25    NGX_CORE_MODULE,                       /* module type */
    26    NULL,                                  /* init master */
    27    NULL,                                  /* init module */
    28    NULL,                                  /* init process */
    29    NULL,                                  /* init thread */
    30    NULL,                                  /* exit thread */
    31    NULL,                                  /* exit process */
    32    NULL,                                  /* exit master */
    33    NGX_MODULE_V1_PADDING
    34};
    35
    36typedef struct {
    37    ngx_str_t             name;
    38    void               *(*create_conf)(ngx_cycle_t *cycle);
    39    char               *(*init_conf)(ngx_cycle_t *cycle, void *conf);
    40ngx_core_module_t;

    从上面的配置中我们可以得到如下信息:

    • ngx_events_module 是一个核心模块 (NGX_CORE_MODULE类型)
    • ngx_events_module 只解析一个命令,即events这个NGX_BLOCK命令,并且不带参数
    • ngx_events_modulecreate_conf()函数为空,它只有init_conf()函数
    • 当遇到events指令的时候,调用 ngx_event_block()函数进行解析处理

    解析events指令

    我们在前面的文章中介绍过,配置文件的解析是在ngx_init_cycle()函数中完成的。我们再次把这部分代码摘出来,如下:

    1cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
    2    if (cycle->conf_ctx == NULL) {
    3        ngx_destroy_pool(pool);
    4        return NULL;
    5    }

    这里分配conf_ctx的内存空间,然后执行如下的代码:

     1for (i = 0; cycle->modules[i]; i++) {
    2        if (cycle->modules[i]->type != NGX_CORE_MODULE) {
    3            continue;
    4        }
    5
    6        module = cycle->modules[i]->ctx;
    7
    8        if (module->create_conf) {
    9            rv = module->create_conf(cycle);
    10            if (rv == NULL) {
    11                ngx_destroy_pool(pool);
    12                return NULL;
    13            }
    14            cycle->conf_ctx[cycle->modules[i]->index] = rv;
    15        }
    16    }

    遍历所有的NGX_CORE_MODULE类型的模块,调用他们的create_conf()方法,并且赋值给cycle->conf_ctx,上面分析过,ngx_event_module并没有create_conf()方法,所以这部分代码对ngx_event_module没有影响。

    ngx_events_block

    下面我么分析一下ngx_events_block()函数,这个函数的作用就是解析events指令,代码如下:

     1static char *
    2ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
    3
    {
    4    char                 *rv;
    5    void               ***ctx;
    6    ngx_uint_t            i;
    7    ngx_conf_t            pcf;
    8    ngx_event_module_t   *m;
    9
    10    if (*(void **) conf) {
    11        return "is duplicate";
    12    }
    13
    14    /* count the number of the event modules and set up their indices */
    15
    16    ngx_event_max_module = ngx_count_modules(cf->cycle, NGX_EVENT_MODULE);
    17
    18    ctx = ngx_pcalloc(cf->pool, sizeof(void *));
    19    if (ctx == NULL) {
    20        return NGX_CONF_ERROR;
    21    }
    22
    23    *ctx = ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *));
    24    if (*ctx == NULL) {
    25        return NGX_CONF_ERROR;
    26    }
    27
    28    *(void **) conf = ctx;
    29
    30    for (i = 0; cf->cycle->modules[i]; i++) {
    31        if (cf->cycle->modules[i]->type != NGX_EVENT_MODULE) {
    32            continue;
    33        }
    34
    35        m = cf->cycle->modules[i]->ctx;
    36
    37        if (m->create_conf) {
    38            (*ctx)[cf->cycle->modules[i]->ctx_index] =
    39                                                     m->create_conf(cf->cycle);
    40            if ((*ctx)[cf->cycle->modules[i]->ctx_index] == NULL) {
    41                return NGX_CONF_ERROR;
    42            }
    43        }
    44    }
    45
    46    pcf = *cf;
    47    cf->ctx = ctx;
    48    cf->module_type = NGX_EVENT_MODULE;
    49    cf->cmd_type = NGX_EVENT_CONF;
    50
    51    rv = ngx_conf_parse(cf, NULL);
    52
    53    *cf = pcf;
    54
    55    if (rv != NGX_CONF_OK) {
    56        return rv;
    57    }
    58
    59    for (i = 0; cf->cycle->modules[i]; i++) {
    60        if (cf->cycle->modules[i]->type != NGX_EVENT_MODULE) {
    61            continue;
    62        }
    63
    64        m = cf->cycle->modules[i]->ctx;
    65
    66        if (m->init_conf) {
    67            rv = m->init_conf(cf->cycle,
    68                              (*ctx)[cf->cycle->modules[i]->ctx_index]);
    69            if (rv != NGX_CONF_OK) {
    70                return rv;
    71            }
    72        }
    73    }
    74
    75    return NGX_CONF_OK;
    76}

    该函数的执行流程如下:

    • 计算当前有多少个NGX_EVENT_MODULE类型的模块,我们这里的例子中有两个该类型的模块
    • 分配内存空间
    • 调用所有NGX_EVENT_MODULE类型模块的create_conf()方法
    • 递归解析events块指令的内部指令,比如use,worker_connections等指令
    • 调用所有 NGX_EVENT_MODULE类型模块的init_conf()方法

    上面就是ngx_events_block()方法的执行流程。这个方法很简单,因为牵涉到ngx_event_core_modulengx_epoll_module,所以下一节我们详细介绍一下这两个事件模块。


    喜欢本文的朋友们,欢迎长按下图关注订阅号郑尔多斯,更多精彩内容第一时间送达

    郑尔多斯郑尔多斯
  • 相关阅读:
    导入别人的flex项目出现的问题
    HTTP通信原理
    java 代码的细节优化
    跨服务器之间的session共享
    spring整合hibernate配置文件
    java中时间类型的问题
    Hibernate注解映射sequence时出现无序增长问题+hibernate 映射 oracle ID自动增长:
    并发处理方案 个人总结
    MsSqlserver 查看锁表与解锁
    c# CTS 基础数据类型笔记
  • 原文地址:https://www.cnblogs.com/zhengerduosi/p/10122326.html
Copyright © 2011-2022 走看看