服务器开发并不简单,大型游戏服务器的开发更难。比起Web服务器,市面上没有很通用的游戏服务器框架,很多底层功能都需要开发者自己实现,它涉及网络编程,数据库优化,多线程调度等等。而且,游戏的业务与web业务有很大不同,不同类型的游戏对应的服务器结构也不同,内容很多。
OSCHINA特邀《百万在线》的作者@罗培羽 和大家一起聊聊游戏服务器设计相关的问题,在此,我们整理了活动中最有意思的十个问题,与大家分享。
嘉宾简介
罗培羽,任职于广州四三九九公司,负责游戏研发和技术研究工作。专著《Unity3D网络游戏实战(第2版)》被国内多家高校的软件工程专业选做教材。
2021年新作《百万在线:大型游戏服务端开发》以巧妙的章节构思大大降低游戏行业服务端岗位的进入门槛,广受好评,上市两周即荣登京东游戏类新书版TOP1。
问题1:游戏服务器开发是不是使用c/cpp,而电商一般使用java?
答:游戏服务端使用的语言白花齐放,主流看大厂,腾讯用的是cpp,网易cpp+python,阿里游戏cpp+lua,4399用erlang和cpp+lua,所以总体上看cpp方案居多。其他的golang、nodejs、java、.net也都有游戏公司使用。
问题2:mmorpg游戏是否是在服务器维护一个大世界对象?
答:主流的mmorpg技术方案中,玩家、怪物等等都是由服务端去维护的。包括怪物的寻路、人工智能,角色的技能效果等等都由服务端来计算。按照经验一台普通配置的服务器可以支撑几千名玩家,三千到六千之间较为普遍。另外有些游戏采用较为折中的办法,例如将性能消耗较高的玩家寻路、移动位置、技能是否命中计算交给客户端处理,一定程度减少服务端的计算压力。
问题3:游戏服务器入门,需要学习哪些?
答:游戏服务器入门主要要关注网络、数据库、多线程这方面的内容。建议的话说看看一些开源游戏服务框架,比如《百万在线》介绍的skynet,还有ET、kbengne引擎,看他们实现了哪些功能,再探究是怎样实现的。
问题4:游戏服务器的多线程是怎样设计的?
答:不同的技术方案会不同,例如skynet是开启固定的线程数,然后将网络消息分配给其中某个线程去处理;另一种常见设计方案叫“one loop per thread”,也开启固定的线程,将不同的连接分配给不同的线程去处理。一般不会给每个客户端单独开一条线程,因为线程挺占资源,经验上一台服务器支撑数百条线程就会卡顿。
问题5:是否能在游戏引擎中引入区块链技术来防止作弊?
答:没必要。区块链技术解决的是“不信任”情况下的一致性问题,它的效率很低。而游戏服务端就是一个可以“信任”的服务器,就无须花费很多成本去实现区块链了。客户端间也可以两两通信,就像常见的端对端传输技术。总的来说,区块链技术是可以解决游戏客户端间端对端传输时候防止作弊的问题,但它的效率远远低于引入服务器。
问题6:分布式系统并不稳定,那跨服活动之类的需求是如何实现的?
答:现代游戏服务端大部分都是分布式的,按照经验一台普通配置的服务器可以支撑几千名玩家(例如mmorpg游戏),游戏在线人数一般很高,一台服务器是无法支撑起来的。就算给客户端暴露的是一个大区服,实际内部也会使用分布式结构。不同的服务器通过网络通信。一般而言,会将一款游戏的所有服务器放到一个机房内,这样稳定性会高一些。分布式事务很复杂,除非像支付相关的系统,不然一般只用直接的网络通信来处理跨服逻辑。
问题7:网络游戏的通信是长链接吗?通信是手机端发起的吗?
答:现在的游戏一般都是长连接,除非是那种单机玩法为主的,每局游戏上传个分数的小游戏有可能有短连接。通信都是服务端监听,客户端(手机)发起连接。手机下载的游戏里会有服务端的地址,然后手机去连接服务器。
问题8:对于帧同步的游戏,服务器端怎样选取一个合适的时间间隔来处理收到的多帧数据?
答:一般而言,每秒8-15次的同步是较为合适的,可以参考这个时间间隔,相对而言较为平衡操作的反馈和网络负载。但如果使用tcp,同步次数就要更低一些。对于落后太多时间的,客户端快速模拟,模拟过程中会屏蔽该玩家的操作,避免出现数据错乱。如果实在落后太多,就只能把这名玩家提出游戏了,以免影响其他玩家。
问题9:实时游戏服务端怎么解决网络延迟问题?
答:对于TCP连接,要关闭nagle算法,可以做到大概3v3的战斗;客户端也可以做些障眼法,比如做平顺的移动来让玩家有较好的感受。《百万在线》第8章“同步算法”,会介绍延迟对网络同步的影响等内容。若要达到更好的效果,可以使用udp协议,但游戏udp不可靠,需要自己再封装一层实现比TCP快的协议(但流量一般会增多,比如开源的kcp协议)。
问题10:mmorpg游戏的NPC是如何设计他们的AI系统才能让服务器不至于过载呢?
答:MMO游戏的怪物AI一般比较简单,比如视野内有人就走过去打,超出行动范围就返回原地,逻辑不太难。行为树、状态机很耗性能,一般不会每帧执行,比如根据怪物的设定难度,每隔一两秒执行一次行为树,这样性能就能降低,而且可以把多个怪物的执行时间错开,使得整体达到较为平稳的性能损耗。
购买链接:https://item.jd.com/12931061.html
|