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团队,不是生,就是死。在这大半年开发中,咱们的产品也是在不断调整方向,以适应残酷的游戏市场,国家出了新规以后,咱们也是第一时间就去申请了文网文以及游戏版号,足以见得,咱们团队的每一个人,都想要在这场无声的战争中活下来。眼看产品就要上线,咱们也对本身这款产品作了上线后的数据目标以及盈利目标,无论怎么样,我认为这是咱们辛勤付出的东西,无论成功与否,咱们都有了宝贵的经验,也算对得起努力的付出了。

相关文章
相关标签/搜索