Nginx 事件机制介绍

先看几个主要方法

  • ngx_add_channel_event 主要是把事件注册到事件池中,并且添加事件 handler,具体要结合后面的事件机制来展开。

  • ngx_write_channel 主要是将数据写入到 pipe 中:

       n = sendmsg(s, &msg, 0);

       Top of Form

       Bottom of Form

  • ngx_read_channel 从 pipe 中读取数据:n = recvmsg(s, &msg, 0);

 

接下来分析事件模块工作流程

 

ngx_event模块结构

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_event 模块初始化

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_commands 数组可以知道,event 模块初始化函数为 ngx_events_block,该函数工作内容如下:

 

  1. 创建模块 context 结构

  2. 调用所有 NGX_EVENT_MODULE 模块的 create_conf

  3. 解析 event 配置

  4. 调用所有 NGX_EVENT_MODULE 模块的 init_conf

 

ngx_core_event模块初始化

ngx_core_event_module 是在 ngx_cycle_init 的时候初始化的:

 

for (i = 0; ngx_modules[i]; i++) { 

        if (ngx_modules[i]->init_module) { 

                if (ngx_modules[i]->init_module(cycle) != NGX_OK) { /* fatal */ 

                        exit(1); 

                } 

         } 

}

 

我们先来看下 ngx_core_event_module 的结构:

ngx_module_t ngx_event_core_module = { 

        NGX_MODULE_V1, 

        &ngx_event_core_module_ctx, /* module context */

        ngx_event_core_commands, /* module directives */

        NGX_EVENT_MODULE, /* module type */ 

        NULL, /* init master */

        ngx_event_module_init, /* init module */

        ngx_event_process_init, /* init process */ 

        NULL, /* init thread */ 

        NULL, /* exit thread */ 

        NULL, /* exit process */ 

        NULL, /* exit master */ NGX_MODULE_V1_PADDING

};

 

ngx_event_module_init 实现了初始化过程,该过程分以下几个步骤:

  1. 连接数校验

  2. 初始化互斥锁

 

事件进程初始化

在工作线程初始化的时候,将会调用 ngx_event_process_init:

for (i = 0; ngx_modules[i]; i++) { 

        if (ngx_modules[i]->init_process)  { 

                if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) { /*fatal */ 

                      exit(2); 

                } 

        } 

}

 

ngx_event_process_init 该过程分以下几步:

  1. 设置 ngx_accept_mutex_held

  2. 初始化定时器

  3. 初始化真正的事件引擎(linux 中为 epoll)

  4. 初始化连接池

  5. 添加 accept 事件

 

ngx_process_events_and_timers 事件处理开始工作

工作流程如下:

  1. ngx_trylock_accept_mutex 当获取到标志位后才进行 accept 事件注册。

  2. ngx_process_events 处理事件

  3. 释放 accept_mutex 锁

  4. 处理定时器事件

  5. ngx_event_process_posted 处理 posted 队列的事件

 

ngx 定时器实现

ngx 的定时器利用了红黑树的实现

 

ngx 惊群处理

accept_mutex 解决了惊群问题,虽然linux的新内核已经解决了这个问题,但是ngx 是为了兼容。

 

整体原理图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值