2011-07-08 26 views
0

我有一個用C#.net編寫的TCP/IP服務器,它可以一次容易地連接10,000個連接。但是,當從套接字接收到回調時,它將由應用程序線程池中的新線程處理。這意味着真正的併發通信限制是線程池內的線程數量。例如,如果這些10,000個連接都嘗試同時發送數據,則大多數人將不得不等待線程池以儘可能快的速度運行。任何人都可以通過高性能套接字服務分享他們的經驗,並告知大型公司如何確保10,000個連接不僅可以同時連接,而且還可以同時進行通信?謝謝如何在應用程序線程池限制時提高TCP/IP服務器的可伸縮性

回答

2

不要在回調中內聯處理數據包。在那裏完成最低限度的工作,然後通過生產者 - 消費者隊列將它們交給單獨的工作者線程池,(理想情況下)不會阻塞生產者線程,這是您的套接字偵聽器。 BlockingCollection<T>可能在這裏很有用。

你必須要小心的是,隊列不無限地增長 - 如果你的消費者比生產者慢了很多,在正常負載下隊列增長,您有哪些限制網絡接收是顯而易見的解決的問題,儘管不受歡迎。

+0

嗨,謝謝你的回答,你建議不要在回調中處理內聯數據包;我正在做的是使用異步套接字,我的功能是有效的如下,你能確認這是適合你的建議嗎?謝謝.. private void receiveClientCallback(IAsyncResult result){SocketConnection client =(SocketConnection)result.AsyncState; client.EndReceive(result); System.Threading.ThreadPool.QueueUserWorkItem(new ConnectionHandler(this,client).ThreadPoolCallback);} – Chris

+0

Broadly這是主意。在實踐中的適用性取決於誰還在使用'ThreadPool'進程。使用你自己的隊列和線程池會給你更嚴格的控制 - 在'ThreadPool'你正在與其他'東西'競爭,並且應該明白你的系統是什麼,知道你是否應該使用私有池。調整'ThreadPool'參數可能是您所需要的。 –

+0

線程池是爲連接處理程序線程保留的,它只進行一些數據庫查詢,然後將特定的數據包內容保存到文件中,而另一服務在其自己的線程池中拾取並處理。 – Chris

1

你在這裏犯了一個錯誤。無論您有多少線程,數據總是必須等待,除非您有一個CPU核心每個連接。可伸縮性並不是無限制的相對論,而是爲了處理大量的優化並保持CPU的全部能力。

線程池的大小是完美的。一旦CPU達到完全利用率,無論如何你都不能做任何事情。

,並建議大公司將如何去保證了10,000個連接不僅可以 連接的同時,還可以在同一時間進行溝通?

許多計算機擁有500個處理器內核。訣竅是:什麼延遲是可以接受的。你不需要即時溝通。你試圖擺脫錯誤的結局。

+0

感謝TomTom,你似乎在闡明我在想什麼,這應該是一樣好,現在沒有其他辦法可以改善這一點,從這裏開始,它必須是硬件。我有一臺8核筆記本電腦,可以在幾秒鐘內接受10,000個連接,但如果這些連接繼續發送認證數據包,這會導致線程查詢數據庫,然後他們繼續傳輸3kb的數據,它需要7分鐘的總時間來接受,驗證,然後接受來自10,000個連接的3kb數據包 – Chris

+0

我很擔心,因爲我們要運行此服務器的虛擬專用服務器只有1個ram和1個內核。如果我們將VPS增加到8核心,並且仍然需要7分鐘才能從10,000個連接接受3kb,那麼我想我們需要幾臺服務器,每臺服務器運行幾個服務副本,以處理這種連接數量。 – Chris

+0

哦,親愛的,你的bean計數器想要虛擬化你的系統?聽起來這個配置不好。你很擔心伊莫。 –

相關問題