可扩展的Node.js应用程序架构

过去,我只在本地机器上玩过Node.js,所以我只有单进程Node.js应用程序的经验。 现在我想创build一个Web应用程序,我可以在网上发布。

这个networking应用程序就像多人游戏 – 使用Socket.IO进行客户端 – 服务器通信,使用Express处理HTTP请求,使用Grunt进行任务pipe理等等 – 我还想使用其他NPM软件包以执行各种任务。

我想devise这个应用程序的体系结构

  • 启用横向可伸缩性(后来,当我有很多访问者,我不必重写整个应用程序)
  • 最大限度地减less对不同执行环境的依赖(最大化可移植性)

我怎样才能实现这个使用节点?

我想高级架构将包括:

  • 不同的服务器进程 (每个进程将运行一个Express实例并处理传入的HTTP请求)。
  • 应该有一个负载平衡器的地方。
  • 可选: 后台进程可以定期运行并处理“共享数据”

由于我的应用程序是一个多人应用程序,每个用户都可以与其他在线用户交互,所以我应该在某个地方存储一些可以在这些进程之间共享的共同状态 (“共享数据”)。

为了简单起见,起初我不必坚持这个共享数据,所以我想我应该使用像Redis这样的内存数据存储。

大图像看起来像这样:

示例Node.js应用程序体系结构

这个devise提出了一些问题:

如何产生过程?

我应该使用Node的child_process还是cluster模块并手动启动工作进程? 顺便说一句,是否有可能手动启动这些,例如,如果我的应用程序部署到Heroku或Nodejitsu ?

或者: is there a better way to store these information in a config file?

我的意思是,如果我可以configuration多less个服务器实例,而不是编辑代码而是一个configuration条目,会更好。

系统边界?

如果我手动产生进程,那么(我猜)所有进程都会在同一个(虚拟)服务器上运行。

如果这个服务器有4个CPU内核,那么你最多可以产生4个Node实例,因为如果你产生了更多的CPU,你的CPU将会产生上下文切换,这会损害整体性能。

如果我需要更多的stream程实例,我该怎么办? 假设我需要100个服务器实例。 我必须将我的应用程序部署到25台服务器,并在每台服务器上产生4个进程?

在我看来,像Nodejitsu这样的主机服务以某种方式隐藏了你的这个系统边界层,但我不明白它在实践中是如何工作的。

特别是有这个“共享数据”提供者组件。 我想这个提供者(比如一个Redis服务器)必须运行在不同的服务器上,这样它才能被所有进程使用。 但在这种情况下,很容易成为瓶颈,不是吗?

负载平衡器?

如果我使用一些托pipe服务,我必须自己设置负载均衡器层吗?


编辑:

回答一些实际问题:第一步,我想要无缝地处理4-500个并发用户(Socket.IO连接)。 这是我可以切实实现的访问量。

但是我只是好奇,可能(如果是的话,怎么样?)来devise一个可以轻松扩展的应用程序架构。 假设我的网站会一天比一天stream行起来,而不是处理几百个并发用户,第二天我就要服务几千个。

据我所知,像Heroku和Nodejitsu这样的云托pipe服务可以很容易地适应这些情况 – 你只需要增加工人数量/ dynos /任何 – 但只有你有正确的应用程序架构才能工作。

关于共享数据:我不想坚持下去。 我只是想保留在内存中。 一方面,由于Socket.IO,一些共享的数据提供者是需要的 – 一个用户将能够发送消息给另一个“节点”中的用户。 为此,我将使用Redis作为共享数据提供者。 Redis需要处理的事务数量等于使用Socket.IO发送/接收的消息数量,约1000-1500条消息/秒。

另一方面,一些共享数据提供者是需要的,因为我想根据几个标准连接用户。 之后,后台进程会定期重新计算/优化这些连接的概率(“权重”)。 我已经有一些想法如何实现高效的数据结构来处理快速插入/移除到这个内存表。 所以“共享数据提供者”组件将包含一些服务器端代码(可能是Node.js),可以存储这些连接。

我知道这是TL,但是我希望它能回答你所有关于这个问题的技术问题。 🙂

好的,这是很多要经历的。 首先,你关心的问题是适当的,你需要一个进程通信的方式,这可以通过Redis实例,或其他pub / sub或req / res系统(无论是redis,kue,zmq等)。 注意:如果您的数据显着增长,您可能仍然需要分割您的数据/消息使用量,至less尽可能多。 如果使用更复杂的消息队列系统(Rabbit或其他AMQP),则可以减轻这一点。

看来你最关心的是stream程pipe理。 一般来说,如果你使用的是Heroku,你应该可以扩展每个节点的单个进程,但是你仍然需要你的协调节点。 如果你是自我托pipe(不是通过heroku或类似的),那么你应该看看pm2或永远 …然后,你可以调出多个实例…

大多数情况下,您的物stream/基础设施问题将根据您的需求而有所不同。 更不用提涉及CI / CD,docker等的新策略了。 或者你的数据库使用。