弱交互移動遊戲服務器端框架設計

  很早前即有想法設計一套穩定、高效、安全的弱交互移動網絡遊戲服務器端基礎框架,前些天初步完成簡單的初稿文檔。第一版設計參考了印象裏之前的一些工做經歷經驗。這些經歷經驗雖已日漸模糊,但從它們這裏,本身獲益良多。算法

  初稿文檔暫只是簡單記錄了目前想到,或以爲比較重要的內容(或許會更新),具體細節等涉及較少。可能我會在業餘時間裏一點點實現本文所述框架,只是開發計劃暫沒法預期,畢竟精力頗有限。數據庫

  

  一、功能描述編程

    1.1) 弱交互移動休閒類遊戲服務器端基礎框架(以房間爲遊戲單位,諸如棋牌類遊戲)後端

    1.2) 相較傳統的 MMORPG 服務器框架,簡化結構安全

 

  二、框架構成服務器

    2.1) LoginGate(登陸網關)網絡

      運行在公網環境,用於轉發客戶端與 LoginServer 間的登陸交互等。LoginGate 若是被攻擊,可新開其它地址(如在別的機房)的 LoginGate。固然也可部署多個 LoginGate。架構

    2.2) LoginServer(登陸服務器)負載均衡

      運行在內網環境,只接受合法的 LoginGate 鏈接,自身也鏈接至 DBServer,用於客戶端登陸驗證及登陸狀態管理等。框架

    2.3) GameGate(遊戲網關)

      運行在公網環境,主要用於轉發客戶端與 GameServer 之間的通信封包,同時也能處理諸如外掛、惡意鏈接等(如新連上來的客戶端若 15 秒還不發數據,或如有客戶端以非正常速度發數據則直接踢掉甚至加入黑名單)。

      一般會有多個 GameGate 進程部署在相同或不一樣的物理機上,甚至可部署在不一樣的機房。

    2.4) GameServer(遊戲服務器)

      運行在內網環境,遊戲邏輯核心服務器,只接受合法的 GameGate 鏈接,自身也鏈接至 DBServer,且會經過 UDP 協議發送日誌信息給 LogServer 保存。

    2.5) DBServer(數據服務器)

      運行在內網環境,主要負責遊戲數據存取、登陸驗證(可選)等邏輯,只接受 LoginServer 與 GameServer 的鏈接。

    2.6) LogServer(日誌服務器)

      運行在內網環境,用於保存 GameServer(甚至 DBServer、LoginServer 等)經過 UDP 發過來的日誌信息。

    各服務器間鏈接圖以下。

    

    GameServer、DBServer、LoginServer 及 LogServer 可放在同一局域網甚至同一臺物理機上(若是負載不大的話)。經過模塊功能劃分框架構成,各模塊職責明確,代碼結構清晰,對於網絡攻擊防範及減輕譬如 GameServer 的壓力等大有裨益。

 

  三、客戶端進入遊戲流程

    3.1) 客戶端啓動時,向某指定的(固定不變的)地址(域名)發起一個 HTTP 請求,獲取 LoginGate 地址(IP&Port)

    3.2) 客戶端鏈接至 LoginGate,以後輸入帳號密碼並提交

    3.3) LoginGate 轉發帳號密碼等信息給 LoginServer,由 LoginServer 驗證(與 DBServer 交互)

    3.4) 若驗證經過,DBServer 準備玩家數據,LoginServer 經過(分佈式)負載均衡算法返回某 GameGate 地址,而後 LoginGate 斷開和客戶端的鏈接

    3.5) 客戶端斷開與 LoginGate 的鏈接,並鏈接至 GameGate

    3.6) 客戶端經過 GameGate 與 GameServer 創建起鏈接並進入&開始遊戲

 

  四、技術實現

    4.1) 開發技術

      4.1.1) Golang

        遊戲後臺開發(至少核心及基礎框架),用編譯型(原生)語言來編寫應是比較合理的作法(譬如強類型語法在編譯期能提早排除不少可能要到線上運行時才能發現的問題)。動態語言固然也能,但明顯這並不是它們所長(如代碼組織、代碼可讀性、調試便利度、部署複雜度以及安全和效率等方面)。

                      Java 等語言技術固然也能,並且可用的資源不少,人才也很是之多,但它帶 VM,部署麻煩,框架厚重,相對而言並不算理想的選擇。

                      C++ 太複雜(即使只用其很小的一部分子集),對人員的技術要求較高(寫出穩健的 C++ 程序並不容易),編譯太慢,對於中小技術團隊來講並不是好的選擇。

                      而 Delphi,單從其品質中下、人才難尋等方面考慮,更非合適選擇。

                      至於以替代 C++ 爲目標的 Rust,綜合其語言複雜度(彷佛至今語法還未成型)及開發支持團隊、社區、使用案例等,至少短時間內,可能觀望一下比較合適。

                      原生、語法簡單且以實用爲導向、標準及三方庫強大(譬如網絡等方面)、編譯迅速、編譯器優化主流水平(GC 改進已很大且一直在持續改進)、跨平臺,說 Golang 是天生的後端開發利器並不爲過。

                      而早已有很多 Web後臺、遊戲後端、KV數據庫等(成功)使用案例。

                      一般狀況下,Golang 能比較快上手,熟悉其它語言技術的開發人員轉到 Golang 基本會很快。

      4.1.2) Lua(可選)

        不止在遊戲界,業務邏輯採用腳本語言(較經常使用的是 Lua、Python 等)來開發很是常見,這種方式的好處在於:

                      4.1.2.1) 靈活,業務邏輯變更可能較頻繁,而腳本代碼修改執行很方便

                      4.1.2.2) 劃分核心層和業務層,普通開發人員接觸不到核心的代碼,只能拿到腳本接口文檔用腳本寫業務邏輯

                      4.1.2.3) 腳本代碼出錯了,最多影響局部邏輯(可上報腳本錯誤以方便後續解決問題),用腳本作一個安全的調用層能夠避免整個進程崩潰

                      4.1.2.4) 熱更新

                      綜上,採用 Golang + Lua 相結合的方式,或許不失爲可嘗試的開發模式。

      4.1.3) Protobuf(可選)

        高性能的網絡傳輸協議格式,序列化及反序列化速度甚至遠勝 JSON、XML 等,其簡單、精簡(數據描述文件很是小),不依賴於平臺,支持多種編程語言。但其實,自實現緊湊高效的封包格式也並不難。

      4.1.4) 加解密

        PC 網遊通常採用 動態加解密模式(編寫數套加解密算法並編譯,而後摳出每套加解密函數的機器碼,每次客戶端上線時,隨機選取一套加解密算法發給客戶端,以後客戶端與服務器的通信封包皆經過此算法加解密),但移動遊戲估計不容易實現。

                      若是封包較小且不密集,可考慮採用不對稱加解密算法,增長封包破解難度。

                      否,應考慮 TEA、AES 等對稱加解密算法(如 QQ 的聊天信息本質上就是用 TEA 加密的)。

                      譬如可考慮隨機使用幾種加解密算法中的一種(每次客戶端上線時,服務器經過約定的 ID 告知應使用哪套加解密算法),增長靈活性及破解難度。

    4.2) 數據庫存儲

      4.2.1) MySQL Community x64

                 4.2.2) MongoDB(備選)

    4.3) 運行平臺

                 Linux 64bit(CentOS / Red Hat)

 

  五、後記

    以上思路,是以單個的遊戲爲設計立足點,較有侷限。

    譬如登陸,統一走登陸平臺的方式更通行及合理(此時可由 LoginGate 與 平臺進行交互驗證)。而日誌處理等,能有專門的處理後臺也不失是好的作法。

    只是如此會涉及不少方方面面的細節和作法,於初衷有悖,是以本文所述設計,僅供參考而已。但很明顯,基於以上設計,縱使需做擴展,改進起來也較簡單(畢竟,此服務器框架專爲弱交互移動遊戲而設計)。

 

  六、一些討論

    與某基友討論如斯設計,基友認爲無需三層結構(Client-->GameGate-->GameServer),而是讓客戶端直連 GameServer(GameServer 負責邏輯處理,能夠線性擴展),且加一箇中央服務器(CenterServer),作簡單的遊戲狀態記錄和邏輯處理,以及支配各 GameServer 等。這種設計固然很好,只是在考慮到諸如框架簡明及服務器安全等因素,短時間內估計無心以此思路來改動第一版設計。

相關文章
相關標籤/搜索