1. 程式人生 > >MMO遊戲伺服器從零開發(架構篇)

MMO遊戲伺服器從零開發(架構篇)

MMO遊戲伺服器屬於大型多人線上遊戲伺服器,負載,穩定,效率(包括反饋延遲和開發效率)是這種伺服器基本要求。

本人從10年入行至今一直從事MMO遊戲的研發和架構設計工作,對此類伺服器有一些理解和見解。下面分享給想了解遊戲伺服器開發的朋友們。這些是本人這些年來對MMO伺服器架構設計的總結的分享。本人會從頭開發一套完整的MMO伺服器架構程式。並在架構的基礎上實現基本的遊戲Demo功能。雖然只是架構,但是完全可以支援線上專案的研發。本人是實戰中成長起來的,不會花哨的語言修飾。都是真槍實彈的code。

開發語言選擇:

本人蔘與C++伺服器架構開發5年,後轉Java,發現Java更加適合遊戲伺服器的研發。優點如下:

1、相對簡單,遠比c++要容易些,這個應該不用爭辯吧。並且Java的人員招聘也比C++要容易些。

2、伺服器穩定,C++伺服器動不動出現指標等問題就可能導致伺服器宕機,但Java有的異常處理機制可以處理幾乎所以因為簡單異常導致的問題,出現引用問題,也只是丟擲一個異常列印即可。

3、開發編譯效率。Java的庫比較完善(C++庫也很完善),但去網上查詢多少開源的java庫和多少開源的c++庫,對比就知道了。相同的功能,用Java去寫邏輯比C++寫邏輯程式碼要少,這是我的感受。c++寫類需要H檔案和CPP檔案,並且需要先定義後實現,這就要多寫一個函式定義。編譯,C++專案的連結機制很耗時,一個完善的大型遊戲伺服器專案重新編譯一次,動不動就是10分鐘半個小時以上,有人會不會說不用聯編啊,我上個專案在使用聯編的條件下需要10分鐘以上,不用聯編時間就不用提了,每個半個小時肯定編譯不完。但Java就快的多了,Java是生成的位元組碼,並且沒有連結的過程。比如修改一個函式,Java新增完成,可以直接啟動測試,但是C++就可能會因為一行程式碼的修改,導致無數Cpp檔案的編譯。這個過程十分耗時。這是我比較推薦使用Java開發的主要原因。

因為專案開發的大部分時間還是邏輯功能的開發。如果因為編譯過程消耗大量時間,後期的開發維護成本大大減低。

4、效率對比,有人可能說C++比Java執行效率高,這個我不爭辯。網上爭辯的太多,現在的機器效能已經足夠高,不夠就堆積硬體,硬體成本遠低於軟體成本。也不是說Java確實效率不行,實際上Java和C++效率對比已經可以忽略。比如相同程式,C++跑1000萬次耗時1秒,Java耗時0.9秒。雖然慢,但是1000萬次的數量級,完全沒有必要非得爭取那0.1秒。但也是分領域。比如遊戲內部尋路演算法NavMesh,這種純運算的邏輯還是用C++,確實效率高。通過Java的Jni方式與本地C++Dll實現互動,Java呼叫C++方法。

5、跨平臺問題。就說Window和Linux,C++編寫的程式碼在不同的平臺要有兩份實現。就僅僅網路部分window的Iocp,linux的Epoll就是兩種實現。其他的函式庫,兩個平臺也有不同,都要進行處理。對於Java,就一個虛擬機器,在window還是在linux都是執行在虛擬機器之下,只要有Java虛擬機器,管你是什麼系統。

模組介紹:

雖然只是伺服器架構,但是麻雀雖小,五臟俱全。先整體介紹一下MMO伺服器需要的基礎組成部分,讓大家有一個整體的認識。

基礎元件:

1、網路元件:包括內網通訊模組和外網通訊模組。還有協議部分。

2、資料庫元件:負責玩家資料和全域性資料的持久化。

3、日誌元件:包括異常日誌(程式碼異常列印日誌)和行為日誌(為運營平臺提供的行為日誌)。

4、配置讀取元件:程式啟動配置(程式啟動相關配置如ip,port,連線關係等這個很簡單,使用ini配置即可)和遊戲相關配置(遊戲邏輯相關配置使用量巨大,採用json格式資料)。

遊戲邏輯模組:

以上元件都是為了這部分的做支撐。這個部分也是程式碼量最大,使用量最大的部分。這部分還可以細分出很多模組。具體模組後續詳細說明。遊戲邏輯模組主要分成兩部分執行緒組:系統服務執行緒組和場景邏輯執行緒組。不同的系統伺服器掛載不同的服務執行緒上,不同的場景掛載不同的場景執行緒上。

系統服務包括哪些:比如登陸系統服務,好友系統服務,幫派系統服務,等。可以將一個或者多伺服器掛載一個執行緒,也可以分別掛載不同執行緒。根據預測的邏輯運算量進行分配,同步配置檔案可以實現配置掛載。

場景邏輯:玩家的所有操作基本都屬於場景邏輯執行緒組的。玩家的行走,戰鬥,道具獲得,使用。系統服務執行緒組提供的系統服務基本都是通過RPC呼叫的方式為場景邏輯組執行緒提供服務。比如新增好友,場景邏輯執行緒上的玩家收到新增好友訊息,然後通過Rpc的方式呼叫系統伺服器執行緒組的好友服務實現新增好友功能。但登陸服務做了特殊處理,登陸訊息會直接分發到登陸服務,登陸服務進行驗證,驗證通過後會在場景服務執行緒組建立對應的角色通訊物件實現與客戶端的通訊處理。

程序劃分:

之前做C++的時候,一般都把程序都可以劃分為登陸程序,閘道器程序,遊戲邏輯程序,資料庫程序,日誌程序,平臺程序。但轉Java後,發現啟動多程序反而啟動麻煩。由於伺服器架構整體都是多執行緒架構,就沒有做細緻的程序劃分,我們的伺服器可以全部都開在一個程序上,也可以分開啟動。我們最近上的專案就是所有功能都在一個程序啟動,開服第一天開了10幾組伺服器,由於導量的不均勻,導致首服人數特別火爆,最初設定的最高線上人數初始都是3000人,最後將首服調整為5500人。因為硬體都是試用雲伺服器,足夠的大記憶體,cpu,完全沒有必要分開程序啟動,多程序反而會消耗更大的記憶體和cpu,單程序多執行緒更優。運維啟動也更方便。

PS:本文是從整體到部分的實現步驟,所以難免有部分細節介紹可能存在一些疏忽或者問題。希望大家可以及時反饋,本人之後也會再發現問題修改本文的部分內容。