SLG手遊Java服務器的設計與開發——架構分析

  • 文章版權歸騰訊GAD全部,禁止匿名轉載;禁止商業使用;禁止我的使用。

1、前言

從去年12月份開始,到如今,我全程參與了公司一款SLG手遊的研發,負責整個遊戲的服務端部分。這也是我第一次單獨負責一款網遊的服務端開發,整個研發過程,也讓個人各方面技術提高了很多。目前這款遊戲正在緊張的測試中,預計下週左右會在XY渠道進行一輪封測,以測試玩家對咱們的遊戲的反饋數據。前端

這款遊戲集合市面上大多數SLG的特色,包含了卡牌、裝備、科技、建築的等養成內容,同時也在戰鬥系統作了創新,經過卡牌搭配,裝備搭配,以及陣型搭配,再加上各方面的養成數據,能讓玩家在戰鬥中產生不一樣的效果。同時,他最大的特色也是最核心的部分,就是國戰,不過很遺憾的是,初版上線不會有國戰內容,由於在測試過程當中,咱們發現整個國戰的遊戲機制還存在不少漏洞,咱們將會持續優化,優化出一版完整的國戰內容,再呈現給玩家。sql

我經歷了整個開發過程,在遊戲服務器開發方面有了很多新的認識,我想經過寫文章的方式把這些設計思路、技術難點、以及踩過的坑,都分享給你們,因此咱們準備經過系列文章的方式一點一點把服務器的框架內容分享出來,本章首先從遊戲服務器的架構分析開始。數據庫

2、功能介紹

在開始設計整個遊戲服務器的架構以前,我首先須要對遊戲的功能有所掌握。上文已經簡單提到了部分核心功能,好比卡牌、裝備、陣型等,但實際上游戲的內容並不止這些。這款遊戲屬於SLG手遊,即策略類的遊戲,遊戲以三國爲題材,經過得到三國名將卡牌,搭配各類裝備,設置戰鬥陣型,達到在戰鬥中的不一樣表現效果,戰鬥模式相似於《小小軍團》的戰鬥,可是小小軍團主要以兵種爲核心,而咱們的戰鬥以武將爲核心,不一樣武將有不一樣的技能,不一樣的戰鬥屬性,合理搭配,才能發揮最大的效果。圍繞着這些遊戲核心,設計瞭如下不一樣的功能模塊。後端

1.帳號系統

做爲一款網遊,最基礎的,就是帳號系統,一款網遊必定會有帳號系統,這是保證玩家能從不一樣終端都能進入本身的遊戲數據的憑證。不過最近在手遊市場,通常狀況遊戲都不會有本身的帳號系統,而是接入第三方的帳號系統,好比騰訊遊戲通常會讓玩家選擇QQ登陸或微信登陸,網易通常會讓玩家選擇網易帳號登陸,還有不少渠道如XY,海馬玩,快用等,都有本身的帳號系統,帳號系統的功能,就是保證玩家的惟一標識。緩存

2.君主模塊

進入遊戲以後,玩家就須要建立一個君主,並設置君主的名字,性別,頭像和國家。SLG遊戲中,資源也是一個很重要的內容,全部的資源都是跟玩家直接相關的,因此資源內容也是跟君主相關,咱們就能夠把資源內容綁定在君主模塊中,玩家在遊戲中,是扮演這個君主的角色,全部遊戲中的資源消耗以及資源產出,都是跟君主息息相關。在競技場以及國戰等pvp玩法中,君主也是玩家在遊戲的惟一身份顯示。服務器

3.卡牌模塊

這款遊戲在SLG的基礎之上加上了卡牌養成玩法,玩家須要經過收集卡牌來進行遊戲的操做,卡牌包含了呂布、關羽、張飛、華雄等三國名將。卡牌分了白綠藍紫橙紅的品質分段,不一樣品質的卡牌有着不一樣的屬性數值。卡牌能夠經過酒館抽卡得到,抽卡分爲單次抽卡和十連抽,十連抽會必中一張橙色卡片。卡牌具備星級屬性,多張相同的卡牌還能夠進行升星操做,升星具備必定的失敗概率,品質越高,失敗率越高。若是有多餘的卡牌,還能夠進行分解操做,分解卡牌能夠得到將魂和銀兩,而將魂還能夠繼續用於抽卡。在戰鬥中,上陣的卡牌將會增加經驗,而卡牌的等級,就與它的經驗相關。總結起來,卡牌具備等級和星級兩個養成屬性,其它還有統勇智以及攻擊防護,技能傷害,普攻傷害等基礎屬性。整個卡牌模塊還有不少養成點的。微信

4.裝備模塊

有了戰鬥的卡牌,那就必須給卡牌配備裝備模塊了,全部的卡牌具備6個裝備位,每一個裝備位對應一種裝備,裝備也分爲了白綠藍紫橙紅的幾個品質階段,不一樣品質的卡牌也能給卡牌加上不一樣的屬性效果,卡牌一樣具備等級和星級兩個養成屬性以及其餘的基礎屬性,裝備能夠進行強化以強化等級,以及升星來提高裝備的星級,升星消耗任意的裝備做爲材料。卡牌模塊配合裝備模塊,能夠有更多的養成玩法的自由發揮空間。網絡

5.道具模塊

遊戲中也有常見的揹包,揹包中存放着各類道具,道具種類繁多,包括糧草、銀兩、經驗丹等資源道具,也能夠在揹包中查看擁有的卡牌和裝備。揹包中能夠直接使用道具,使用完道具就能增長相應的資源。數據結構

6.建築模塊

玩家剛進入遊戲會看到不少建築,這些建築都具備不一樣的功能,升級這些建築會加強建築的屬性效果,建築包括皇城、軍機處、校場、倉庫、招商局、兵營、酒館、競技場、鐵匠鋪、農田(6個)、民居(6個),各個建築具備不一樣的功能,皇城等級限制全部建築的最高等級,軍機處能夠解鎖升級科技,軍機處等級限制科技等級,倉庫等級限制最高資源上限,招商局等級限制民居產出,兵營等級限制兵力上限,鐵匠鋪等級限制裝備強化等級,農田和民居的等級限制資源的產出,競技場和酒館沒有等級,競技場是功能入口,酒館包含抽卡,卡牌升星和卡牌分解的功能。架構

7.科技模塊

軍機處的科技收到軍機處建築的等級限制,科技一共有30個,隨着軍機處的等級分別開放,不一樣的科技能增長不一樣的效果,其實有部分科技是屬於陣型,每解鎖一種陣型,就能在戰鬥前設置戰鬥的陣型,陣型中的位置也會隨着君主的等級而開放。

8.關卡模塊

遊戲核心內容是戰鬥,戰鬥包含了普通關卡和精英關卡、以及競技場、國戰和平常副本。其中,普通關卡、精英關卡和平常副本在功能上來講是差很少的,只是戰鬥中的數值配置不一樣,精英關卡和平常副本加了挑戰次數限制,平常副本還加了難度解鎖限制。

9.競技場

玩家的君主等級升級到16級時會開啓競技場,競技場是玩家第一次感受本身玩的不是單機的內容,競技場的規則是打離線數據,服務器開服以後會初始化2000名機器人,玩家選擇挑戰前面排名的玩家,若是挑戰成功,則互換位次,若是挑戰失敗,則位次不變,同時成功失敗均會損失挑戰次數,挑戰次數第二天刷新。

10.活動模塊

國產遊戲最少不了的仍是活動模塊了,作遊戲除了賣情懷,就是賣活動,活動是一款遊戲付費率最高的內容。這款遊戲中包含的活動很少,只有每日簽到、會員、首衝、以及豪華簽到。每日簽到是每9天一個輪迴,天天簽到送不一樣的獎勵,其餘幾種活動均是須要充值人民幣以後再領取到相應的獎勵。

11.國戰模塊

國戰分爲兩個模塊,國戰PVE和人國戰PVP,玩家30級開啓國戰以後會進入一個大地圖,地圖上有76座城池,玩家首先須要進入國戰PVE模塊,把全部的城池都攻打下來纔會開啓國戰的PVP模塊,不過很遺憾的是,即將上線的版本的國戰PVP模塊並無開放,打完PVE以後就會彈出提示PVP暫未開放。雖然沒有開放,但實際上咱們也作了一版國戰,不過在測試中發現其機制有問題,便決定優化以後再上線這個模塊。國戰PVE同關卡部分大同小異,只不過由闖關改成了攻打城池。

12.熱更新

如今的網遊大部分都會有熱更新的功能,所謂熱更新,就是指用戶在不從應用商店更新遊戲版本的狀況下,直接進入遊戲,在遊戲中更新遊戲版本。熱更新的原理就是在服務端存儲一個遊戲版本,客戶端每次進入遊戲先讀取服務端的版本信息,若是有最新版本,就直接從服務端進行下載,下載完在本地解壓更新本地資源,而後再進入遊戲,這樣玩家就能看到最新版本的遊戲資源。

以上是部分功能內容,其餘還有不少邊緣的系統功能沒有介紹,經過這部份內容咱們就能夠開始對遊戲的服務器框架進行分析設計了。

3、網絡通訊

經過功能設計,能夠發現,除了國戰模塊,遊戲總體對實時性要求都不高,與前端商議以後,決定先使用HTTP短鏈接,國戰部分再作商議(但其實後來開發國戰模塊也是經過短鏈接實現的,由於其機制就是一個異步的機制),網絡通訊的數據傳輸也暫時採用最簡單的JSON字符串。不過目前這個機制確實產生了不少問題,首先是HTTP協議,在其餘模塊沒多大問題,但在國戰模塊的時候要求實時性較高,應該採用實時性更強的TCP長鏈接比較合適。另外就是數據傳輸的問題,直接採用JSON字符串確實也沒問題,可是傳輸字符串會讓傳輸信息量變大,這樣在弱網狀況下會使得遊戲的體驗很很差,若是採用二進制進行傳輸,就會好不少。此次的這方面問題沒有考慮周全,下一次我仍是但願採用TCP長鏈接加Google Protobuffer這樣的二進制傳輸協議進行數據交互。

4、數據存儲

遊戲數據分爲兩部分:遊戲數據和玩家數據,遊戲數據指的是遊戲中的靜態數據,若是簽到獎勵,戰鬥掉落,抽卡機率等內容,這部份內容均由策劃配置好靜態表,服務器啓動時直接讀取靜態表,將表中內容加載到服務器內存,使用時直接從內存讀取,而玩家數據指是隨着玩家的操做而變化的數據,這部分數據我又分爲了冷數據和熱數據,熱數據即遊戲中讀寫頻繁的數據,如免費抽卡次數、君主體力恢復、國戰城池狀態等,這部分數據的特色就是讀寫都很頻繁,而且數據結構各不相同,每時每刻這些數據都有可能產生變化,產生讀寫操做,這部分數據,數據結構各不相同,能夠採用nosql數據庫,而Redis不只是nosql數據庫,仍是內存數據庫,很是適合這部分數據的存儲。冷數據,則指的是交互相對不是很頻繁的數據,如君主等級,卡牌等級,卡牌星級,裝備等級,裝備星級等,這部分數據的特色就是讀寫不是很頻繁,須要玩家作了必定操做纔會發生變化,而且數據具備結構化的特色,這些數據能夠抽象出關系型數據表,因此我採用了Mysql進行了這部分數據的存儲,爲了考慮數據庫性能,我採用了Memcache進行Mysql結果集的緩存。後來我認爲,其實遊戲數據的結構應該是採用Mongo更符合需求,它多變的數據結構知足遊戲中的各類數據類型,但因爲確實Mongo的實際開發經驗和維護經驗,也沒敢輕易嘗試。

5、架構設計

做爲後端服務器,可否對前端請求快速作出響應,是判斷一個服務器性能是否良好的重要指標,對於客戶端來講,服務端就是一個url地址或者一個套接字,可是對於整個服務端架構來講,暴露給客戶端的或許只是其中的一個鏈接處理服務器。良好的服務端架構是整個服務端開發成功了一半。我我的經驗並非很豐富,因此我所設計的架構也並非很好的架構,大多數都是我參考了網上大量的關於服務端架構的文章以後的設計,在參考別人文章的過程當中,本身也有了不少感悟。
根據遊戲的需求,可將服務器大體分爲登陸服務器、邏輯服務器、文件服務器、支付服務器、國戰服務器和聊天服務器。在第一輪進行封測時候只有一臺服務器,因此目前全部的服務器設計均部署在同一臺服務器上,提早設計好架構以便在之後更多玩家進來以後進行服務器分離,以承受更多的負載。
整體的結構設計圖以下:
服務器架構圖

1.登陸服務器

負責接入客戶端的登陸,選服的功能,多臺登陸服務器可經過Nginx配置負載均衡以承載更多玩家的鏈接。玩家登陸選服以後,登陸服務器會返回邏輯服務器的地址,此時客戶端與登陸服務器便沒有任何關係,只須要拿着地址去鏈接相應的邏輯服務器,經過引導玩家去到不一樣的遊戲服就實現了玩家流量的分流。

2.邏輯服務器

這是遊戲中最重要的用於處理玩家遊戲邏輯的服務器,玩家的全部邏輯操做都將基於此服務器,若是要用到其餘的服務,則採用Rpc的通訊方式調用其餘服務器的進程,邏輯服務器與其餘服務器的通訊採用Motan Rpc框架,邏輯服務器做爲Motan的調用方,其餘服務器均做爲Motan的服務方。

3.文件服務器

主要用於遊戲中的熱更新,進入遊戲前,客戶端將進行版本檢查,若是發現有最新版本的內容,會提供文件服務器的最新版本下載地址,客戶端請求文件服務器進行更新版本文件下載。

4.支付服務器

遊戲中的充值付費均由支付服務器完成,在邏輯服務器調用支付操做以後,邏輯服務器會經過Motan Rpc調用支付服務器發起支付操做,以後支付服務器會開始調用相應的支付操做,目前遊戲的支付通常是衆多平臺的聯運,會接入第三方的支付SDK,各聯運商的支付接口規範各式各樣,開發商必需要遵循個平臺的規範。

5.國戰服務器

國戰服務器負責處理遊戲中的核心玩法——國戰玩法,因爲國戰的同時在線人數可能較多,因此我把此部分單獨分爲一個服務器,來處理國戰部分的內容,玩家經過邏輯服進入國戰服務器以後,全部的接入將會轉爲國戰服務器,由國戰服務器來處理國戰相關的內容,這樣又能把一部分玩家流量分出來,承擔更多的負載。

6.聊天服務器

遊戲暫無聊天功能,但若是之後加入聊天功能,會將此功能單獨分出來做爲聊天服務器,處理遊戲中的聊天信息。

6、系統架構

以上對服務器的部署架構進行了設計,以上設計按照功能劃分,把遊戲服務器分爲了多個模塊,以邏輯服爲中心,其餘服爲服務提供者的方式進行的服務器劃分。各個模塊在承受不住玩家壓力時均可以再縱向作服務器的集羣擴展,我的感受這種設計仍是比較合理的。由上可見,邏輯服務器是遊戲服務器整個架構的核心。

架構設計以後就要開始對服務器中的技術進行選型,首先開發語言是定位了Java,那麼從網絡層來講,常見的就有Servlet、Spring、Struts、Netty、和Mina,Servlet、Spring和Struts其實能夠歸爲一類,由於Spring和Struts實際上就是對Servlet的一層封裝,在Java Web開發來講,應該說已是很成熟的技術了,他們其實已經對底層的鏈路作了良好的封裝,僅支持HTTP協議,用戶使用他們只須要關注核心的業務邏輯便可,但在Servlet3.0之前,Servlet的IO都是同步阻塞的IO處理(BIO),從3.0開始,纔將Servlet API和NIO結合在了一塊兒,在遊戲中,玩家客戶端與遊戲服務端的請求處理操做是很是頻繁的,從IO方式來看,顯然異步的NIO機制要比同步的BIO快不少,基於NIO能構建出IO處理速度更快的服務端,而Mina和Netty都是基於NIO的網絡框架。最終,在Servlet3和Netty,以及Mina中,我選擇了Netty做爲個人網絡層框架,緣由是Netty有更多的成熟案例,API開發更加簡易,而且有更多的社區和資料。
從數據層來講,前文已經提到了,我將使用Mysql來存儲玩家冷數據,用Redis存儲玩家熱數據,使用Mysql時結合Memcache緩存查詢結果集,增長數據庫的讀性能。使用Redis直接使用Redis官方的Jedis API便可,Jedis不只能直接鏈接Redis,也能用Sentinel進行Redis的主從集羣。Mysql我使用了Hibernate作數據庫ORM框架,緣由是遊戲中不會有太多的複雜查詢,最多會有一個相似於"where userid=1"這樣的查詢條件,沒有太複雜的SQL語句,Hibernate對JDBC作了良好的封裝,若是沒有不少複雜的SQL語句,則能夠直接使用Hibernate便可。雖然Hibernate的性能不如MyBatis或JDBC,但有了Hibernate+Memcache的方案,相信能彌補一些性能上的不足。
還有其餘一些技術就再也不作過多的介紹,整體的架構流程以下:
1.遊戲客戶端爲Cocos2d,與服務器交互採用Http通訊,數據傳輸採用Json格式字符串
2.服務器端的網絡層使用基於Netty實現的Http服務器
3.經過Netty接入客戶端請求,根據請求數據中的協議號,調用服務器中相對應的邏輯模塊
4.邏輯模塊處理消息,若要處理遊戲數據則調用Jedis或Hibernate處理,若觸發某事件,則調用事件處理器
5.經過Netty的ChannelHandlerContext返回處理結果
6.客戶端與服務器交互的數據經過XXTea+Base64進行加密處理
系統架構圖以下:
系統架構圖

7、總結

至此,本文對遊戲的架構分析的內容就結束了,我參加工做也不久,我的經驗很欠缺,文中描述的技術如有誤導的部分,還請幫忙指出來,不要繼續誤導其餘人,再次感謝你們。本系列文章是我本人蔘與一款SLG手遊服務端開發的一些我的看法,我只是想把我學到的,我知道的東西分享給你們。下章開始,我將從各個部分,以源代碼爲基礎進行詳細介紹,下章先講講Netty在HTTP遊戲服務器中的應用。

8、後續

從產品立項到開發,到測試,我經歷了整個開發的過程,整個過程除了讓我在我的技術上有了很多提高、對遊戲服務器有了新的認識以外,也讓我對整個遊戲行業有了不少的見解。在產品的研發過程當中,咱們團隊見證了COK的火爆,CR的興起,ChinaJoy中也看到了中國有不少優秀的手遊做品,同時咱們也看到了國家在7月1日開始對遊戲行業立的新規,以及蘋果對中國政策的妥協。咱們目前的狀態,能夠說是挑戰與機遇並存,小型遊戲CP團隊,不是生,就是死。在這大半年開發中,咱們的產品也是在不斷調整方向,以適應殘酷的遊戲市場,國家出了新規以後,咱們也是第一時間就去申請了文網文以及遊戲版號,足以見得,咱們團隊的每一個人,都想要在這場無聲的戰爭中活下來。眼看產品就要上線,咱們也對本身這款產品作了上線後的數據目標以及盈利目標,無論怎麼樣,我認爲這是咱們辛勤付出的東西,無論成功與否,咱們都有了寶貴的經驗,也算對得起努力的付出了。

相關文章
相關標籤/搜索