程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> NGINX 定時器

NGINX 定時器

編輯:關於C語言

寫在前面

寫NGINX系列的隨筆,一來總結學到的東西,二來記錄下疑惑的地方,在接下來的學習過程中去解決疑惑。

也希望同樣對NGINX感興趣的朋友能夠解答我的疑惑,或者共同探討研究。

整個NGINX系列的文章中,我會將我的疑惑用紅色標出,希望能遇到前輩在評論中給我解答迷津。

定時器

在介紹定時器之前,先簡要說下nginx處理事件的流程和方式。

Worker進程的主要流程:

 

 1 static void
 2 ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data){
 3   for(;;) {
 4   if(ngx_exiting) {}
 5   ngx_process_events_and_timers(cycle);
 6   if (ngx_terminate) {}
 7   if (ngx_quit) {}
 8   if (ngx_reopen) {}
 9 }
10 
11 void
12 ngx_process_events_and_timers(ngx_cycle_t *cycle) {
13   (void) ngx_process_events(cycle, timer, flags);
14 }

 

ngx_process_events調用epoll(linux下)實現事件的處理。

ngx_process_events處理事件有兩種方式:一是直接調用處理函數處理,二是將事件放到post隊列中,函數返回後再處理隊列中的事件。

在使用了 NGX_POST_EVENTS標記時,ngx_process_events不直接處理事件,將事件放到Post隊列中,待函數返回,再在隊列中取出事件處理。

因為調用ngx_process_events會加鎖(為什麼加鎖?),函數返回後,將鎖釋放再處理事件,可以減少鎖的占用時間。

 

以上是nginx處理事件的大體方式,下面介紹nginx中定時器的實現。

Nginx定時器使用紅黑樹組織(為什麼使用紅黑樹,紅黑樹效率高到哪?可以研究下)存儲,這個不多說。

Nginx定時器的觸發有兩種方式,第一種是設置時間信號。

ngx_event_process_init函數中 ,設置了時間信號,每隔固定時間觸發,時間信號的處理函數,只是設置ngx_event_timer_alarm = 1,但他會中斷ngx_process_events中epoll_wait的處理,epoll_wait返回後,調用ngx_time_update更新時間,接著返回到函數ngx_process_events_and_timers中處理,ngx_process_events_and_timers中,會調用ngx_event_expire_timers,查詢超時的事件並處理。

但這種方式有個問題,如果事件信號是在處理IO事件時(epoll_wait調用之後)發生的,那麼定時器的查詢遍歷,只能到下一次epoll_wait調用時才會處理,如果這時有IO事件發生,那麼epoll_wait可以立即返回,然後因為上次信號發生已經置ngx_event_timer_alarm = 1,可以立即更新時間,ngx_process_events返回後可以處理定時器事件。但如果沒有IO事件發生,epoll_wait會阻塞到下次時間信號到來,然後處理定時器事件,這樣豈不大大降低了定時器的精確度。這塊nginx怎麼處理的?

 

另外每隔固定時間(具體設置的時間信號的時間)才更新時間值,甚至可能是兩倍時間信號的時間才更新時間值,那麼代碼中在插入的定時器,實際觸發時間和理論時間就會有這麼大的誤差。是不是這樣呢?

 

Nginx定時器的第二種觸發方式是利用epoll_wait的超時。

每次在調用epoll_wait之前,nginx都會取得下一個最小(最早要觸發)的定時器的時間值,然後拿這個值作為epoll_wait的超時時間。這樣epoll_wait在返回後就可以處理超時事件了。既可以在頻繁IO的情況下處理超時,又可以在IO少量的情況下處理超時。

這種方式epoll_wait返回後,都會先更新時間,這樣epoll_wait返回後,在IO事件的處理代碼中加入定時器,誤差不會太大,因為時間剛剛被更新。

但這個方法的問題是,IO頻繁的情況下,也會頻繁更新時間,是否會影響性能?

這兩種方式各自的優缺點是哪些呢?

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved