1

我在一个小团队中开发一个单页应用程序,该应用程序严重依赖 WebSockets 上的低延迟查询。后端在 Node.js + Redis 上运行。它需要支持成百上千的同时连接,并且请求需要在 50 - 100 毫秒(在客户端良好的网络条件下)内得到服务。我们对服务器这部分的初始实现相当满意,它按预期执行。

我们还需要通过 HTTP 提供大量静态文件。这些请求对时间不敏感。由于存储需求很大,出于成本原因,我们希望选择 HDD 阵列而不是 SSD。

是否存在磁盘 I/O 缓慢降低 Node.js 应用程序其余部分的性能(WebSocket 部分仅使用内存数据库)的风险,还是会严格影响服务器的 HTTP / 静态文件服务部分? 据我了解,具有异步特性的 Node.js 非常适合这种情况,因为它允许 WebSockets 模块在 HTTP 模块等待磁盘读/写时正常处理查询?

也许大量“等待服务”的 HTTP 请求会以某种方式阻塞服务器(毕竟,它们需要存储在某个地方,如果读/写可用,则可能无法自由轮询),我们需要考虑使用单独的 Node.js 进程来提供静态文件,甚至完全使用单独的专用服务器?

我可以想到以下几点:

  • “等待服务”的 HTTP 请求将用完有限数量的并发 TCP 连接可用
  • “等待服务”的 HTTP 请求也会消耗一些 RAM
  • 系统文件可能应该驻留在不会忙于为静态文件提供服务的磁盘上

我们还不能在现实世界中测试这个场景,所以我会非常感谢任何有类似经历的人的来信。这可能需要我们重新考虑架构,这是我们最好早日发现的东西。

4

2 回答 2

2

简短回答:的,存在巨大风险:p

https://nodejs.org/api/fs.html#fs_threadpool_usage

线程池使用#

除了 fs.FSWatcher() 和显式同步的文件系统 API 之外的所有文件系统 API 都使用 libuv 的线程池,这可能会对某些应用程序产生令人惊讶的负面性能影响。有关详细信息,请参阅 UV_THREADPOOL_SIZE 文档。

http://docs.libuv.org/en/v1.x/design.html#file-io

UV Threadpool 由系统线程支持,因此缩放配置文件将与应用程序的其余部分非常不同。IMO 这并不一定会带来更大的风险......不同的硬数据将有助于查看您的应用程序的扩展配置文件。


认为一般的最佳做法是尽可能卸载静态文件的服务。在您的应用程序前面有一个能够快速提供静态文件(nginx)的代理可能会有所帮助(不是因为它解决了阻塞文件系统读取的核心问题,而是因为它可以提供更统一/可预测的性能或扩展,因为它只必须管理服务文件,而您的应用程序需要在用户和服务文件之间进行上下文切换。我个人会研究您关于使用单独进程或 CDN 的建议,以尝试从您的应用程序中完全删除静态文件的服务。

于 2019-01-10T20:24:52.897 回答
1

如果您有很多来自客户端的请求,则需要通过集群 API https://nodejs.org/api/cluster.html使用负载均衡器。 您还需要考虑使用缓存,因为 http 和磁盘操作确实很昂贵。如果这些东西还不够,您只需添加新服务器。这就是我做和理解解决高负载问题的方式。

PS 我不认为 node.js 是个问题,它是处理静态文件之类的好平台。你只是有很多请求,你需要用我描述的方法来处理这个问题。

于 2019-01-08T09:55:23.377 回答