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