這個內容在cnblogs中也討論過很多次了,這兩天大概看了一些資料,看到一些簡單的性能指標拿出來和大家討論一下。
Socket + Threads/ThreadPool
大概效能:小於1500個連線
實作:Accept一個Socket,就交給一個執行緒去管理,比較笨,但也比較有效,因為是同步方式,控制起來很方便。高階點的,就是交給一個執行緒池去管理,執行緒池由系統自動託管,省去了開銷執行緒的時間。一般小型項目,用這個完全足夠,開發也簡單。但要注意,如果若干Socket長時間佔用線程池中的線程,同時其它連接數又比較多,很容易出現提示說你沒有足夠的線程供使用。呵呵,讓Socket少做點事,少佔用時間,換一個快點的CPU是不錯的方式。另外,如果有一些比較好的第三方線程池元件,也可以選擇使用,例如SmartThreadPool。
Socket + Select
大概效能:大於1500個連接後效能下降
實作:Select是很常用的模型。是在阻塞功能中輪詢一個或多個Socket,將要處理的Socket放到一個IList中,當Select輪詢結束後,然後我們再自己處理這個IList中的Socket。具體的用法可以看一下MSDN。 Select的效率並不能說是高的,因為當佇列中待處理的Socket比較多的時候,處理最後幾個Socket相當於要遍歷所有前面的Socket,非常不划算的。
Socket + Asynchronous
大概效能:約7500個客戶端連線
實作:BeginXXXX,EndXXXX,再熟悉不過了吧。非同步Socket歸根到底,還是用的線程池技術,用線程池來處理非同步IO。這又引出個問題,.NET的執行緒池又是用的什麼實作方式,以前看過有人說,.NET的執行緒池是用的完成連接埠來實現的,我不知道這樣的說法是不是正確,從查到的資料中也沒有辦法確認(希望這點有朋友可以告訴我)。非同步Socket對於程式的處理流程來說比同步複雜了許多,非同步回呼函數的控制不如同步方式那麼直觀。但有一點我想應該是要注意的,就是回調函數應該輕裝上陣,不應該處理過多的事務,對傳遞資料的處理,應該交給其它線程進行處理。
IOCP(完成連接埠)
大概效能:約20000~50000個客戶端連線
實作:現在.NET下有一些偽IOCP,大家可以去搜尋一下,還沒看過開放出來的用這些偽IOCP來實現的SOCKET範例。我說的20000~50000個客戶端連接,是指在C++下開發的情況,這樣的情況下,需要用到的基本技術還包括記憶體池、查詢演算法等。
偽IOCP能實現多少最大連接,沒有資料可以查,如果有朋友知道,可以討論一下。另外上面提到的許多數據,是從一些資料上摘抄下來的,我沒有自己試過,只是拿出來和大家討論一下。我想,一個高效能的服務端程序,可能需要的技術不僅僅是採用什麼模型,還有許多細節需要注意,例如記憶體的處理,採用什麼演算法等等,當然,這僅僅是軟體成本上的,硬體上肯定也是需要投入的。