遊戲服務端架構發展史(中)

skywind發表於2015-07-29

遊戲服務端架構發展史(上)

型別4:第三代遊戲伺服器 2007

從魔獸世界開始無縫世界地圖已經深入人心,比較以往遊戲玩家走個幾步還需要切換場景,每次切換就要等待 LOADING個幾十秒是一件十分破壞遊戲體驗的事情。於是對於 2005年以後的大型 MMORPG來說,無縫地圖已成為一個標準配置。比較以往按照地圖來切割遊戲而言,無縫世界並不存在一塊地圖上面的人有且只由一臺伺服器處理了:


每臺 Node伺服器用來管理一塊地圖區域,由 NodeMaster(NM)來為他們提供總體管理。更高層次的 World則提供大陸級別的管理服務。這裡省略若干細節伺服器,比如傳統資料庫前端,登入伺服器,日誌和監控等,統統用 ADMIN概括。在這樣的結構下,玩家從一塊區域走向另外一塊區域需要簡單處理一下:

玩家1完全由節點A控制,玩家3完全由節點B控制。而處在兩個節點邊緣的2號玩家,則同時由A和B提供服務。玩家2從A移動到B的過程中,會同時向A請求左邊的情況,並向B請求右邊的情況。但是此時玩家2還是屬於A管理。直到玩家2徹底離開AB邊界很遠,才徹底交由B管理。按照這樣的邏輯將世界地圖分割為一塊一塊的區域,交由不同的 Node去管理。

對於一個 Node所負責的區域,地理上沒必要連線在一起,比如大陸的四周邊緣部分和高山部分的區塊人比較少,可以統一交給一個Node去管理,而這些區塊在地理上並沒有聯絡在一起的必要性。一個 Node到底管理哪些區塊,可以根據遊戲實時執行的負載情況,定時維護的時候進行更改 NodeMaster 上面的配置。

於是碰到第一個問題是很多 Node伺服器需要和玩家進行通訊,需要問管理伺服器特定UID為多少的玩家到底在哪臺 Gate上,以前按場景切割的伺服器這個問題不大,問了一次以後就可以快取起來了,但是現在伺服器種類增加不少,玩家又會飄來飄去,按UID查詢玩家比較麻煩;另外一方面 GATE需要動態根據座標計算和哪些 Node通訊,導致邏輯越來越厚,於是把:“使用者物件”從負責連線管理的 GATE中切割出來勢在必行於是有了下面的模型:

閘道器伺服器再次退回到精簡的網路轉發功能,而使用者邏輯則由按照 UID劃分的 OBJ伺服器來承擔,GATE是按照網路接入時的負載來分佈,而 OBJ則是按照資源的編號(UID)來分佈,這樣和一個使用者通訊直接根據 UID計算出 OBJ伺服器編號傳送資料即可。而新獨立出來的 OBJ則提供了更多高層次的服務:

  • 物件移動:管理具體玩家在不同的 Node所管轄的區域之間的移動,並同需要的 Node進行溝通。
  • 資料廣播:Node可以給每個使用者設定若干 TAG,然後通知 Object Master 按照TAG廣播。
  • 物件訊息:通用訊息推送,給某個使用者傳送資料,直接告訴 OBJ,不需要直接和 GATE打交道。
  • 好友聊天:角色之間聊天直接走 OBJ/OBJ MASTER。

整個伺服器主體分為三層以後,NODE專注場景,OBJ專注玩家物件,GATE專注網路。這樣的模型在無縫場景伺服器中得到廣泛的應用。但是隨著時間的推移,負載問題也越來越明顯,做個活動,遠來不活躍的區域變得十分活躍,靠每週維護來調整還是比較笨重的,於是有了動態負載均衡。

動態負載均衡有兩種方法,第一種是按照負載,由 Node Master 定時動態移動修改一下各個 Node的邊界,而不同的玩家物件按照先前的方法從一臺 Node上遷移到另外一臺 Node上:

圖11 動態負載均衡

這樣 Node Master定時查詢地圖上的熱點區域,計算新的場景切割方式,然後告訴其他伺服器開始調整,具體處理方式還是和上面物件跨越邊界移動的方法一樣。

但是上面這種方式實現相對複雜一些,於是人們設計出了更為簡單直接的一種新方法:

圖12 基於網格的動態負載均衡

還是將地圖按照標準尺寸均勻切割成靜態的網格,每個格子由一個具體的Node負責,但是根據負載情況,能夠實時的遷移到其他 Node上。在遷移分為三個階段:準備,切換,完成。三個狀態由Node Master負責維護。準備階段新的 Node開始同步老 Node上面該網格的資料,完成後告訴NM;NM確認OK後同時通知新舊 Node完成切換。完成切換後,如果 Obj伺服器還在和老的 Node進行通訊,老的 Node將會對它進行糾正,得到糾正的 OBJ將修正自己的狀態,和新的 Node進行通訊。

很多無縫動態負載均衡的服務端宣稱自己支援無限的人數,但不意味著 MMORPG遊戲的人數上限真的可以無限擴充,因為這樣的體系會受制於網路頻寬和客戶端效能。頻寬決定了同一個區域最大廣播上限,而客戶端效能決定了同一個螢幕到底可以繪製多少個角色。

從無縫地圖引入了分散式物件模型開始,已經完全脫離 MUDOS體系,成為一種新的服務端模型。又由於動態負載均衡的引入,讓無縫伺服器如虎添翼,容納著超過上一代遊戲伺服器數倍的人數上限,並提供了更好的遊戲體驗,我們稱其為第三代遊戲服務端架構。網遊以大型多人角色扮演為開端,RPG網遊在相當長的時間裡一度佔據90%以上,使得基於 MMORPG的服務端架構得到了蓬勃的發展,然而隨著玩家對RPG的疲憊,各種非MMORPG 遊戲如雨後春筍般的出現在人們眼前,受到市場的歡迎。

 

型別5:戰網遊戲伺服器

經典戰網服務端和 RPG遊戲有兩個區別:RPG是分割槽分服的,北京區的使用者和廣州區的使用者老死不相往來。而戰網,雖然每局遊戲一般都是 8人以內,但全國只有一套伺服器,所有的玩家都可以在一起遊戲,而玩家和玩家之使用 P2P的方式連線在一起,組成一局遊戲:

玩家通過 Match Making 伺服器使用:建立、加入、自動匹配、邀請 等方式組成一局遊戲。伺服器會選擇一個人做 Host,其他人 P2P連線到做主的玩家上來。STUN是幫助玩家之間建立 P2P的牽引伺服器,而由於 P2P聯通情況大概只有 75%,實在聯不通的玩家會通過 Forward進行轉發。

大量的連線對戰,體育競技遊戲採用類似的結構。P2P有網狀模型(所有玩家互相連線),和星狀模型(所有玩家連線一個主玩家)。複雜的遊戲狀態在網狀模型下難以形成一致,因此星狀P2P模型經受住了歷史的考驗。除去遊戲資料,支援語音的戰網系統也會將所有人的語音資料傳送到做主的那個玩家機器上,通過混音去重再編碼的方式返回給所有使用者。

戰網類遊戲,以競技、體育、動作等型別的遊戲為主,較慢節奏的 RPG(包括ARPG)有本質上的區別,而激烈的遊戲過程必然帶來到較 RPG複雜的多的同步策略,這樣的同步機制往往帶來的是很多遊戲結果由客戶端直接計算得出,那在到處都是破解的今天,如何保證遊戲結果的公正呢?

主要方法就是投票法,所有客戶端都會獨立計算,然後傳遞給伺服器。如果結果相同就更新記錄,如果結果不一致,會採取類似投票的方式確定最終結果。同時記錄本劇遊戲的所有輸入,在可能的情況下,找另外閒散的遊戲客戶端驗算整局遊戲是否為該結果。並且記錄經常有作弊嫌疑的使用者,供運營人員封號時參考。

 

型別6:休閒遊戲伺服器

休閒遊戲同戰網伺服器類似,都是全區架構,不同的是有房間伺服器,還有具體的遊戲伺服器,遊戲主體不再以玩家 P2P進行,而是連線到專門的遊戲伺服器處理:

和戰網一樣的全區架構,使用者資料不能象分割槽的 RPG那樣一次性load到記憶體,然後在記憶體裡面直接修改。全區架構下,為了應對一個使用者同時玩幾個遊戲,使用者資料需要區分基本資料和不同的遊戲資料,而遊戲資料又需要區分積分資料、和文件資料。勝平負之類的積分可以直接提交增量修改,而更為普遍的文件類資料則需要提供讀寫令牌,寫令牌只有一塊,讀令牌有很多塊。同帳號同一個遊戲同時在兩臺電腦上玩時,最先開始的那個遊戲獲得寫令牌,可以操作任意的使用者資料。而後開始的那個遊戲除了可以提交勝平負積分的增量改變外,對使用者資料採用只讀的方式,保證遊戲能執行下去,但是會提示使用者,遊戲資料鎖定。

 

型別7:現代動作網遊

從早期的韓國動作遊戲開始,傳統的戰網動作類遊戲和 RPG遊戲開始嘗試融合。單純的動作遊戲玩家容易疲倦,留存也沒有 RPG那麼高;而單純 RPG戰鬥卻又慢節奏的乏味,無法滿足很多玩家激烈對抗的期望,於是二者開始融合成為新一代的:動作 + 城鎮 模式。玩家在城鎮中聚集,然後以開副本的方式幾個人出去以動作遊戲的玩法來完成各種 RPG任務。本質就是一套 RPG服務端+副本服務端。由於每次副本時人物可以控制在8人以內,因此可以獲得更為實時的遊戲體驗,讓玩家玩的更加爽快。

說了那麼多的遊戲伺服器型別,其實也差不多了,剩下的型別大家拼湊一下其實也就是這個樣子而已。遊戲服務端經歷了那麼多結構上的變遷,內部開發模式是否依然不變?究竟是繼續延續傳統的開發方式?還是有了更多突破性的方法?經歷那麼多次架構變遷,後面是否有共通的邏輯?未來的發展還會存在哪些困難?遊戲服務端開發如何達到最終的彼岸?請看下節:技術的演進。

// 伯樂線上小提示:下篇還沒出,敬請期待

相關文章