加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 站长资讯 > 外闻 > 正文

教你从头写游戏服务器框架

发布时间:2019-02-23 14:24:51 所属栏目:外闻 来源:腾讯游戏学院
导读:副标题#e# 1.需求 由于越通用的代码,就是越没用的代码,所以在设计之初,我就认为应该使用分层的模式来构建整个系统。按照游戏服务器的一般需求划分,最基本的可以分为两层: 底层基础功能:包括通信、持久化等非常通用的部分,关注的是性能、易用性、扩展
副标题[/!--empirenews.page--]

1.需求

由于“越通用的代码,就是越没用的代码”,所以在设计之初,我就认为应该使用分层的模式来构建整个系统。按照游戏服务器的一般需求划分,最基本的可以分为两层:

底层基础功能:包括通信、持久化等非常通用的部分,关注的是性能、易用性、扩展性等指标。

高层逻辑功能:包括具体的游戏逻辑,针对不同的游戏会有不同的设计。

我希望能有一个基本完整的“底层基础功能”的框架,可以被复用于多个不同的游戏。由于目标是开发一个适合独立游戏开发的游戏服务器框架。所以最基本的需求分析为:

功能性需求

  1. 并发:所有的服务器程序,都会碰到这个基本的问题:如何处理并发任务。一般来说,会有多线程、异步两种技术。多线程编程在编码上比较符合人类的思维习惯,但带来了“锁”这个问题。而异步非阻塞的模型,其程序执行的情况是比较简单的,而且也能比较充分的利用硬件性能,但是问题是很多代码需要以“回调”的形式编写,对于复杂的业务逻辑来说,显得非常繁琐,可读性非常差。虽然这两种方案各有利弊,也有人结合这两种技术希望能各取所长,但是我更倾向于基础是使用异步、单线程、非阻塞的调度方式,因为这个方案是最清晰简单的。为了解决“回调”的问题,我们可以在其上再添加其他的抽象层,比如协程或者添加线程池之类的技术予以改善。
  2. 通信:支持请求响应模式以及通知模式的通信(广播视为一种多目标的通知)。游戏有很多登录、买卖、打开背包之类的功能,都是明确的有请求和响应的。而大量的联机游戏中,多个客户端的位置、HP 等东西都需要经过网络同步,其实就是一种“主动通知”的通信方式。
  3. 持久化:可以存取对象。游戏存档的格式非常复杂,但其索引的需求往往都是根据玩家 ID 来读写就可以。在很多游戏主机如 PlayStation 上,以前的存档都是可以以类似“文件”的方式存放在记忆卡里的。所以游戏持久化最基本的需求,就是一个 key-value 存取模型。当然,游戏中还会有更复杂的持久化需求,比如排行榜、拍卖行等,这些需求应该额外对待,不适合包含在一个最基本的通用底层中。
  4. 缓存:支持远程、分布式的对象缓存。游戏服务基本上都是“带状态”的服务,因为游戏要求响应延迟非常苛刻,基本上都需要利用服务器进程的内存来存放过程数据。但是游戏的数据,往往是变化越快的,价值越低,比如经验值、金币、HP,而等级、装备等变化比较慢的,价值则越高,这种特征,非常适合用一个缓存模型来处理。
  5. 协程:可以用 C++ 来编写协程代码,避免大量回调函数分割代码。这个是对于异步代码非常有用的特性,能大大提高代码的可读性和开发效率。特别是把很多底层涉及IO的功能,都提供了协程化 API,使用起来就会像同步的 API 一样轻松惬意。
  6. 脚本:初步设想是支持可以用 Lua 来编写业务逻辑。游戏需求变化是出了名快的,用脚本语言编写业务逻辑正好能提供这方面的支持。实际上脚本在游戏行业里的使用非常广泛。所以支持脚本,也是一个游戏服务器框架很重要的能力。
  7. 其他功能:包括定时器、服务器端的对象管理等等。这些功能很常用,所以也需要包含在框架中,但已经有很多成熟方案,所以只要选取常见易懂的模型即可。比如对象管理,我会采用类似 Unity 的组件模型来实现。

非功能性需求

  1. 灵活性:支持可替换的通信协议;可替换的持久化设备(如数据库);可替换的缓存设备(如 memcached/redis);以静态库和头文件的方式发布,不对使用者代码做过多的要求。游戏的运营环境比较复杂,特别是在不同的项目之间,可能会使用不同的数据库、不同的通信协议。但是游戏本身业务逻辑很多都是基于对象模型去设计的,所以应该有一层能够基于“对象”来抽象所有这些底层功能的模型。这样才能让多个不同的游戏,都基于一套底层进行开发。
  2. 部署便利性:支持灵活的配置文件、命令行参数、环境变量的引用;支持单独进程启动,而无须依赖数据库、消息队列中间件等设施。一般游戏都会有至少三套运行环境,包括一个开发环境、一个内测环境、一个外测或运营环境。一个游戏的版本更新,往往需要更新多个环境。所以如何能尽量简化部署就成为一个很重要的问题。我认为一个好的服务器端框架,应该能让这个服务器端程序,在无配置、无依赖的情况下独立启动,以符合在开发、测试、演示环境下快速部署。并且能很简单的通过配置文件、或者命令行参数的不同,在集群化下的外部测试或者运营环境下启动。
  3. 性能:很多游戏服务器,都会使用异步非阻塞的方式来编程。因为异步非阻塞可以很好的提高服务器的吞吐量,而且可以很明确的控制多个用户任务并发下的代码执行顺序,从而避免多线程锁之类的复杂问题。所以这个框架我也希望是以异步非阻塞作为基本的并发模型。这样做还有另外一个好处,就是可以手工的控制具体的进程,充分利用多核 CPU 服务器的性能。当然异步代码可读性因为大量的回调函数,会变得很难阅读,幸好我们还可以用“协程”来改善这个问题。
  4. 扩展性:支持服务器之间的通信,进程状态管理,类似 SOA 的集群管理。自动容灾和自动扩容,其实关键点是服务进程的状态同步和管理。我希望一个通用的底层,可以把所有的服务器间调用,都通过一个统一的集权管理模型管理起来,这样就可以不再每个项目去关心集群间通信、寻址等问题。

一旦需求明确,基本的层级结构也可以设计了:

教你从头写游戏服务器框架

最后,整体的架构模块类似:

2.通信模块

对于通信模块来说,需要有灵活的可替换协议的能力,就必须按一定的层次进行进一步的划分。对于游戏来说,最底层的通信协议,一般会使用 TCP 和 UDP 这两种,在服务器之间,也会使用消息队列中间件一类通信软件。框架必须要有能同事支持这几通信协议的能力。故此设计了一个层次为: Transport。

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读