欢迎转载,转载请注明出处
http://blog.csdn.net/yankai0219/article/details/8453297
文章内容
0.序
1.概述:
2.几个变量的作用
3.ngx_process_events_and_timers结构图
4.ngx_process_events_and_timers函数详解
5.分析Nginx对accept事件的处理
6.小结
|
0.序:
本文学习了阿里巴巴大牛们
Nginx源码分析-事件循环的文章,并对于里面内容进行了更为详尽的分析。并且参考了众多网上文章
http://bollaxu.iteye.com/blog/855457
1.概述:
事件循环这个概念貌似在windows编程中提得更多,Linux程序却很少提及这个概念。本文所提及的事件循环其实就是worker cycle,由于此处将关注的不再是worker进程,而是worker进程在循环过程中关于事件处理的环节,因此就盗用了事件循环这个概念。在具体看代码前,先看一下这个“循环”的概貌:

根据文章1总体概述,我们可以看到ngx_process_events_and_timers函数之前,进行了很多初始化操作。接下来只是分析事件驱动的核心ngx_process_events_and_timers函数,当然这也是worker进程的核心。
2.几个变量的作用
首先说明几个变量的作用
1)ngx_accept_mutex_held:表示进程当前是否持有锁
2)ngx_accept_mutex_delay:当获得锁失败后,再次去请求锁的间隔时间,这个时间在配置文件中设置
3)NGX_POST_EVENTS标记:设置了这个标记就说明当socket有数据被唤醒时,不会马上accept或者读取,而是将这个事件保存起来,然后当我们释放锁以后,才会进行accept或者读取这个句柄。
4)ngx_posted_accept_events:ngx_event_t数组,暂存epoll从监听套接口wait到的accept事件。该数组不为空,就表示有accept事件发生。
5)ngx_posted_events:ngx_event_t数组,暂存进程中非accept事件。
6)ngx_use_accept_mutex:代表是否使用accept互斥体。默认是使用,accept_mutex off;指令关闭。 accept mutex的作用就是避免惊群,同时实现负载均衡。在配置文件中可以配置。
7)ngx_accept_disabled :用于实现进程关于连接的基本负载均衡。ngx_accept_disabled变量在ngx_event_accept函数中计算。 如果ngx_accept_disabled大于了0,就表示该进程接受的 连接过多,因此就放弃一次争抢accept mutex的机会,同时将 自己减1。然后,继续处理已有连接上的事件。Nginx就借用 此变量实现了进程关于连接的基本负载均衡。
8)ngx_shmtx_t中成员变量fd:进程间共享的文件句柄。通过这个fd来控制进程的互斥。这部分内容在nginx中锁的设计以及惊群的处理有详细说明。
9)dalta:对epoll wait事件的耗时统计,存在毫秒级的耗时就对所有事件的timer进行检查;如果time out就从timer rbtree中删除到期的timer,同时调用相应事件的handler函数完成处理。
3.ngx_process_events_and_timers结构图

4.ngx_process_events_and_timers函数详解
void
ngx_process_events_and_timers(
ngx_cycle_t
*cycle)
{
ngx_uint_t
flags;
ngx_msec_t
timer, delta;
if
(ngx_timer_resolution) {
timer = NGX_TIMER_INFINITE;
flags = 0;
}
else
{
timer = ngx_event_find_timer();
flags = NGX_UPDATE_TIME;
#if
(NGX_THREADS)
if
(timer == NGX_TIMER_INFINITE || timer > 500) {
timer = 500;
}
#endif
}
if
(ngx_use_accept_mutex) {
/*默认使用accept mutex*/
if
(ngx_accept_disabled > 0) {
/*用于进程中连接的基本负载均衡*/
ngx_accept_disabled--;
}
else
{
if
(ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
/*尝试去获取锁,这部分内容在文章9Nginx中accept互斥锁中有详细讲述*/
return
;
}
if
(ngx_accept_mutex_held) {
/*
ngx_accept_mutex_held=1,表示
当前进程持有锁,那么所有接收到的accept事件都不会马上处理,而是被保存到ngx_posted_accept_events数组中*/
flags |= NGX_POST_EVENTS;
}
else
|