在基于PHP(或Java / ASP.NET / Ruby)的Web服务器中,每个客户端请求都在新线程上实例化。但是在Node.js中,所有客户端都运行在同一个线程上(它们甚至可以共享相同的变量!)我知道I / O操作是基于事件的,所以它们不会阻塞主线程循环。
我不明白为什么Node的作者选择它是单线程的?这让事情变得困难。例如,我无法运行CPU密集型功能,因为它阻塞了主线程(并阻止了新的客户端请求),因此我需要生成一个进程(这意味着我需要创建一个单独的JavaScript文件并在其上执行另一个节点进程) )。但是在PHP中,cpu密集型任务不会阻止其他客户端,因为我提到每个客户端都在不同的线程上。与多线程Web服务器相比,它有哪些优势?
注意:我已经使用群集来解决这个问题,但它并不漂亮。
答案 0 :(得分:255)
Node.js是作为异步处理的实验明确创建的。理论上说,在典型的Web负载下,在单个线程上执行异步处理可以提供比典型的基于线程的实现更高的性能和可伸缩性。
你知道吗?在我看来,理论得到了证实。没有CPU密集型东西的node.js应用程序可以比Apache或IIS或其他基于线程的服务器运行数千个并发连接。
单线程,异步性质确实使事情变得复杂。但你真的认为它比线程更复杂吗?一场比赛的情况可能毁了整个月!或者由于某些设置而将您的线程池清空,并观察您的响应时间慢到爬行!更不用说死锁,优先级反转以及多线程所带来的所有其他旋转。
最后,我不认为它普遍好或坏;它是不同的,有时它更好,有时它不是。使用正确的工具完成工作。
答案 1 :(得分:55)
服务器的“每个请求一个线程”模型的问题是,与事件循环线程模型相比,它们在几种情况下无法很好地扩展。
通常,在I / O密集型方案中,请求会花费大部分时间等待I / O完成。在此期间,在“每个请求一个线程”模型中,链接到线程(例如内存)的资源未使用,内存是限制因素。在事件循环模型中,循环线程选择要处理的下一个事件(I / O完成)。所以线程总是很忙(如果你当然正确编程的话)。
事件循环模型,因为所有新事物看起来都很闪亮,所有问题的解决方案,但使用哪种模型将取决于您需要解决的方案。如果您有一个密集的I / O场景(如代理),则事件基础模型将进行规则,而具有较少并发进程数量的CPU密集型场景将最适用于基于线程的模型。
在现实世界中,大多数情景都会在中间。您需要平衡对可伸缩性的真正需求与开发复杂性,以找到正确的体系结构(例如,有一个事件库前端委托后端进行CPU密集型任务。前端将使用很少的资源等待任务结果。)与任何分布式系统一样,它需要一些努力才能使其工作。
如果您正在寻找适合任何场景的银弹而不费力,您最终会得到一颗子弹。
答案 2 :(得分:28)
长话短说,节点来自V8,内部是单线程的。有办法解决CPU密集型任务的约束。
在某一时刻(0.7),作者试图将隔离带作为实现多个计算线程的一种方式,但最终被删除了:https://groups.google.com/forum/#!msg/nodejs/zLzuo292hX0/F7gqfUiKi2sJ