跳到主要内容

与传统架构对比

介绍

这篇,我们讨论一下传统架构与 ioGame 架构的对比,会选择性的抽出几点来做对比, 但不涵盖全部,因为对比得越多,传统架构暴露的缺点也会越多。

传统架构

legacy_system

提示

在传统架构设计中,游戏对外服部分称为网关(或称为玩家网关)。 为了方便理解,这里沿用了 ioGame 游戏对外服的叫法。

传统架构设计通常都是相互直连,从图中可以看出,每个游戏逻辑服都需要与其他的逻辑服建立连接以便能够相互通信。

由于笔墨有限,上图中只画出了 4 个游戏逻辑服和一个游戏对外服,此时的线条已经足够凌乱了。 由于传统的架构服务器之间会相互连接,那么实际连接数 = N * (N-1)。 为了方便表达与计算,后续称这个术语称为 N*N 问题。

N * N 问题

可以看出,传统架构会产生 N*N 问题,下面简单说说 N*N 带来的其他问题。

在连接方面

假设我们有 1,000 个游戏逻辑服,那么光内部连接就有 1000*1000=1,000,000 个。 你没有看错,是百万的内部连接。 那么 10,000 个游戏逻辑服呢?此时的连接大约是一亿个内部连接。

在心跳消耗方面

为了检测连接是否存活,就需要心跳,心跳有发送心跳与响应心跳。 那么连接之间每次处理心跳的次数是 2*N*N

先不说其他的,光心跳就占用了多少开销了。 如果有 10,000 个游戏逻辑服,大约有一亿个内部连接,这样啥都没干,光每次心跳检测就消耗了 2 亿次(请求、响应)。

随着游戏对外服、游戏逻辑服的增加,内部连接总数会以恐怖的数字增加。

依赖中间件方面

此外,你还需要借助很多需要安装的第三方中间件,如:Redis、MQ、ZooKeeper ...等,才能满足整体架构的运作。 只要引入了需要安装的中间件,那么你的架构或者说框架,基本上与轻量级无缘了。

很多开发者无法正确分辨一个架构或框架是否是轻量级的,甚至还见过以代码量来划分是否轻量级的。 Spring 代码量比较多吧,这里可以明确的告诉你,Spring 是轻量级的框架。

或许你会问,Spring-Data 系列需要安装 Mysql、MongoDB、Redis 之类的,为什么还说 Spring 是轻量级的。 首先,Spring-Data 只是 Spring 的一个子项目, 其次,是你为了满足业务需要才引入的,而不是 Spring 强行给你引入的。

一个架构、框架是不是真正的轻量级,取决于是否依赖了需要独立安装的中间件。

或许你会说,我不安装这些中间件不就是轻量级的架构或框架了。 老哥,你这么说是没毛病的,但随着你的业务发展需要,安装中间件是必然的,因为传统架构就是这么设计的。

管理使用方面

你需要为每个游戏逻辑服都分配独立的端口,这里还是以 10,000 个游戏逻辑服为例,这样就需要管理着上万的端口。 在这个数量的基础上,每次有新的游戏逻辑服上线,都需要从注册中心得到各游戏逻辑服的 ip:port,并与这些游戏逻辑服建立连接。

如果使用的是云服务器之类的,别忘了你还需要配置一下相关 port ,否则其他逻辑服连接不进来,别小看这一个环节,通常这些小地方最浪费开发者的时间。

开发成本

在分布式开发体验方面,大部分传统架构是不支持同进程启动多个游戏逻辑服的。 这会让调试与排查问题变得非常困难,从而降低开发者的效率、增加工作量等。 随着你的业务增加,你的开发成本将越来超高。

在业务开发成本,由于传统架构各自相互连接,越多越混乱,那么业务开发的复杂度无形之中又上升了。

成本方面

在使用传统架构时,在成本方面还需要关注,如:安装中间件的成本、维护中间件的成本、学习中间件的成本、部署中间件的成本。

稳定性方面的考虑,安装和使用的中间件越多,不稳定因素则越多,甚至你还得考虑团队其他成员乱用中间件的因素。

优点

由于各服务器之间是相互直连的,那么只需要一次传输就可以到达。

ioGame 架构

提示

ioGame 架构除了具备传统架构的优点外,还能避免传统架构的所有缺点。

重要的是,没有 N*N 问题。

ioGame


从架构简图中,我们知道了整体架构由三部分组成,分别是 1.游戏对外服、2.游戏网关、3.游戏逻辑服,三者既可相互独立,又可相互融合。

N * B

这里的 N 指的是游戏对外服和游戏逻辑服,而 B 指的是 Broker(游戏网关)。

在连接方面

假设我们有 1,000 个游戏逻辑服,那么内部连接的数量是 1000*1=1,000个。 你没有看错,只有一千个内部连接。 那么 10,000 个游戏逻辑服呢?此时的连接大约是一万个内部连接。

由于 Broker(游戏网关)只负责转发请求,全是 cpu 密集型的处理。 所以,我们需要 Broker(游戏网关)机器的数量并不会很多。

通过对比可以看出,无论我们如何计算,ioGame 架构的连接总数是远远少于传统架构的。

在心跳消耗方面

由于 ioGame 架构没有 N*N 问题,所以在心跳开销方面几乎可以忽略不计。

依赖中间件方面

在轻量级方面,ioGame 不依赖任何第三方中间件或数据库就能支持集群、分布式,只需要 java 环境就可以运行。 这意味着在使用上简单了,在部署上也为企业减少了部署成本、维护难度。使用 ioGame 时,只需一个依赖即可获得整个框架, 而无需安装其他服务,如: Nginx、Redis、MQ、Mysql、ZooKeeper、Protobuf 协议编译工具 ...等。

管理使用方面

在安全方面,所有的游戏逻辑服不需要开放端口,天然地避免了扫描攻击。

在 ioGame 中,你不需要为每个逻辑服(游戏对外服、游戏逻辑服)都分配独立的端口。 因为逻辑服是以客户端的方式来连接 Broker(游戏网关)的, 所以,我们只需要知道其中一个 Broker 的 IP:Port 就够了。

由于不需要为每个逻辑服分配独立的端口,那么我们在使用诸如云服务器之类的服务时,就不需要担心端口开放权限的问题了。 别小看这一个环节,通常这些小细节最浪费开发者的时间。 由于我们不需要管理这些 IP:Port这部分的工作量就自然地消失了

更好的分布式开发体验

在分布式开发体验方面,通常在开发分布式应用时是需要启动多个进程的。 这会让调试与排查问题变得非常困难,从而降低开发者的效率、增加工作量等,这也是很多框架都解决不了的问题,但 ioGame 做到了! ioGame 支持多服单进程的启动方式,这使得开发者在开发和调试分布式系统时更加简单。

成本方面

ioGame 不依赖任何第三方中间件或数据库就能支持集群、分布式,只需要 java 环境就可以运行。 从而避免了安装中间件的成本、维护中间件的成本、学习中间件的成本、部署中间件的成本

由于我们不需要打理和使用任何中间件,意味着这部分的工作量就自然的消亡了。

优点

在传统架构中,各服务器之间是相互直连的,那么只需要一次传输就可以到达。

初次接触 ioGame 的开发者在看完架构图后,会认为 ioGame 必须比传统架构多一次的跳转才能到达。 这么理解是正确的,但也不完全正确。 不完全正确是因为 ioGame 是具备架构多样性的, 架构多样性能够适应各种业务场景。

之前我们已经介绍过了,ioGame 的架构由三部分组成,三者既可相互独立,又可相互融合。 所以,使用 ioGame 几乎可以满足任意的部署方式,可以根据你的需求来适应不同类型的游戏,并且在 ioGame 中做这些工作是简单的。

为了更简单的说明三者之间的灵活性,现在把三者用字母代替, A.游戏对外服、B.Broker(游戏网关)、C.游戏逻辑服。 我们可以得出如下组合

  • ABC : 三者在一个进程中,他们之间使用内存通信,无需传输。
  • AB + C : 游戏对外服和游戏网关在一个进程中,他们之间使用内存通信,传输一次。
  • A + BC : 游戏网关和游戏逻辑服在一个进程中,他们之间使用内存通信,传输一次。
  • A + B + C : 三者在不同的进程中,比传统多一次传输。

通过上面的组合,我们可以看出,ioGame 架构是支持类似传统架构那样只做一次跳转, 甚至可以做到零跳转,这完全取决于你们的部署方式。

提示

ioGame 架构是可以做混合组合的,虽然上面只列出了 4 种,但这 4 种是可以混合使用的,不需要局限于某一种方式。 ioGame 的架构由三部分组成,可以将其比作为乐高积木,想适配什么样的游戏,就组装成什么样的架构。 无论如何组装,你的业务代码都不需要做任何改变。

通过不同的部署方式,可以适应各种类型的游戏。 部署方式可以随意的进行切换、变更,并且部署方式的变更是不会对现有的业务造成破坏性影响的,这就是架构灵活性。

小结

本篇中,只是做了一些简单的对比。

  1. 从对比中我们可以看出,传统架构是重量级的,ioGame 架构则是轻量级的。
  2. 传统架构需要借助很多第三方中间件才能正常的运作,而引入的中间件越多,则会造成不稳定性就会上。
  3. 引入需要安装的中间件,存在着安装中间件的成本、维护中间件的成本、学习中间件的成本、部署中间件的成本
  4. 传统架构还存在 N*N 的问题,即使什么都不做,心跳就已经消耗了大部分的机器资源了。
  5. 传统的游戏逻辑服需要给每台机器安排一个启动端口,如果使用的是云服务器之类的, 别忘了你还需要配置一下相关 Port,否则其他逻辑服连接不进来,别小看这一个环节,通常这些小地方最浪费开发者的时间。 而 ioGame 中的逻辑服不需要做这些工作,意味着这部分的工作量自然的消亡了。

这里还没有对比通讯方式,ioGame 提供了多种通讯方式,帮助开发者简化跨进程通信,并且这些通讯方式是可扩展的,通过这些丰富的通讯方式,几乎可以满足任何业务。