nginx转发流程的框架结构

nginx初始化完成后,进入到运行阶段.代码如下:

 if (ngx_process == NGX_PROCESS_SINGLE) {
        ngx_single_process_cycle(cycle);   //单进程

    } else {
        ngx_master_process_cycle(cycle);    //多进程,master进程进入这个,这个函数在不同操作系统有不同实现。
    }


ngx_cycle_t是nginx处理进程的核心结构. ngx_single_process_cycle函数初始化环境变量和模块处理函数的初始化后,就开始工作了.


 for ( ;; ) {
        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
        ngx_process_events_and_timers(cycle);
        if (ngx_terminate || ngx_quit) {
            for (i = 0; ngx_modules[i]; i++) {
                if (ngx_modules[i]->exit_process) {
                    ngx_modules[i]->exit_process(cycle);
                }
            }
            ngx_master_process_exit(cycle);
        }
  
        if (ngx_reconfigure) {
            ngx_reconfigure = 0;
            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring");
            cycle = ngx_init_cycle(cycle);
            if (cycle == NULL) {
                cycle = (ngx_cycle_t *) ngx_cycle;
                continue;
            }
            ngx_cycle = cycle;
        }
  
        if (ngx_reopen) {
            ngx_reopen = 0;
            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
            ngx_reopen_files(cycle, (ngx_uid_t) -1);
        }
    }

上面的代码虽然很短,却实现了修改配置不需要重起进程的特色功能.  真正处理业务的函数是ngx_process_events_and_timers.

从语义看是处理事件和定时器的模块,而nginx中的业务就是由事件来驱动的.

void
ngx_process_events_and_timers(ngx_cycle_t *cycle)
{
    ngx_uint_t  flags;
    ngx_msec_t  timer, delta;

    delta = ngx_current_msec;
    //epoll开始wait事件
    (void) ngx_process_events(cycle, timer, flags);

    delta = ngx_current_msec - delta;

    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                   "timer delta: %M", delta);
    //ngx_posted_accept_events暂存epoll从监听套接字接口wait到的accept事件
    if (ngx_posted_accept_events) {
        ngx_event_process_posted(cycle, &ngx_posted_accept_events);
    }

    if (ngx_accept_mutex_held) {    //所有accept事件处理完成了,如果拥有锁的话,赶紧释放了
        ngx_shmtx_unlock(&ngx_accept_mutex);
    }
    //delta是上文对epoll wait事件的耗时统计,存在毫秒级的耗时就对所有事件的timer进行检查,
    if (delta) {
        ngx_event_expire_timers();
    }

    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                   "posted events %p", ngx_posted_events);
    //处理普通事件(连接上获得的读写事件)
    if (ngx_posted_events) {
        if (ngx_threaded) {
            ngx_wakeup_worker_thread(cycle);

        } else {
            ngx_event_process_posted(cycle, &ngx_posted_events);
        }
    }
}

从上面代码可以看到, nginx中ngx_process_events为事件处理的核心,该函数一直轮询是否有连接接收,如果有则根据配置直接处理事件或者将事件加入到全局变量ngx_posted_accept_events或者ngx_posted_events。

便于后续事件处理。

采用epoll模式时,定义为:ngx_process_events ----〉ngx_event_actions.process_events ---〉ngx_epoll_process_events

事件的添加不是一次全部添加完成的,比如连接时ngx_epoll_process_events只添加了ngx_event_accept事件,而处理时间中又会将http处理的ngx_http_init_request添加进来。

void
ngx_event_process_posted(ngx_cycle_t *cycle,
    ngx_thread_volatile ngx_event_t **posted)
{
    ngx_event_t  *ev;

    for ( ;; ) {

        ev = (ngx_event_t *) *posted;

        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                      "posted event %p", ev);

        if (ev == NULL) {
            return;
        }

        ngx_delete_posted_event(ev);

        ev->handler(ev);
    }
}

上面是事件处理函数, 很容易看到事件处理的逻辑,处理完一个事件之后, 就将自己本事件从链表上摘下来,处理另外一个事件,知道处理完成为止.







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值