目前與我建立一個HTTP服務器上的實驗支持保持活動插座。服務器由一個監聽線程使用select(...)和四個由線程池管理的工作線程進行多線程處理。目前,我正在Core I3 330M上管理大約每秒14k-16k的請求,文檔長度爲70字節,響應時間爲6-10ms。但是這沒有保持活力,並且在工作完成時我立即關閉了所有的套接字。問題一個土生土長的HTTP服務器
編輯:工作線程處理'作業',當檢測到套接字上的活動時調度,服務請求。 「工作」完成後,如果沒有更多的「工作」,我們會睡覺,直到更多的「工作」被派出,或者如果已經有一些工作可用,我們開始處理其中的一個。當我開始嘗試實施保活的支持
我的問題開始。隨着保持活動激活,我只能用100個開放式套接字管理每秒1.5k-2.2k的請求。這個數字通過1000個開放式插座增長到12k左右。在這兩種情況下,響應時間都在60-90毫秒左右。我覺得這很奇怪,因爲我目前的假設認爲請求應該升高而不是降低,並且響應時間應該有望下降,但絕對不會升高。
我試過幾種不同的策略以固定低性能:
-
1.呼叫選擇(...)/ PSELECT(...)有超時值,以便我們能夠重建我們FD_SET結構和聽到我們阻止後到達的任何其他套接字,併爲檢測到的套接字活動提供服務。 (除了性能低,這裏還有插座的問題被關閉,而我們封鎖,導致選擇(...)/ PSELECT(...)報告壞的文件描述符。)
-
2.有一個監聽線程只接受新的連接和一個保持活動狀態的線程,通過管道通知我們阻塞之後到達的任何新套接字以及任何新的套接字活動,並重建FD_SET。 (與'1'相同的附加問題)。
-
3.選擇(...)/ PSELECT(...)以超時,當新的工作是必須要做的,分離爲具有活性的插座的鏈接列表條目,並將其添加回的請求時已經提供服務。重建FD_SET希望會更快。這樣我們也避免試圖聽任何不好的文件描述符。
-
4.合併(2.)和(3.)。
-
- 。可能還有幾個,但他們逃脫我。
保活套接字存儲在一個簡單的鏈接列表中,其添加/刪除方法被pthread_mutex鎖包圍,負責重建FD_SET的功能也具有此鎖。
我懷疑它是在這裏的主要元兇互斥的不斷鎖定/解鎖,我試着來分析這個問題,但沒有gprof的還是谷歌perftools一直非常合作,無論是引入極端不穩定或純拒不收集所有數據(這可能是我不知道如何正確使用這些工具)。但是移除鎖可能會使鏈表處於非正常狀態並可能崩潰或將程序置於無限循環中。 我也懷疑選擇(...)/ pselect(...)超時,但我很確信這不是問題,因爲即使沒有它,低性能也會保持。
我在我應該如何處理保持活動插座一個損失,我爲此想,如果你人在那裏有關於如何解決低性能或有任何建議,任何其他方法我可以使用任何建議去支持保持活着的插座。
- 如果您需要更多的信息,以便能夠正確回答我的問題,不要猶豫,問它,我將盡我所能,爲你提供必要的信息,並與這個新的信息更新的問題。
爲了分析,你可以使用'oprofile',它應該比'gprof'少一些侵入性。 – ninjalj 2011-04-26 20:15:26
你可以發佈執行鎖定的代碼嗎?你保護什麼樣的數據結構(鏈接列表?)以及該數據結構上的哪些操作受到鎖保護(添加/刪除?)或什麼? – johnnycrash 2011-04-27 01:49:36
我使用C開發的Web服務器「GoAhead」,並根據需要進行修改。你可以使用它作爲參考。 – AjayR 2011-04-27 05:10:40