java 分散式遊戲伺服器框架,叢集遊戲伺服器框架,遊戲伺服器閘道器框架 ioGame 網路遊戲伺服器框架

2022-11-18 21:00:24

ioGame

國內首個基於螞蟻金服 SOFABolt 的 java 網路遊戲伺服器框架;無鎖非同步化、事件驅動的架構設計

通過 ioGame 可以很容易的搭建出一個叢集無中心節點、有狀態多程序的分步式遊戲伺服器

無中介軟體依賴、程式碼即檔案、JSR380、斷言 + 異常機制 = 更少的維護成本、開發成本

同樣的一套業務程式碼無需變更,可以同時支援多種協定:websocket、socket

輕量級、啟動快、更節約、更簡單、開箱即用、無組態檔、超高效能

近原生的快、業務框架平均每秒可以執行 1152 萬次業務邏輯

在業務開發中自帶神級特性:業務程式碼存取定位與跳轉

架構部署多樣性:即可相互獨立,又可相互融合

各個邏輯服之間可以相互的進行跨程序通訊

可同時與同型別多個遊戲邏輯服通訊

支援玩家動態繫結邏輯服節點

對webMVC開發者友好

無 spring 強依賴

 

 


最小依賴

ioGame 已經上傳到中央倉庫

https://search.maven.org/search?q=a:bolt-run-one

 

ioGame 是輕量級的網路遊戲伺服器框架,ioGame 沒有中介軟體的強依賴,即無需安裝任何其他的中介軟體產品;此時,你只需一個依賴即可獲得整個框架,並同時支援開頭介紹的全部功能特性。

<dependency>
    <groupId>com.iohao.game</groupId>
    <artifactId>bolt-run-one</artifactId>
    <version>${ioGame.version}</version>
</dependency>

 

將變數 ${ioGame.version} 替換成最新版本就可以了。


 

 

願景

讓網路遊戲伺服器的程式設計變得輕鬆簡單!

 

網路遊戲框架簡介

ioGame 是一個由 java 語言編寫的網路遊戲伺服器框架。支援 websocket、tcp ,適用於全球同服、回合制遊戲、策略遊戲、即時戰鬥等遊戲伺服器的開發。具有高效能、穩定、易用易擴充套件、超好程式設計體驗等特點。可做為 H5、手遊、端遊的 java 遊戲伺服器。

 

ioGame 是輕量級的網路遊戲伺服器框架,在使用 ioGame 時,只需一個依賴即可獲得整個框架,而無需在安裝其他服務,如: Nginx、Redis、MQ、Mysql、ZooKeeper、Protobuf協定編譯工具 ... ...等。簡單點說,就是無需安裝其他產品,就能支援開頭介紹的內容特性;這意味著在使用上簡單了,在部署上也為企業節約了成本。

 

通過 ioGame 你可以很容易的搭建出一個穩定、高效能、叢集無中心節點、分步式、自帶負載均衡、跨程序通訊、避免類爆炸設計的網路遊戲伺服器。遊戲框架藉助於螞蟻金服 sofa-bolt 通訊框架來提供通訊方面的穩定與高效能

 

在 ioGame 中能讓你遺忘 Netty,你幾乎沒有機會能直接的接觸到 Netty 的複雜,但卻能享受 Netty 帶來的高效能。對開發者要求極低,為開發者節約開發時間。

 

即使之前沒有遊戲程式設計的經驗,也能參與到遊戲程式設計中。如果你之前具備一些遊戲開發或者 webMVC 相關的知識,則會更容易上手遊戲服務的開發。

 

開發者基於 ioGame 編寫的專案、模組通常是條理清晰的,得益於框架對路由的合理設計。當我們整理好這些模組後,對於其他開發者接管專案或後續的維護中,會是一個不錯的幫助(模組的整理與建議)。

 

基於 ioGame 編寫的專案,通常是語法簡潔的、高效能的、低延遲的。框架最低要求使用 JDK17,這樣即可以讓專案享受到 ZGC 帶來的改進,還能享受語法上的簡潔。從 JDK17 開始 GC 已經處理得越來越好了,JDK17 中的 ZGC 遠低於其亞毫秒級暫停時間的目標;當開發者使用 JDK17 時,相當於在你們的專案中變相的引入了一位 JVM 調優大師,詳細請看 JDK17 垃圾回收GC效能飛躍提升

 

在部署上,支援多服單程序的方式部署(類似單體應用、在分步式開發時,偵錯更加方便)、也支援多服多程序多機器的方式部署。在部署方式上可以隨意切換,而不需要更改程式碼;日常中按照單體思維開發,在生產上可以使用多程序的方式部署;當然,也可以使用單程序的方式部署。

 

ioGame 框架職責清晰、業務開發幾乎零學習成本、原始碼有高質量註釋、範例多、使用檔案多,開發體驗最佳、業務程式碼自動生成與遊戲前端對接的檔案、邏輯服之間可跨程序跨機器通訊、業務程式碼定位--神級特性、異常機制。提供了豐富的線上高質量使用檔案,為你的團隊助力,帶上你們的小夥伴一起,這樣就不用手把手的教了。

 

ioGame 可以很方便的與 spring 整合(5 行程式碼)。

 

綜上,ioGame 遮蔽了很多複雜且重複性的工作;超棒的開發體驗,使用簡單,無中介軟體依賴,只需一個依賴即可獲得整個框架;減少了學習成本、減少了使用成本、減少了開發者的工作量、減少了專案的運維成本。並可為專案中的功能模組結構、開發流程等進行清晰的組織定義,減少了後續的專案維護成本。從而讓開發團隊更方便快捷高效的開發遊戲專案。


 

架構簡圖

 

 

通過 ioGame 你可以很容易的搭建出一個叢集、分步式的網路遊戲伺服器!

 

無鎖非同步化與事件驅動的架構設計、叢集無中心節點、自帶負載均衡、分散式支援、可動態增減機器、避免類爆炸的設計;

 

圖中的每個遊戲對外服、每個遊戲邏輯服、每個 broker (遊戲閘道器)都可以在單獨的程序中部署,邏輯服之間可以跨程序通訊(遊戲對外服也是邏輯服的一種)。

 

遊戲閘道器叢集

broker (遊戲閘道器)可以叢集的方式部署,叢集無中心節點、自帶負載均衡。ioGame 本身就包含服務註冊,你不需要外接一個服務註冊中心,如 Eureka,ZooKeeper 等(變相的節約伺服器成本)。

 

通過 broker (遊戲閘道器) 的介入,之前非常複雜的負載均衡設計,如服務註冊、健康度檢查(後續版本提供)、到伺服器端的連線維護等這些問題,在 ioGame 中都不需要了,結構也簡單了很多。實際上單臺 broker (遊戲閘道器) 效能已經能夠滿足了,因為遊戲閘道器只做了轉發。

 

邏輯服

邏輯服通常說的是遊戲對外服和遊戲邏輯服。邏輯服可以有很多個,邏輯服擴充套件數量的理論上限是 netty 的連線上限。

 

遊戲對外服

對外服保持與使用者(玩家)的長連線。先來個假設,假如我們的一臺硬體支援我們建立使用者連線的上限是 5000 人,當用戶量達到 7000 人時,我們可以多加一個對外伺服器來進行分流減壓。由於遊戲對外服擴充套件的簡單性,意味著支援同時線上玩家可以輕鬆的達到百萬、千萬甚至更多。

 

即使我們啟動了多個遊戲對外服,開發者也不需要關心這些玩家連線到了哪個遊戲對外服的問題,這些玩家總是能接收到廣播(推播)訊息的,因為框架已經把這些事情給做了;在玩家的角度我們只有「一個」伺服器,同樣的,在開發者的角度我們只有「一個」遊戲對外服;

 

在結構組合上(部署多樣性)

在部署上,支援多服單程序的方式部署(類似單體應用、在分步式開發時,偵錯更加方便)、也支援多服多程序多機器的方式部署。

 

架構由三部分組成:1.遊戲對外服、2.Broker(遊戲閘道器)、3.遊戲邏輯服;三者既是相互獨立的,又是可以相互融合的(相互獨立、相互融合;話雖簡單,實際實現卻不簡單)。如:

  • 遊戲對外服、Broker(遊戲閘道器)、遊戲邏輯服這三部分,在一個程序中;【單體應用;在開發分步式時,偵錯更加方便
  • 遊戲對外服、Broker(遊戲閘道器)、遊戲邏輯服這三部分,在多個程序中;【分散式】
  • 遊戲對外服、Broker(遊戲閘道器)這兩部分在一個程序中;而遊戲邏輯服在多個程序中;【類似之前遊戲的傳統架構】
  • 甚至可以不需要遊戲對外服,只使用Broker(遊戲閘道器)和遊戲邏輯服這兩部分,用於其他系統業務;

 

因為 ioGame 遵循物件導向的設計原則(單一職責原則、開閉原則、裡式替換原則、依賴倒置原則、介面隔離原則、迪米特法則)等,所以使得架構的職責分明,可以靈活的進行組合;

 

遊戲對外服是架構的三部分之一,預設的遊戲對外服是基於 netty 實現的。如果有需要,將來我們還可以使用基於 minasmart-socket 等通訊框架編寫,額外提供一個遊戲對外服的實現;即使是使用 minasmart-socket 提供的遊戲對外服,也並不會影響現有的遊戲邏輯服業務邏輯,因為遊戲對外服滿足單一職責原則,只維護使用者(玩家)長連線相關的。

 

開發人員幾乎都遇見過這麼一種情況;在專案初期階段,通常是以單體專案的方式進行開發,隨著需求不斷的增加與迭代,會演變成一個臃腫的專案;此時在對一個整體進行拆分是困難的,成本是極高的。甚至是不可完成的,最後導致完全的重新重構;

 

ioGame 提供了在結構組合上的部署多樣性,通過組合的方式,在專案初期就可以避免這些拆分問題。在開發階段中,我們可以使用單體應用開發思維,降低了開發成本。通過單體應用的開發方式,在開發分步式專案時,偵錯更加的方便;這既能兼顧分步式開發、專案模組的拆分,又能降低團隊的開發成本;

 

 

架構優點

架構有很高程度的抽象,讓設計者更加關注於業務,而無需考慮底層的實現、通訊引數等問題。

 

邏輯服的位置透明性;同時,由於模組化、抽象化,使得整個架構各伺服器之間耦合度很低,邏輯服註冊即可用,大大增加了可伸縮性、可維護性,動態擴充套件變得簡單而高效。由於邏輯服是註冊到 Broker(遊戲閘道器) 上的,所以邏輯服可以動態的增加、刪除、改變;由於邏輯服之間耦合度較小,偵錯和測試的工作也是可控的;

 

架構比較清晰的就是,遊戲對外服負責維護使用者端的接入(使用者、玩家的連線),遊戲邏輯服專心負責業務邏輯,他們之間的排程由 Broker(遊戲閘道器)來負責;因為架構拆分的合理,所以特別方便用 k8s 來自由伸縮部署這三種服,哪個服水位高就擴容哪個,水位過去了又可以縮容。

 


ioGame 支援的通訊方式

 

ioGame 支援 3 種型別的通訊方式,分別是單次請求處理、推播、邏輯服間的相互通訊;下面分別對這 3 種型別的通訊方式相關的應用場景舉幾個例子。

 

框架對這 3 種型別的通訊方式提供了程式碼呼叫點的紀錄檔,簡單點說就是框架可以讓開發者知道,是在哪一行程式碼中觸發的業務邏輯。

 

我們可以想象一下,假如框架沒有提供程式碼呼叫點的紀錄檔會是什麼樣的;比如,遊戲前端傳送一個業務請求到遊戲伺服器中,但是處理這個請求的業務方法,會觸發多個響應(通常是推播、廣播)給遊戲前端。一但時間久了,開發者是很難知道分別響應了哪些業務資料給遊戲前端,特別是一些二手專案;所以這將是一個災難性的問題,因為這會耗費大量的時間來尋找這些相關的業務程式碼。

 


 

快速入門

業務互動簡圖

 

抽象的說,遊戲前端與遊戲服務的的互動由上圖組成。遊戲前端與遊戲服務可以自由的雙向互動,互動的業務資料由 .proto 作為載體。協定檔案是對業務資料的描述載體,用於遊戲前端與遊戲服務的資料互動。

 

當遊戲前端和遊戲伺服器端建立了連線後,就可以開始相互傳遞業務資料,處理各自的業務了。好了,看完業務互動介紹後,開始編寫一個遊戲業務處理範例吧,接下來我們先定一個業務資料協定。

 

協定檔案

協定檔案是對業務資料的描述載體,用於遊戲前端與遊戲服務的資料互動。Protocol Buffers 是Google公司開發的一種資料描述語言,也簡稱 PB。當然協定檔案描述還可以是 json、xml或者任意自定義的,因為最後傳輸時會轉換為二進位制,但遊戲開發中 PB 是目前的最佳。

 

遊戲前端

遊戲前端的展現可以是 UnityUE(虛幻)Cocos或者其他的遊戲引擎。這些遊戲引擎只是展現遊戲畫面的一種形式,資料互動則由通訊來完成(TCP、UDP 等)。遊戲前端可以是 UnityUE(虛幻)Cocos或者其他的遊戲引擎。

 

快速入門程式碼範例

這裡主要介紹遊戲服務器相關的,下面這個範例介紹了服務程式設計可以變得如此簡單。

 

協定檔案定義

首先我們自定義一個協定檔案,這個協定檔案作為我們的業務載體描述。這個協定是純java程式碼編寫的,使用的是 jprotobuf,jprotobuf 是對 google protobuf 的簡化使用,效能同等。

 

可以把這理解成DTO、POJO、業務資料載體等,其主要目的是用於業務資料的傳輸;

1 /** 請求 */
2 @ProtobufClass
3 @FieldDefaults(level = AccessLevel.PUBLIC)
4 public class HelloReq {
5     String name;
6 }

 

 

Action

遊戲服務的程式設計,遊戲服務接收業務資料後,對業務資料進行處理;

1 @ActionController(1)
2 public class DemoAction {
3     @ActionMethod(0)
4     public HelloReq here(HelloReq helloReq) {
5         HelloReq newHelloReq = new HelloReq();
6         newHelloReq.name = helloReq.name + ", I'm here ";
7         return newHelloReq;
8     }
9 }

 

一個方法在業務框架中表示一個 Action(即一個業務動作)。

 

方法聲名的引數是用於接收前端傳入的業務資料,在方法 return 時,資料就可以被遊戲前端接收到。程式設計師可以不需要關心業務框架的內部細節。

 

從上面的範例可以看出,這和普通的 java 類並無區別,同時這種設計方式避免了類爆炸。如果只負責編寫遊戲業務,那麼對於業務框架的學習可以到此為止了。

 

遊戲程式設計就是如此簡單

 

問:我可以開始遊戲服務的程式設計了嗎?

是的,你已經可以開始遊戲服務的程式設計了。

 

存取範例(控制檯)

當我們存取 here 方法時(通常由遊戲前端來請求),控制檯將會列印

 

┏━━━━━ Debug. [(DemoAction.java:4).here] ━━━ [cmd:1 - subCmd:0 - cmdMerge:65536]
┣ userId : 888
┣ 引數: helloReq : HelloReq(name=塔姆)
┣ 響應: HelloReq(name=塔姆, I'm here )
┣ 時間: 0 ms (業務方法總耗時)
┗━━━━━ Debug [DemoAction.java] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 

控制檯列印說明

Debug. [(DemoAction.java:4).here]:
表示執行業務的是 DemoAction 類下的 here 方法,4 表示業務方法所在的程式碼行數。
在工具中點選控制檯的 DemoAction.java:4 這條資訊,就可以跳轉到對應的程式碼中(快速導航到對應的程式碼),這是一個開發良好體驗的開始!

userId :  
當前發起請求的 使用者 id。

引數 :  
通常是遊戲前端傳入的值。

響應:
通常是業務方法返回的值 ,業務框架會把這個返回值推播到遊戲前端。

時間:
執行業務方法總耗時,我們可根據業務方法總耗時的時長來優化業務。

路由資訊:[cmd - subCmd]
路由是唯一的存取地址。

 

有了以上資訊,遊戲開發者可以很快的定位問題。如果沒有視覺化的資訊,開發中會浪費很多時間在前後端的溝通上。問題包括:

  • 是否傳參問題 (遊戲前端說傳了)
  • 是否響應問題(遊戲後端說返回了)
  • 業務執行時長問題 (遊戲前端說沒收到響應, 遊戲後端說早就響應了)

 

其中程式碼導航可以讓開發者快速的跳轉到業務類對應程式碼中,在多人合作的專案中,可以快速的知道業務經過了哪些方法的執行,使得我們可以快速的進行閱讀或修改;

 

適合人群?

  1. 長期從事 web 內部系統開發人員, 想了解遊戲的
  2. 剛從事遊戲開發的
  3. 未從事過遊戲開發,但卻對其感興趣的
  4. 對設計模式在實踐中的應用和 sofa-bolt 有興趣的學習者
  5. 可以接受新鮮事物的
  6. 想放棄祖傳程式碼的

推薦實際程式設計經驗一年以上的人員