五邑隱俠,本名關健昌,10年游戲生涯,現隱居海邊,
本教程以Go語言磁區游戲服務端框架搭建為例,
Go語言是Google開發的一種靜態強型別、編譯型、并發型、具有垃圾回收功能的編程語言,語法上近似C語言,支持介面、可通過struct包含另一個struct方式實作繼承等面向物件的概念,性能上媲美C/C++,相比C/C++更健壯,更易開發并發程式,我以前也寫C++服務端,接觸Go后,更傾向用Go做游戲服務端開發,
磁區游戲,指游戲將分為很多個區,不同區之間玩家不能互動或只有少量互動,玩家需要選擇磁區進入指定磁區開始游戲,一個玩家可以同時在不同磁區有角色,目前市面上大多中重度網路游戲都采用這種模式,磁區游戲適合不需要大DAU互動的游戲,如卡牌、MMORPG、SLG等,從技術層面,磁區屬于集群擴容的一種手段;運營上,有利于磁區精細運營,滾服運營已經是比較成熟的游戲運營手段,磁區的基礎上,可以按相鄰磁區編號設定組服務,例如10個磁區一組設定組服務,用于跨磁區的玩法,相對磁區游戲,也存在不磁區的社交游戲,這類游戲核心玩法是匹配對抗競技,例如COC,簡單的匹配競技游戲可以把磁區游戲的磁區改為節點服務組,把組服務拆分成組匹配服務和多個競技服務,匹配服務只做簡單的報名和匹配,匹配成功后把玩家分配到指定的競技服務,并在里面分配房間開始游戲,
搭建磁區游戲服務端框架,首先建立一個服務注冊發現機制,我們以中心服作為機制的核心,提供服務注冊,以及服務資訊廣播,作為游戲主體,磁區是注冊的物件,磁區啟動成功后,連接中心服,并注冊磁區,這樣中心服知道所有磁區的基本資訊和狀態,由于所有磁區都連接中心服,中心服還有轉發、廣播的功能,磁區注冊后,有哪些服務需要發現磁區、關注磁區的狀態變化?對于玩家,登錄后要知道有哪些磁區以及狀態情況,所以登錄服需要發現磁區,玩家通過登錄回傳知道磁區情況,選擇磁區進入游戲,而玩家是通過網關連接磁區的,所以網關需要發現磁區,磁區注冊后,需要切換狀態來支持開服測驗、開服、維護,一般會搭建一個管理服,運營人員可以通過管理服發指令給磁區更改狀態,所以管理服也需要發現磁區,這樣得到第一個框架模型如下:

按照這個模型,先啟動中心服等待其他服務注冊,然后分別啟動管理服、登錄服、網關,這些服務注冊到中心服,新開一個磁區就啟動該磁區服務,磁區狀態為未開服,磁區啟動成功后注冊到中心服,中心服通知管理服該磁區啟動成功,狀態為未開服,管理服通過中心服轉發指令給該磁區,更改狀態為開服測驗,該磁區把狀態更改發給中心服通知狀態變更,中心服通知管理服、登錄服、網關該磁區狀態變化,網關連接該磁區的服務,這時候測驗賬號可以登錄進入該磁區開始測驗,測驗通過后同理管理服可以發指令更改該磁區狀態為正常正式開服,當磁區需要維護時,管理服發指令給該磁區更改狀態為維護,網關收到中心服廣播后,斷開與該磁區服務的連接,5分鐘后該磁區的服務可以關閉進入維護,這樣一個整體流程算是跑通了,
接下來看看磁區的服務怎樣劃分,先看一個簡單的情況,磁區有一個主服務,負責注冊到中心服、處理玩家的基本請求,包括磁區登錄、玩家基本資訊操作、養成等業務,這些業務都需要頻繁修改玩家資料,應避免直接操作資料庫,因此使用redis做快取,主服務直接操作redis上的資料,redis資料要有一個落地的機制避免redis崩潰或資料過期后資料丟失,這里選用mysql做固化資料庫,玩家的游戲資料會從redis固化到mysql,對于redis上資料已過期的玩家再次登錄,還需要把資料從mysql加載到redis,所以這里增加一個資料服,負責資料的預熱和落地,一個基本的流程,玩家進入磁區,主服務處理請求,從redis獲取玩家資料,redis上不存在該玩家資料,主服務通過redis發布訊息給資料服預熱該玩家資料,資料服查詢mysql,如果mysql沒有該玩家資料,資料服往mysql新加一條玩家資料注冊個新玩家,資料服把玩家mysql的資料添加到redis,資料服發布訊息通知主服務該玩家資料已準備好,主服務繼續從redis獲取該玩家資料,回傳給客戶端,這樣磁區的基本流程也能跑通,
除了基本流程,磁區可能需要廣播訊息,例如世界聊天、系統公告,在磁區搭建一個廣播服,在redis里維護一個廣播佇列,主服務往廣播佇列里添加廣播訊息,廣播服從廣播佇列里拿訊息進行廣播,對于MMORPG,還需要有場景服管理各個游戲地圖,回合制的卡牌、MMORPG游戲需要有單獨戰斗服進行戰斗的預演,如果有跨服玩法,還需要有組服務,相鄰幾個磁區共用一個組服務,這樣得到的磁區服務模型如下:

這樣一個基本的游戲服務端框架輪廓就出來了,接下來需要封裝一些公共基礎功能,以便快速搭建各個服務
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/276585.html
標籤:其他
