zoukankan      html  css  js  c++  java
  • Nginx的事件处理机制

    1. void  
    2. ngx_process_events_and_timers(ngx_cycle_t *cycle)  
    3. {  
    4.     ngx_uint_t  flags;  
    5.     ngx_msec_t  timer, delta;  
    6.     if (ngx_timer_resolution) {  
    7.         timer = NGX_TIMER_INFINITE;  
    8.         flags = 0;  
    9.     } else {  
    10.         timer = ngx_event_find_timer();  
    11.         flags = NGX_UPDATE_TIME;  
    12.     }  
    13.     /*ngx_use_accept_mutex变量代表是否使用accept相互排斥体 
    14.      默认是使用,accept_mutex off;指令关闭。 
    15.      accept mutex的作用就是避免惊群,同一时候实现负载均衡。 
    16.      */  
    17.     if (ngx_use_accept_mutex) {  
    18.       
    19.         /* 
    20.          ngx_accept_disabled变量在ngx_event_accept函数中计算。 
    21.          假设ngx_accept_disabled大于了0,就表示该进程接受的 
    22.          连接过多,因此就放弃一次争抢accept mutex的机会,同一时候将 
    23.          自己减1。然后,继续处理已有连接上的事件。Nginx就借用 
    24.          此变量实现了进程关于连接的基本负载均衡。 
    25.          */  
    26.         if (ngx_accept_disabled > 0) {  
    27.             ngx_accept_disabled--;  
    28.         } else {  
    29.             /* ngx_accept_disabled小于0,连接数没超载*/  
    30.               
    31.             /*尝试锁accept mutex,仅仅有成功获取锁的进程,才会将listen 
    32.               套接字放入epoll中。因此,这就保证了仅仅有一个进程拥有 
    33.               监听套接口,故全部进程堵塞在epoll_wait时,不会出现惊群现象。 
    34.             */  
    35.             if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {  
    36.                 return;  
    37.             }  
    38.             if (ngx_accept_mutex_held) {  
    39.                 /*获取锁的进程,将加入一个NGX_POST_EVENTS标志, 
    40.                   此标志的作用是将全部产生的事件放入一个队列中, 
    41.                   等释放锁后,再慢慢来处理事件。由于,处理事件可能 
    42.                   会非常耗时,假设不先释放锁再处理的话,该进程就长 
    43.                   时间霸占了锁,导致其它进程无法获取锁,这样accept 
    44.                   的效率就低了。 
    45.                 */  
    46.                 flags |= NGX_POST_EVENTS;   
    47.             } else {  
    48.               
    49.                 /*没有获得锁的进程,当然不须要NGX_POST_EVENTS标志了。 
    50.                   但须要设置最长延迟多久,再次去争抢锁。 
    51.                 */  
    52.                 if (timer == NGX_TIMER_INFINITE  
    53.                     || timer > ngx_accept_mutex_delay)  
    54.                 {  
    55.                     timer = ngx_accept_mutex_delay;  
    56.                 }  
    57.             }  
    58.         }  
    59.     }  
    60.       
    61.     delta = ngx_current_msec;  
    62.     /*epoll開始wait事件了,ngx_process_events的详细实现是相应到 
    63.       epoll模块中的ngx_epoll_process_events函数。单独分析epoll 
    64.       模块的时候,再详细看看。 
    65.     */  
    66.     (void) ngx_process_events(cycle, timer, flags);  
    67.     delta = ngx_current_msec - delta; /*统计本次wait事件的耗时*/  
    68.     /*ngx_posted_accept_events是一个事件队列 
    69.       暂存epoll从监听套接口wait到的accept事件。 
    70.       前文提到的NGX_POST_EVENTS标志被使用后,就会将 
    71.       全部的accept事件暂存到这个队列。 
    72.        
    73.       这里完毕对队列中的accept事件的处理,实际就是调用 
    74.       ngx_event_accept函数来获取一个新的连接,然后放入 
    75.       epoll中。 
    76.     */  
    77.     if (ngx_posted_accept_events) {  
    78.         ngx_event_process_posted(cycle, &ngx_posted_accept_events);  
    79.     }  
    80.     /*全部accept事件处理完毕,假设拥有锁的话,就赶紧释放了。 
    81.       其它进程还等着抢了。 
    82.     */  
    83.     if (ngx_accept_mutex_held) {  
    84.         ngx_shmtx_unlock(&ngx_accept_mutex);  
    85.     }  
    86.     /*delta是上文对epoll wait事件的耗时统计,存在毫秒级的耗时 
    87.       就对全部事件的timer进行检查,假设time out就从timer rbtree中, 
    88.       删除到期的timer,同一时候调用相应事件的handler函数完毕处理。 
    89.     */  
    90.     if (delta) {  
    91.         ngx_event_expire_timers();  
    92.     }  
    93.     /*处理普通事件(连接上获得的读写事件)队列上的全部事件, 
    94.       由于每一个事件都有自己的handler方法,该怎么处理事件就 
    95.       依赖于事件的详细handler了。 
    96.     */  
    97.     if (ngx_posted_events) {  
    98.         if (ngx_threaded) {  
    99.             ngx_wakeup_worker_thread(cycle);  
    100.         } else {  
    101.             ngx_event_process_posted(cycle, &ngx_posted_events);  
    102.         }  
    103.     }  
    104. }  
  • 相关阅读:
    oracle 11g行转列 列转行
    System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本
    ORA-00257: 归档程序错误。在释放之前仅限于内部连接
    java 回传参数
    Oracle 删除表分区
    Oracle 删除重复数据只留一条
    cmd下windows批处理,获取当前系统时间,生成日志文件名
    c# 应用程序部署发布
    eclipse 集成 STS 插件
    Mamen所需要的jar包怎么生成
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4015466.html
Copyright © 2011-2022 走看看