linux驚群

來源:互聯網
上載者:User

標籤:

基本概念:子進程繼承父進程環境和內容相關的大部分內容的拷貝,其中就包括檔案描述符表。

父進程fork出來的子進程,複製父進程的檔案描述符。這些檔案描述符fd是獨立的,但是檔案描述符指向的系統檔案表項是唯一的,即是 struct file本身唯一。

同理,fork得到的子進程和父進程共用同一個socket(通訊端代表檔案)。fd與檔案關聯,通過綁定struct sockaddr通訊端地址空間,跟特定的ip和連接埠綁定在一起。

所以在子進程中accept(listen,....),雖然listen在不同進程中,代表不同的進程的檔案描述符,但是這個檔案描述符對應的通訊端是一樣的。又因為通訊端指定了通訊端地址,所以可以監聽來自用戶端的串連。

驚群的伺服器的模型:

父進程listen之後,子進程堵塞在accept函數這裡,這就是驚群發生的根本原因

驚群現象:

當父進程綁定一個連接埠監聽socket,然後fork出多個子進程,子進程們開始迴圈處理(比如accept)這個socket。每當使用者發起一個TCP串連時,多個子進程同時被喚醒,然後其中一個子進程accept新串連成功,餘者皆失敗,重新休眠。

驚群現象的危害:

在較老的unix系統中,當有串連到來時,accept()在每個阻塞在這的進程裡被喚醒。但是,只有這些進程中的一個能夠真正的accept這個串連,其他的進程accept將返回EAGAIN,驚群造成的結果是系統對使用者進程/線程頻繁的做無效的調度、環境切換,系統系能大打折扣。

解決:

我們不能只用一個進程去accept新串連嗎?然後通過訊息佇列等同步方式使其他子進程處理這些建立的串連,這樣驚群不就避免了?沒錯,驚群是避免了,但是效率低下,因為這個進程只能用來accept串連。對多核機器來說,僅有一個進程去accept,這也是程式員在自己創造accept瓶頸。所以,我仍然堅持需要多進程處理accept事件。

 

其實,在linux2.6核心上,accept系統調用已經不存在驚群了(至少我在2.6.18核心版本上已經不存在)。大家可以寫個簡單的程式試下,在父進程中bind,listen,然後fork出子進程,所有的子進程都accept這個監聽控制代碼。這樣,當新串連過來時,大家會發現,僅有一個子進程返回建立的串連,其他子進程繼續休眠在accept調用上,沒有被喚醒。(沒有被喚醒,繼續休眠)

 

解決方案:

 

linux驚群

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.