在基于PHP(或Java/ASP.NET/Ruby)的web服务器中,每个客户端请求都在一个新线程上实例化。但是在Node.js中,所有的客户端都运行在同一个线程上(它们甚至可以共享相同的变量!)我知道I/O操作是基于事件的,所以它们不会阻塞主线程循环。

What I don't understand is WHY the author of Node chose it to be single-threaded? It makes things difficult. For example, I can't run a CPU intensive function because it blocks the main thread (and new client requests are blocked) so I need to spawn a process (which means I need to create a separate JavaScript file and execute another node process on it). However, in PHP cpu intensive tasks do not block other clients because as I mentioned each client is on a different thread. What are its advantages compared to multi-threaded web servers?

注意:我已经使用集群来解决这个问题,但它并不漂亮。


Node.js是作为异步处理的实验显式创建的。理论上,在一个线程上进行异步处理可以在典型的web负载下提供比典型的基于线程的实现更好的性能和可伸缩性。

你知道吗?在我看来,那个理论已经被证实了。一个node.js应用程序不做CPU密集型的事情,可以比Apache或IIS或其他基于线程的服务器多运行数千个并发连接。

单线程、异步的特性确实让事情变得复杂。但是你真的认为它比线程更复杂吗?一个比赛条件可以毁掉你的整个月!或者由于某个地方的某些设置而清空线程池,并看着您的响应时间慢到爬行!更不用说死锁、优先级反转和所有与多线程相关的其他旋转。

最后,我不认为这是普遍的好或坏;这是不同的,有时更好,有时不好。使用正确的工具。

长话短说,节点从V8中抽取,V8内部是单线程的。对于cpu密集型任务,有一些方法可以解决这些限制。

在某一点(0.7),作者试图引入隔离作为实现多线程计算的一种方式,但最终被删除了:https://groups.google.com/forum/#!味精/ nodejs zLzuo292hX0 / F7gqfUiKi2sJ

服务器的“每个请求一个线程”模型的问题在于,与事件循环线程模型相比,它们不能很好地适应多种场景。

通常,在I/O密集型场景中,请求花费大部分时间等待I/O完成。在此期间,在“每个请求一个线程”模型中,链接到线程的资源(如内存)是未使用的,内存是限制因素。在事件循环模型中,循环线程选择下一个事件(I/O完成)来处理。因此线程总是处于忙碌状态(当然,如果您正确地编程)。

事件循环模型是所有新事物的闪亮之处,是所有问题的解决方案,但使用哪种模型取决于您需要处理的场景。如果您有一个密集的I/O场景(如代理),则事件库模型将起主导作用,而CPU密集且并发进程数量较少的场景将最适合使用基于线程的模型。

在现实世界中,大多数场景都处于中间位置。你需要平衡可伸缩性的实际需求和开发的复杂性,以找到正确的架构(例如,拥有一个事件基础前端,将CPU密集型任务委托给后端。前端将使用很少的资源等待任务结果。)与任何分布式系统一样,它需要一些努力才能使其工作。

如果你想毫不费力地寻找一颗适用于任何情况的灵丹妙药,那你只会落得脚中弹的下场。