我现在已经进入节点深度潜水了几周。我从安东尼关于udemy的优秀课程中学到了很多东西,而我现在正在读一本书#34; nodejs正确的方式"。我还经历了很多文章,这些文章提出了关于节点和耦合其他技术的真实场景的一些非常好的观点。
然而,它似乎被接受为法律,你不会将Node作为单一线程架构执行计算繁重的任务。我了解了事件循环和异步回调等。事实上,如果我理解正确,节点强度源于大量的并发IO连接。无论我在哪里阅读,消息来源警告不要挂断执行任务的线程。我似乎无法找到任何经验法则来避免使用节点进程。我已经看到一个解决方案,说节点应该将计算量很大的任务传递给像RabbitMQ这样的消息服务,专用的应用程序服务器可以通过这个服务(对于这个任务有什么与节点配对的建议吗?我读了一些关于N的东西)层架构)。我之所以感到困惑的原因是因为我看到节点被用于读取和写入文件以突出显示流的使用,但在我看来,提取/读取/写入文件是一项昂贵的任务(我觉得有点误)。
Tl; Dr应该将节点传递给工作服务器的任何类型的任务?我可以阅读哪些材料来详细解释范例?
编辑:似乎我缺乏理解源于不知道什么甚至会在明显同步的IO请求之外停止一个线程。因此,如果我理解正确读取和写入数据是IO,其中改变所述数据或进行数学计算是计算上昂贵的(当然,取决于任务的不同级别)。谢谢你的所有答案!
答案 0 :(得分:1)
如果您将node.js用作服务器,则运行长时间运行的同步计算任务会占用一个线程,在此计算过程中,您的服务器不会响应其他请求。这通常是服务器的糟糕情况。
因此,node.js服务器设计的一般设计原则是:
仅使用异步I / O功能。例如,使用fs.readFile()
,而不是fs.readyFileSync()
。
如果您的计算操作非常紧张,请将其移至子进程。如果你做了很多这些,那么有几个子进程可以处理这些长时间运行的操作。这样可以保持主线程空闲,从而可以响应I / O请求。
如果要提高服务器的整体可伸缩性和响应能力,可以使用每个CPU的服务器进程实现群集。这不是上面#2的替代品,但也可以提高可扩展性和响应能力。
我之所以感到困惑的原因是因为我看到节点被用于 读取和写入文件以突出显示流的使用但在我的 提取/读取/写入文件是一项昂贵的任务(我觉得 误)。
如果您使用I / O函数的异步版本,那么从磁盘读取/写入不会阻止主JS线程,因为它们呈现异步接口,并且主线程可以在系统获取数据时执行其他操作来自磁盘。
节点应该将哪些任务传递给工作服务器?
这取决于您尝试支持的服务器负载,您要求它做什么以及您对响应延迟的容忍度。您的目标负载越高,那么您需要从主JS线程和其他进程中获得任何计算密集型任务。在中等数量的长时间运行事务和适度的服务器负载下,您可能只能使用群集来实现可伸缩性和响应性目标,但是在交易长度或您尝试的负载的某个阈值处支持,你必须从主JS线程中获取计算密集的东西。
答案 1 :(得分:1)
但是,它似乎被接受为法律,你不会将Node作为单一线程架构执行计算量很大的任务。
我会改写这个:
除非您需要使用Node
,否则不要执行计算量很大的任务
有时,您需要处理大量数据。有时,在进程中执行此操作比通过它更快或更好。
我有一个Node.js服务器,它从一堆服务器读取原始日志数据。我没有使用标准的日志记录实用程序,因为我已经完成了一些自定义处理,以及用于获取日志数据的自定义身份验证方案。整个过程就是HTTP请求,然后解析并重写数据。
可以想象,这使用了大量的CPU。虽然这是因为CPU浪费了吗?我用JS做任何事情,如果我用另一种语言写的话,我能做得更快吗?通常情况下,CPU忙于一个真正的原因,切换到更本地的东西的好处可能是微不足道的。然后,你必须考虑转换的开销。
请记住,使用Node.js,您可以编译本机扩展,因此可以在完善的框架中充分利用这两个世界。
对我而言,人类的权衡取而代之。我是一个比本地运行的任何东西都更有效率的Node.js开发人员。即使我的Node.js应用程序被证明比本机的速度慢5倍(我认为这将是极端的),我可以再购买5台服务器来运行,成本远低于我需要的成本。开发和维护本机解决方案。
使用您需要的东西。如果您需要在Node.js中刻录大量CPU,请确保尽可能高效地执行此操作。如果您发现可以使用本机代码优化某些内容,请考虑进行扩展并确保以后测量性能差异。如果你觉得有必要抛弃整个堆栈......重新考虑你的方法,因为可能是你不考虑的东西。
答案 2 :(得分:0)
读取和写入文件是I / O操作,因此它们不是CPU密集型的。您可以使用Node执行大量并发I / O,而不会占用任何单个请求(例如,在节点HTTP服务器中)。
但人们总是将Node用于CPU密集型任务,并且很好。您必须意识到,如果它在任何大量时间内使用所有CPU,那么您将阻止对该服务器的所有其他请求,如果您需要服务器保持可用,这通常是不可接受的。但是很多时候你的Node进程并没有试图成为一个服务器反击许多请求的响应,比如当你有一个只处理数据的Node程序而根本不是服务器时。
此外,使用其他进程并不是在Node中执行后台任务的唯一方法。还有webworker-threads
允许您使用线程,如果更方便(您必须复制数据)。
我会停止阅读并做一些有针对性的实验,这样你就可以看到他们在谈论什么。尝试创建并测试三个不同的程序:1)HTTP服务器处理大量请求,总是立即返回文件内容2)HTTP服务器处理大量请求,但某个请求导致大数学计算需要很多秒才能返回(将阻止所有其他请求 - 大问题)3)一个不是HTTP服务器的节点程序,它执行大型数学计算并在终端中吐出结果(即使它需要一段时间才能工作,但不处理其他请求,因为它不是一个服务器,所以它很好阻止)。