我們知道,nginx接受連接請(qǐng)求的過程,配置文件中設(shè)置
events {
accept_mutex off;
}
讓我們看看accept_mutex的意義:當(dāng)一個(gè)新連接到達(dá)時(shí),如果激活了accept_mutex,那么多個(gè)Worker將以串行方式來處理,其中有一個(gè)Worker會(huì)被喚醒,其他的Worker繼續(xù)保持休眠狀態(tài);如果沒有激活accept_mutex,那么所有的Worker都會(huì)被喚醒,不過只有一個(gè)Worker能獲取新連接,其它的Worker會(huì)重新進(jìn)入休眠狀態(tài),這就是「[驚群?jiǎn)栴}](http://en.wikipedia.org/wiki/Thundering_herd_problem)」。
Nginx缺省激活了accept_mutex,也就是說不會(huì)有驚群?jiǎn)栴}。對(duì)于驚群,如果喚醒的進(jìn)程數(shù)量相對(duì)比較龐大,驚群會(huì)引起性能的損失。但類似于nginx這種一般只啟動(dòng)跟cpu核心數(shù)差不多的進(jìn)程數(shù)。關(guān)閉accept_mutex或許是更好的選擇。
我們來看看避免驚群的代碼實(shí)現(xiàn)。
ngx_event.c
//是否使用accept互斥體。accept mutex的作用就是避免驚群,同時(shí)實(shí)現(xiàn)負(fù)載均衡
if (ngx_use_accept_mutex) {
if (ngx_accept_disabled > 0) { //大于0說明該進(jìn)程接收的連接過多,放棄一次爭(zhēng)搶accept mutex的機(jī)會(huì)
ngx_accept_disabled--;
} else {
if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
return;
}
if (ngx_accept_mutex_held) {
flags |= NGX_POST_EVENTS; //這個(gè)標(biāo)志是將所有產(chǎn)生的事件放入到一個(gè)隊(duì)列中。等釋放鎖以后再慢慢來處理事件。
} else {
if (timer == NGX_TIMER_INFINITE
|| timer > ngx_accept_mutex_delay) //設(shè)置最長(zhǎng)延遲多久,再次去爭(zhēng)搶鎖
{
timer = ngx_accept_mutex_delay;
}
}
}
進(jìn)程間通信采用共享內(nèi)存。mmap