天天看點

workerman:reusePort->避免驚群效應

說明:

設定目前worker是否開啟監聽端口複用(socket的SO_REUSEPORT選項),預設為false,不開啟。

開啟監聽端口複用後允許多個無親緣關系的程序監聽相同的端口,并且由系統核心做負載均衡,決定将socket連接配接交給哪個程序處理,避免了驚群效應,可以提升多程序短連接配接應用的性能。

注意:此特性需要PHP版本>=7.0

什麼是驚群:

舉一個很簡單的例子,當你往一群鴿子中間扔一塊食物,雖然最終隻有一個鴿子搶到食物,但所有鴿子都會被驚動來争奪,沒有搶到食物的鴿子隻好回去繼續睡覺, 等待下一塊食物到來。這樣,每扔一塊食物,都會驚動所有的鴿子,即為驚群。對于作業系統來說,多個程序/線程在等待同一資源是,也會産生類似的效果,其結 果就是每當資源可用,所有的程序/線程都來競争資源,造成的後果:

參考

1)系統對使用者程序/線程頻繁的做無效的排程、上下文切換,系統系能大打折扣。

2)為了確定隻有一個線程得到資源,使用者必須對資源操作進行加鎖保護,進一步加大了系統開銷。

對于驚群效應的場景描述,最常見的就是對于socket操作符的accept操作的描述。當多個使用者程序/線程同時監聽同一個端口時,由于實際上一個請求過來,隻有一個程序/線程accept成功,是以就會産生驚群效應。

實際上這是一個很古老的問題。linux作業系統在核心層面很早就解決了這個問題,一個請求過來,核心隻會喚醒一個程序來accept,這樣就沒有驚群現象了。但是在很多場景下,隻要有競争,就可能會出現驚群效應。比如常見的生産者-消費者模型,一般來說消費可能會比較耗時,是以消費者會有多個。當突然有生産者往隊列裡面投了一個job時,這些消費者就會一哄而上去隊列中搶這個job,這就發生了驚群效應。

一個基本的線程池架構也是基于生産者-消費者模型的。也就是說隻要用到了程序池或者線程池,你可能就避免不了要處理驚群效應帶來的問題。