应该如何设置针对高需求应用程序的node.js堆栈?

die*_*lar 7 mongodb node.js sails.js mean-stack

我目前正在研究超过25000人使用的Node.js堆栈应用程序,我们特别使用Sails.js框架,我们得到的MongoDB应用程序运行在具有30GB RAM的EC2实例上,数据库运行在Mongolab上基于AWS的集群在EC2所在的同一区域中.我们甚至有一个1.5GB的Elastic Cache Redis实例用于存储.

因此,我们面临的主要和巨大问题是延迟.当我们达到请求应用程序的并发用户的峰值时,我们得到多个超时和sails应用程序达到超过7.5GB的RAM,对API的HTTP请求花费的时间超过15秒(这是不可接受的),甚至得到502和504的响应发送nginx的.

我可以注意到Mongo写入操作是我们的主要延迟问题,但是当存在需求峰值时,即使GET请求也需要很长时间.我无法访问生产服务器,我只有pm2(实际上很棒)和New Relic警报的keymetrics监控工具.

所以,我想知道一些应对这些问题的路线图,也许应该提供更详细的信息,到目前为止,我可以说当没有太多用户时,应用程序看起来很稳定.

要考虑哪些主要因素和设置?

到目前为止,我知道我应该做的,但我不知道有关细节或怎么样了.

恕我直言:

  1. 尽可能缓存.
  2. 延迟MongoDB写操作.
  3. 具有更高写入需求的单独Mongo数据库.
  4. 虚拟化?
  5. 调整节点设置.

在优化代码时,我发布了另一个stackoverflow问题,其中包含一个我正在遵循代码模式示例.

您对生产应用有何建议和意见?

Kon*_*rev 3

基本上大部分要点已经在答案中体现了。我只是总结一下。

为了优化您的应用程序,您可以做几件主要的事情。

  1. 尝试将形式转移node.jsio.js它仍然具有更好的性能和最新的前沿更新。(但请仔细阅读实验功能)。或者至少从node.js v10v12。有很多性能优化。

  2. 避免使用使用 I/O 操作或处理大量数据的同步函数。

  3. 从单节点进程切换到集群系统。

  4. 检查您的应用程序是否存在内存泄漏。我正在使用memwatch-next fornode.js v12memwatch fornode.js v10

  5. 尽量避免将数据保存到全局变量中

  6. 使用缓存。对于应该在全球范围内访问的数据,您可以使用Redis或者Memcached也是一个很棒的商店。

  7. 避免async与 一起使用Promises。两个库都在做同样的事情。所以没有必要同时使用它们。(我在你的代码示例中看到了这一点)。

  8. 结合可以做到的方法async.waterfallasync.parallel例如,如果您需要从 mongo 获取一些仅与用户相关的数据,您可以获取用户,然后并行获取您需要的所有其他数据。

  9. 如果您正在使用,sails.js请确保它处于production模式下。(我假设你已经这样做了)

  10. 禁用所有不需要的挂钩。在大多数情况下,钩子是无用的。如果您的应用程序grunt不需要- 使用文件禁用它。就像是:Socket.io.sailsrc

    { "generators": { "modules": {} }, "hooks": { "grunt": false, "sockets": false } }

另一个可以禁用的钩子是:i18n, csrf, cors。但前提是您不在系统中使用它们。

  1. 禁用无用的全球化。在config/globals.js。我认为_, async,services可以默认禁用。只是因为Sails.js使用旧版本的库lodashasync新版本具有更好的性能。

  2. 手动安装lodash到项目asyncSails.js并使用新版本。(看第11点)

  3. 将结果返回给用户后可以进行一些“写入 mongo”操作。例如:您可以调用res.view()将在之前向用户发送响应的方法,Model.save()但代码将继续使用所有变量运行,因此您可以将数据保存到 mongo DB。因此用户在写入操作期间不会看到延迟。

  4. 您可以使用RabbitMQ等队列来执行需要大量资源的操作。例如:如果您需要存储大数据集合,您可以将其发送给RabbitMQ用户并向用户返回响应。然后在“后台”进程广告存储数据中处理此消息。它还可以帮助您扩展应用程序。