例如多伺服器用戶登錄,我要實時知道在線用戶人數(應該是個分散式的問題吧)。用什麼方法來實現高並發

1.是用一個主伺服器來維護這個全局變數2.還是每次有用戶登錄,就要伺服器之間相互通信來統計總人數

不知道目前主流的方法都這麼實現這個功能的?


這種情況一般不需要完全的準確性和實時性,設計過程中一般每個伺服器非同步上報,應用再通過輪詢獲取一個相對結果就行了。曾經的一個做法是,每個伺服器在zookeeper 上的對應節點每60s寫入當前的數據,然後服務查詢所有節點數據再加和。

在線人數不是一個需要實時和絕對準確的業務。

同步的方法比較貴,而且本來分散式的服務可以提供故障轉移的特性,同步數據又變成單點了。

僅僅是在線用戶數,可以:

1 每個伺服器提供一個API能查詢本地的數值,顯示的時候輪詢一次加起來。2 做一個獨立的計數服務,每台伺服器定時去刷新自己的數字。還有一個費力容易出錯的方案,計數其實速度非常快,比如Memcached就有原子操作+1/-1。可以在上線下線的時候改這個全局數字。這個方法費力是因為除了上線下線,還有很多伺服器故障狀態要處理。

容易出錯是因為一旦出錯就沒有機會修復。


其實非常簡單:

1.如果需要統計精準的數據,那麼就必須犧牲性能:

事務開始
鎖住第1台伺服器的用戶表
鎖住第2台伺服器的用戶表
.....

獲取第1台伺服器的在線用戶數量
獲取第2台伺服器的在線用戶數量
....
事務結束
把以上在線用戶數量,進行累加,返回結果

2.如果需要保持高性能,那麼就必須犧牲統計的精準度:

獲取第1台伺服器的在線用戶數量
獲取第2台伺服器的在線用戶數量
....
把以上在線用戶數量,進行累加,返回結果

以上只是針對普通人進行解釋的方案。我自己則更喜歡這樣的結構:


之前不是日報有個文章寫遊戲伺服器的變遷么,他提到現在主流是星形結構,也就是說所有的slave都跟master交互,master來維護這個統計變數,這樣看起來就簡單的很阿。無論用資料庫,還是用code寫個socket,都相當容易完成了。

=================你要做成push,不要做成pull,這樣就不會有同步的問題了。這也是對一些其他答案的看法。
每個伺服器獨立統計,然後上報匯總;這樣知道了每個伺服器的量級,也可以知道總的量級。
推薦閱讀:
相关文章