文章5:Nginx源码分析--事件循环

本文详细探讨了Nginx的事件循环,重点分析了ngx_process_events_and_timers函数,介绍了ngx_accept_mutex_held、ngx_posted_events等关键变量的作用,并详细阐述了Nginx如何处理accept事件,实现负载均衡和避免惊群现象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

欢迎转载,转载请注明出处 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 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值