Nginx惊群现象的两种解决办法
驚群現(xiàn)象:
驚群現(xiàn)象是指由多個worker進程監(jiān)聽同一個Socket事件時,當事件發(fā)生時,相關(guān)的所有進程被驚醒,但最終只能有一個進程對該事件進行處理,其他進程會重新休眠,從而導(dǎo)致系統(tǒng)資源的浪費和系統(tǒng)性能的下降。驚群包含accept驚群和epoll驚群。
驚群的本質(zhì):睡眠和喚醒問題,屬于典型的觀察者模式,進程通過等待事件,掛載關(guān)注的對象的等待隊列上,但對象有資源時就喚醒等待隊列上的進程,至于是否產(chǎn)生驚群關(guān)鍵在于wake_up_common 是否無差別地喚醒等待隊列上的進程
Epoll驚群的處理:
(1)Accpet_mutex
通過開啟accept_mutex鎖,每個Worker進程都會去搶自旋鎖,只有搶到自旋鎖的才能將Socket加入到Epoll中,Accept新的請求,然后釋放鎖
(2)EPOLLEXCLUSIVE
linux4.5以后內(nèi)核版本中,增加了EPOLLEXCLUSIVE,該選項可以通過EPOLL_CTL_ADD對要監(jiān)控的fd添加EPOLLEXCLUSIVE標記,這樣fd的epoll entry就帶上了EPOLLEXCLUSIVE標記。當有事件到來時,喚醒第一個帶有此標記的epoll entry就退出喚醒過程。通過增加這樣一個標記,多線程共用同一個epoll的驚群現(xiàn)象得到了解決。
(3)SO_REUSEPORT
SO_REUSEPORT 是驚群最好的解決方法,Nginx 在 1.9.1 中加入了這個選項,每個 worker 進程都有自己的 socket,這些 socket 都 bind 同一個端口。當新請求到來時,內(nèi)核根據(jù)四元組信息進行負載均衡,非常高效
Accpet驚群的處理
當多個進程/線程調(diào)用accept監(jiān)聽同一個socket上時,一個新連接的到來就會導(dǎo)致所有阻塞在該socket上的進程/線程都被喚醒,但是最后只有一個進程/線程可以accept成功,其余的又會重新休眠,這樣就產(chǎn)生了驚群現(xiàn)象。通過維護一個等待隊列(隊列的元素為進程),使用WQ_FLAG_EXCLUSIVE標志位(互斥標志位),非exclusive元素會加在等待隊列的前面,而exclusive元素會加在等待隊列的末尾,當有新連接到來時,會遍歷等待隊列,并且只喚醒第一個exclusive進程(非互斥的進程由于排在隊列前面也會被喚醒)就退出遍歷,阻塞在accept上的進程都是互斥的(也就是WQ_FLAG_EXCLUSIVE標志位會被置位),因此現(xiàn)在的linux內(nèi)核調(diào)用accept時,多個進程/線程只有一個會被喚醒并建立新連接
總結(jié)
以上是生活随笔為你收集整理的Nginx惊群现象的两种解决办法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL SERVER 锁定的实例
- 下一篇: Lambda中的常用sql方法