遊戲伺服器啟動多少個執行緒合適

weixin_33670713發表於2018-10-07

執行緒是伺服器的一種希有資源,它的建立,銷燬,切換都需要很多伺服器的其它資源。而在遊戲伺服器中,只要沒有在多執行緒之間有共享資料的操作,都是可以併發的,即可以是多執行緒操作的。比如不同使用者各自的操作處理,或同一個使用者的資料更新到資料庫的操作等等。那為了提高併發性,是不是執行緒越多越好呢?多少才合適呢?先不說遊戲伺服器的特殊性,就按普通的伺服器業務來說,最合適的執行緒數是多少呢?說到執行緒,那一定是和cpu核數相關的。在其它的文章裡面,我們可以看到這樣的結論:


一般說來,大家認為執行緒池的大小經驗值應該這樣設定:(其中N為CPU的個數)

如果是CPU密集型應用,則執行緒池大小設定為N+1

如果是IO密集型應用,則執行緒池大小設定為2N+1

但是,IO優化中,這樣的估算公式可能更適合:

最佳執行緒數目 = ((執行緒等待時間+執行緒CPU時間)/執行緒CPU時間 )* CPU數目

因為很顯然,執行緒等待時間所佔比例越高,需要越多執行緒。執行緒CPU時間所佔比例越高,需要越少執行緒。

下面舉個例子:

比如平均每個執行緒CPU執行時間為0.5s,而執行緒等待時間(非CPU執行時間,比如IO)為1.5s,CPU核心數為8,那麼根據上面這個公式估算得到:((0.5+1.5)/0.5)*8=32。這個公式進一步轉化為:

最佳執行緒數目 = (執行緒等待時間與執行緒CPU時間之比 + 1)* CPU數目


綜上所看,執行緒數並不是越多越好,而是要適量。比如如果遊戲伺服器是使用netty開發的,那麼boss執行緒一般1~2個就足夠,而work執行緒可以根據伺服器配置和上面的公式算出最合適的執行緒數。我們知道,在netty的業務操作中,也就是Channel的Handlerr操作中,不應該有IO操作,因為IO操作時間長,而所有的channel是共用work執行緒的,如果有IO操作,就會卡往其它的請求處理。所以一般來說,遊戲伺服器中的資料應該提前載入到記憶體中,這樣即可消除IO操作。

那麼問題來了,遊戲伺服器中不可能沒有IO操作,比如登陸時資料庫的查詢,部分重要資料的即時更新到資料庫,或向其它服務傳送http請求等等。這該怎麼處理呢?其實我們發現,這些操作都是可以並行的,他們之間沒有依賴關係也沒有共享資料,即沒有什麼順序要求(當前同一個使用者的對資料庫的操作應該是有序的,同一個使用者的操作應該放到同一個單執行緒池中處理,當然多個使用者可以共用這個單執行緒池,使用netty的執行緒模型即可,EventExecutor)。所以我們可以把這些操作放到一個執行緒池中。執行緒池的數量和每個執行緒池中的執行緒數我們可以很好的把控。這個可以封裝到伺服器的框架裡面。

3793531-3e0ef12799450b49.png
歡迎品嚐:點選這裡

技術交流,歡迎留言,也可新增QQ交流群:66728073,197321069



相關文章