Node.js的事件驱动有什么不同?在ASP.Net的HttpAsyncHandler中不能实现吗?

75

我对Web编程并不是很有经验,实际上还没有在Node.js上编写过任何代码,只是对事件驱动的方法感到好奇。它似乎很不错。

该文章解释了使用基于线程的方法处理请求可能会出现的一些问题,并应该选择事件驱动的方法。在基于线程的方法中,收银员/线程将与我们一起被卡住,直到我们的食物/资源准备好。而在事件驱动的方法中,收银员将我们发送到请求队列之外的某个地方,因此在等待食物时不会阻塞其他请求。 要扩展基于线程的阻塞,需要增加线程数。 对我来说,这似乎是不正确使用线程/线程池的借口。

是否可以使用IHttpAsyncHandler来正确处理它?ASP.Net接收请求,使用线程池并运行处理程序(BeginProcessRequest),然后在其中使用回调加载文件/数据库。然后该线程应该自由地处理其他请求。一旦文件读取完成,线程池再次进入操作并执行剩余的响应。 对我来说并没有太大的区别,那么为什么这样做不具有可扩展性呢?

我知道基于线程的缺点之一是需要更多的内存。但是只有这些,您才能享受多核的好处。我怀疑Node.js并没有完全不使用任何线程/核心。

因此,仅基于事件驱动和基于线程的方法(不要提出“因为它是JavaScript和每个浏览器...”的论点),是否可以指出使用Node.js而不是现有技术的实际好处?

问题很长。谢谢:)


你可能会觉得这很有趣:http://ayende.com/blog/72705/node-cs - alun
4个回答

68

首先,Node.js不是多线程的。这很重要。设计能够在线程环境中完美运行的程序需要非常有才华的程序员。线程很难。

你必须成为一个来维护一个没有被正确设计的线程化项目。在非常大的项目中只会有太多的问题难以避免。

其次,整个平台的设计初衷就是异步运行。你见过每个IO交互都是异步的ASP.NET项目吗?简单地说,ASP.NET并不是为事件驱动而设计的。

接着,由于我们每个打开的连接都有一个线程,加上整个扩展问题,就会导致内存占用问题。我可能错了,但我不知道如何避免在ASP.NET中为每个连接创建一个新线程。

另一个问题是当Node.js请求没有被使用或等待IO时它是空闲的。另一方面,C#线程休眠。现在,这些线程可以休眠的数量是有限制的。在Node.js中,你可以轻松地在同一开发机上并行处理10k个客户端。你试着在同一开发机上并行处理10k个线程。

JavaScript本身作为语言使异步编码更容易。如果你仍在使用C# 2.0,那么异步语法就是真正的痛苦。很多开发人员会因为你到处定义Action <>和Function<>并使用回调而变得混乱。一个以事件方式编写的ASP.NET项目对于普通的ASP.NET开发人员来说只是难以维护。

至于线程和核心。Node.js是单线程的,并通过创建多个节点进程来进行扩展。如果你有16个核心,那么你可以运行16个node.js服务器实例,并在其前面放置一个单一的Node.js负载平衡器。(如果需要,可以使用nginx负载平衡器)。

这全部都是从最低层次上设计到平台上的。这不是在后来添加的功能。

其他优点

Node.js不仅仅是以上内容。以上只是说明为什么Node.js处理事件循环的方式比使用ASP.NET异步能力更好。

  • 性能方面,它非常快。
  • Node.js最大的优点之一是其低级API。你有很多控制权。
  • 整个HTTP服务器直接集成到你的代码中,而不是外包给IIS。
  • 你可以进行整个nginx与Apache的比较。
  • 整个C10K挑战对Node来说处理得很好,但对IIS则不行。
  • AJAX和JSON通信感觉自然且容易。
  • 实时通信是Node.js的一大亮点。它就是为此而生。
  • 与基于文档的nosql数据库相匹配。
  • 也可以运行TCP服务器。可以进行文件写入访问,可以在服务器上运行任何Unix控制台命令。
  • 使用JavaScript查询数据库,例如CouchDB和map/reduce。客户端也可以用JavaScript编写。在开发Web堆栈时没有上下文切换。
  • 富集的社区驱动开源模块。Node.js中的所有东西都是开源的。
  • 占用空间小,几乎没有依赖项。你可以自己构建node.js源码。

Node.js的缺点

它很难。它还很年轻。作为一个有经验的JavaScript开发者,我在使用Node.js编写网站时感到困难,只是因为它低级特性以及我所拥有的控制水平。它感觉就像C语言。有很多灵活性和强大的功能,但也可能用来伤害我。

API并不稳定。它正在快速变化中。我可以想象,在5年内完全重写一个大型网站,因为Node.js将在那时被改变了许多。这是可做的,你只需知道维护Node.js网站不便宜。

进一步阅读

理解 Node.js 的事件循环

深入了解 Node.js

Node.js 指南


17
ASP.NET不会在每个请求上创建线程,这就是线程池的作用。 - Hendry Ten
8
如果需要,即使是aspx页面,每个IO操作都可以是异步的。 - Hendry Ten
5
如果你现在同时有100个客户端连接,那么就会有100个线程或者至少n个线程和100-n个客户端在缓冲区等待。异步IO是正确的方式。实现异步IO的一种方法是事件驱动。可以观看这个视频 - Raynos
4
在node.js中,这些将会在队列中吗?并不一定需要100个线程。这就是线程的合适异步用法。只有几个线程等待请求,其他更多的线程用于工作/调用异步或处理回调等。 - Hendry Ten
12
“Threads are just hard.”笑死我了。 “性能很好,非常快。” 笑死我了。作为一名技艺高超的JavaScript开发者,我在使用Node.js编写网站时面临困难,因为它具有低级特性和我所拥有的控制水平,感觉就像C语言一样。 LOL。这个回答确实有些幽默感 :) - kralyk
显示剩余17条评论

28
关于node.js与ASP.Net和异步编程之间的误解很多。你可以在ASP.NET中进行非阻塞IO。大多数人不知道当你使用.NET 2.0及以上版本的begin/end模式进行Web服务调用或其他I/O绑定操作时,.Net框架在底层使用Windows iocompletion ports。IO完成端口是Windows操作系统支持非阻塞IO的方式,因此应用程序线程在IO操作完成时会被释放。有趣的是,通过Cygwin,node.js在Windows上使用了较不理想的非阻塞IO实现。新的Windows版本已经在路线图上,将使用IO完成端口并得到Microsoft的指导。在那时,在底层没有任何区别。
在ADO.NET中也可以进行非阻塞数据库调用,但要注意ORM工具,如NHibernate和Entity Framework,它们仍然是非常同步的。
同步IO(阻塞)使控制流更加清晰,并因此变得流行。计算机环境是多线程的原因只是表面上的。它更普遍地与时间共享和利用多个CPU相关。

只有一个线程可能会在长时间操作期间导致饥饿,这可能与IO和复杂计算有关。因此,即使在利用非阻塞IO时,经验法则是每个核心一个线程,人们仍应考虑足够的线程池大小,以便如果存在更复杂的操作,则简单请求不会被饥饿。多个线程也可以轻松地将复杂操作分割到多个CPU中。像node.js这样的单线程环境只能通过更多的进程和消息传递来协调动作来利用多核处理器。

我个人还没有看到任何引入额外技术(如node.js)的充分理由。但是,可能有很好的原因,但在我看来,这与通过非阻塞IO为大量连接提供服务的要求有很少关系,因为ASP.NET也可以做到这一点。

顺便说一下,tamejs可以帮助使您的nodejs代码更易读,类似于即将推出的新的.Net Async CTP。


是的,我认为Node社区声称有巨大的性能提升并没有什么好处。它真正的优势在于使小团队能够快速开发而不会牺牲性能或限制选项。如果你喜欢JavaScript,请点赞! - Erik Reppen

17

Node.js和ASP.NET社区之间的文化差异很明显,这一点很容易被低估。当然,IHttpAsyncHandler是存在的,自从.NET 1.0以来就一直存在,所以它可能甚至很好,但是与.NET相比,所有关于Node.js的代码和讨论都是关于异步I/O的,这在.NET中显然不是这样。想要使用LINQ To SQL?你有点可以,但只是有点。想记录日志?也许"CSharp DotNet Logger"会有用,也许。

因此,是的,IHttpAsyncHandler是存在的,如果你非常小心地编写事件驱动的Web服务,也许能够避免一些阻塞I/O的问题,但我并没有真正的印象很多人在使用它(而且它肯定不是编写ASP.NET应用程序的主要方式)。相比之下,Node.js则专注于事件驱动的I/O,所有的代码示例、所有的库都是这种方式,并且这是人们使用它的唯一方式。因此,如果你打算赌哪个事件驱动的I/O模型实际上可以完全运行,那么Node.js可能是一个不错的选择。


2
我认为你对异步IO过于严肃了。它很酷,有时可以加快速度,但它总是会让事情变得更加复杂。我认为你应该仔细研究一下.Net 4.5... - AK_
@AK_ 但是异步和事件驱动对于有大量UI经验的JS开发人员来说都是很自然的。在文化上最大的区别在于,相较于特性列表长度,更偏好语言、实现和典型库/工具设计的简洁主义。这种偏好源于多平台编写代码多年的经验,这些平台并不一定都同意你的代码实际含义,我认为这种偏好将继续为有经验的JS开发人员在Node中服务。JS的可塑性和其一流函数的特点意味着,在强大的JS开发人员手中,异步编程需要的代码量要少得多。 - Erik Reppen

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接