如何扩展一个NodeJS有状态的应用程序

我目前正在开发一个基于networking的MMORPG游戏,并且想要build立一个基于Docker和DigitalOcean飞沫的自动缩放策略。

但是,我想知道如何做到这一点:

我的游戏服务器必须在不同的Docker容器之间进行拆分, 但是每个游戏服务器实例都应该像只有一个巨大的游戏服务器那样工作。 这意味着每个修改(angular色移动)都应该在每个其他游戏服务器上进行镜像。

我试图让这个工作(至less在概念上),但无法find一种方法来正确同步我的所有实例。 我应该使用只有广播事件的主人还是有其他select?

我想知道关于我的MySQL数据库的同样的事情:因为每个游戏服务器都必须从db读取/写入数据库,那么随着游戏变得越来越大,我怎样才能使它正确地扩展? 我能想到的最好的解决scheme是将数据库保存在一台function非常强大的服务器上。

我明白,如果所有的游戏服务器都不需要“分享”他们的状态,这可能很容易,但这主要是为了让我可以快速扩展,以防万一突然激增的活动。

(将有不同的“全球”游戏服务器,如A,B,C …但是这些全球游戏服务器中的每一个应该在幕后由运行“真实”游戏服务器的1-Xdocker容器组成, “全球”游戏服务器只是一个概念)

       

网上收集的解决方案 "如何扩展一个NodeJS有状态的应用程序"

你所说的问题太笼统了,很难做出具体的回应。 不过,让我蛮横的,给你一些通用的缩放build议:

  • 从数据库删除计数器。 而是自动递增ID的主键,尝试分配随机的UUID。

  • 通过自包含的数据更改必须通过中心点进行validation的数据。 例如,对于身份validation,不要使用数据库中的用户凭据,而要使用任何主机都可以validation的JSON Web令牌。

  • 使用Consistent Hashing等技术来平衡负载,而不需要负载平衡器。 当然,使用哈希函数可以很好地分配,以避免/最小化碰撞。

上述build议基本上是要改变devise,尽可能多地从有状态转移到无状态。 如果无论如何需要提供有状态的部分,试着猜测哪些实体将有更多的机会共享有状态的数据并将它们分配在相同的(或几乎是服务器)中。 例如,如果游戏中有城市,则尝试在同一个服务器上分配同一城市的用户,因为他们更愿意在不同城市的用户之间进行交互(并共享有状态数据)。

当然,如果这个城市太大而且拥挤,你可能需要在更多的服务器上划分城市,以避免服务器过载。

你的问题太宽泛了,像其他人所提到的一般的缩放问题。 如果您更清楚地说明您的系统要求是什么,那将会很有帮助。

如果它必须是实时的,那么你可以selectRedis作为你的主数据库,但是你需要从属(用于复制),你不能自动缩放*,因为Redis不支持。 我认为当你使用游戏时这不是一个好的select(可能突然出现尖峰)

*似乎有一些托pipe的解决scheme,你需要检查出来

如果它可以接近实时,使用Apache Kafka可以certificate是有用的。

还有一个高度可扩展的数据库,它具有您需要的一切,称为CockroachDB ( 我是贡献者,耶! ),但是您需要运行testing以查看它是否满足您的延迟要求。

总的来说,使用一个非常强大的服务器是一个不错的select,因为有一个天花板,它会花费更多的垂直比例。

横向扩展这样一个应用程序有很大的好处。 我会尽力写下一些想法。

选项1(有状态):

在规划有状态的应用程序时,需要注意状态的同步(通过PubSub,networking广播或其他),并且要知道每个同步都需要一定的时间(当不阻塞每个操作时)。 如果这对你是好的,让我们继续。

假设您在整个集群上每秒有80k个操作。 这意味着每个进程需要每秒同步80k状态更改。 这将是你的瓶颈。 每秒处理80k的变化对Node.js应用程序来说是一个很大的挑战(因为它是单线程的,因此阻塞)。

最后,您需要准确地设置您希望能够同步的最大数量的更改,并使用不同的编程语言执行一些testing。 同步的开销需要添加到应用程序的一般工作负载中。 使用C,Java / Scala或Go等multithreading语言可能会有所帮助。

选项2(有状态路由):*

在某些情况下,实现不同的缩放比例是可行的。 例如,当您的应用程序可以分解成一个地图区域时,您可以从一个应用程序复制开始,该应用程序复制包含完整的地图,当它扩大时,它将以成比例的方式共享地图。 您将需要在应用程序服务器之间实现一些路由,例如更改世界B =>呼叫服务器xyz的城市A中的状态。 这可以自动完成,但降尺度将是一个挑战。

这个解决scheme需要更多的关于应用程序的关心和知识,并不像选项1那样具有容错能力,但可以无限扩展。

选项3(无状态):

将状态移动到其他应用程序,并解决其他地方的问题(如Redis,Etcd,…)