Worker搶占機制
master監(jiān)聽80端口者铜,多個worker進程fork master進程腔丧。client發(fā)送請求時构蹬,worker會爭搶accept_mutex鎖,
然后worker才會處理請求悔据。
events {
accept_mutex off;
}
讓我們看看accept_mutex的意義:當一個新連接到達時庄敛,如果激活了accept_mutex,那么多個Worker將以串行方式來處理科汗,其中有一個Worker會被喚醒藻烤,其他的Worker繼續(xù)保持休眠狀態(tài);如果沒有激活accept_mutex头滔,那么所有的Worker都會被喚醒怖亭,不過只有一個Worker能獲取新連接,其它的Worker會重新進入休眠狀態(tài)坤检,這就是「[驚群問題](http://en.wikipedia.org/wiki/Thundering_herd_problem)」兴猩。
Nginx缺省激活了accept_mutex,也就是說不會有驚群問題早歇,但真的有那么嚴重么倾芝?實際上Nginx作者Igor Sysoev曾經(jīng)給過相關(guān)的[解釋](http://forum.nginx.org/read.php?2,1641,1686#msg-1686):
> OS may wake all processes waiting on accept() and select(), this is called thundering herd problem. This is a problem if you have a lot of workers as in Apache (hundreds and more), but this insensible if you have just several workers as nginx usually has. Therefore turning accept_mutex off is as scheduling incoming connection by OS via select/kqueue/epoll/etc (but not accept()).
簡單點說:Apache動輒就會啟動成百上千的進程,如果發(fā)生驚群問題的話箭跳,影響相對較大晨另;但是對Nginx而言,一般來說谱姓,[worker_processes](http://wiki.nginx.org/CoreModule#worker_processes)會設(shè)置成CPU個數(shù)借尿,所以最多也就幾十個,即便發(fā)生驚群問題的話屉来,影響相對也較小路翻。
另:高版本的Linux中,accept不存在驚群問題茄靠,不過epoll_wait等操作還有茂契。
…
假設(shè)你養(yǎng)了一百只小雞,現(xiàn)在你有一粒糧食嘹黔,那么有兩種喂食方法:
* 你把這粒糧食直接扔到小雞中間账嚎,一百只小雞一起上來搶莫瞬,最終只有一只小雞能得手,其它九十九只小雞只能鎩羽而歸疼邀。這就相當于關(guān)閉了accept_mutex喂江。
* 你主動抓一只小雞過來,把這粒糧食塞到它嘴里旁振,其它九十九只小雞對此渾然不知获询,該睡覺睡覺涨岁。這就相當于激活了accept_mutex。
可以看到此場景下吉嚣,激活accept_mutex相對更好一些梢薪,讓我們修改一下問題的場景,我不再只有一粒糧食尝哆,而是一盆糧食秉撇,怎么辦?
此時如果仍然采用主動抓小雞過來塞糧食的做法就太低效了秋泄,一盆糧食不知何年何月才能喂完琐馆,大家可以設(shè)想一下幾十只小雞排隊等著喂食時那種翹首以盼的情景。此時更好的方法是把這盆糧食直接撒到小雞中間恒序,讓它們自己去搶瘦麸,雖然這可能會造成一定程度的混亂,但是整體的效率無疑大大增強了歧胁。
…
Nginx缺省激活了accept_mutex滋饲,是一種保守的選擇。如果關(guān)閉了它喊巍,可能會引起一定程度的驚群問題了赌,表現(xiàn)為上下文切換增多(sar -w)或者負載上升,但是如果你的網(wǎng)站訪問量比較大玄糟,為了系統(tǒng)的吞吐量勿她,我還是建議大家關(guān)閉它。
Nginx事件處理
client1連接worker1阻塞時阵翎,worker1會去處理client2逢并。(epoll模型)