75

我在 web 编程方面不是很有经验,实际上我还没有在 Node.js 中编写任何代码,只是对事件驱动的方法感到好奇。看起来确实不错。

这篇文章解释了当我们使用基于线程的方法来处理请求时可能发生的一些坏事,应该选择事件驱动的方法。在基于线程的情况下,收银员/线程一直在我们身边,直到我们的食物/资源准备好。在事件驱动中,收银员将我们发送到请求队列之外的某个位置,这样我们就不会在等待食物时阻止其他请求。要基于阻塞线程扩展,您需要增加线程数。对我来说,这似乎是不正确使用线程/线程池的一个不好的借口。

不能使用 IHttpAsyncHandler 正确处理吗?ASP.Net 接收请求,使用 ThreadPool 并运行处理程序 (BeginProcessRequest),然后在其中我们使用回调加载文件/数据库。然后该线程应该可以自由处理其他请求。一旦文件读取完成,ThreadPool 将再次被调用并执行剩余的响应。对我来说并没有太大的不同,那为什么不那么可扩展呢?

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

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

那是一个很长的问题。谢谢 :)

4

4 回答 4

68

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

你必须是才能维护一个设计不正确的线程项目。在非常大的项目中,有很多问题是难以避免的。

其次,整个平台被设计为异步运行。您是否见过任何 ASP.NET 项目,其中每个 IO 交互都是异步的?简而言之,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 挑战由节点很好地处理,但不是由 IIS
  • AJAX 和 JSON 通信让人感觉自然而轻松。
  • 实时通信是 Node.js 的一大优点。它是为此而生的。
  • 与基于文档的 nosql 数据库配合得很好。
  • 也可以运行 TCP 服务器。可以进行文件写入访问,可以在服务器上运行任何 unix 控制台命令。
  • 例如,您可以使用 CouchDB 和 map/reduce 在 javascript 中查询数据库。你用 JavaScript 编写你的客户端。在您的 Web 堆栈上开发时没有上下文切换。
  • 丰富的社区驱动的开源模块。node.js 中的所有内容都是开源的。
  • 占用空间小,几乎没有依赖关系。您可以自己构建 node.js 源代码。

Node.js 的缺点

这个很难(硬。它很年轻。作为一名熟练的JavaScript 开发人员,我在用 Node.js 编写网站时遇到了困难,因为它的低级性质和我拥有的控制级别。感觉就像 C 语言一样。有很大的灵活性和力量,可以为我使用或吊死我。

API 未冻结。它正在迅速变化。我可以想象必须在 5 年内完全重写一个大型网站,因为届时 Node.js 将发生变化。这是可行的,你只需要知道 node.js 网站的维护并不便宜。

进一步阅读

http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/

http://blip.tv/file/2899135

http://nodeguide.com/

于 2011-04-08T18:29:05.713 回答
28

关于 node.js 与 ASP.Net 和异步编程有很多误解。您可以在 ASP.NET 中进行非阻塞 IO。大多数人不知道,当您使用 .Net 2.0 及更高版本中的开始/结束模式进行 Web 服务调用或其他 I/O 绑定操作时, .Net 框架在下面使用 Windows iocompletion 端口。IO 完成端口是 Windows 操作系统支持非阻塞 IO 的方式,以便释放 IO 操作完成的应用线程。有趣的是,node.js 通过 Cygwin 在 Windows 中使用了一种不太理想的非阻塞 IO 实现。一个新的 Windows 版本正在路线图中,在微软的指导下,它将使用 IO 完成端口。在这一点上,下面没有区别。

也可以在 ADO.NET 中进行非阻塞数据库调用,但要注意 ORM 工具,例如 NHibernate 和 Entity Framework。它们仍然非常同步。

同步 IO(阻塞)使控制流更加清晰,因此变得流行。计算机环境是多线程的原因只是表面上与此有关。它更普遍地与多 CPU 的时间共享和利用有关。

在冗长的操作中,只有一个线程会导致饥饿,这可能与 IO 和复杂的计算有关。所以,即使经验法则是一个线程公关。核心在使用非阻塞 IO 时,仍然应该考虑足够的线程池大小,这样简单的请求就不会被更复杂的操作(如果存在)饿死。多线程还允许在多个 CPU 之间轻松拆分复杂的操作。像 node.js 这样的单线程环境只能通过更多的进程和消息传递来使用多核处理器来协调动作。

我个人还没有看到任何令人信服的论据来引入诸如 node.js 之类的附加技术。但是,可能有充分的理由,但在我看来,它们与通过非阻塞 IO 服务大量连接几乎没有关系,因为这也可以通过 ASP.NET 完成。

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

于 2011-08-02T23:07:00.620 回答
17

很容易低估Node.js 和 ASP.NET 社区之间的文化差异。当然,IHttpAsyncHandler存在,并且从 .NET 1.0 开始就已经存在,所以它甚至可能很好,但是围绕 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 可能是首选。

于 2011-04-08T18:36:22.980 回答
1

根据当前时代的技术改进和阅读下面的链接,我可以说,这是专业知识和根据重要的特定场景选择完美组合的问题。NodeJS 正在变得成熟,而 ASP.NET 方面我们有 ASP.NET MVC、WebAPI 和 SignalR 等来让事情变得更好。

Node.js 与 .Net 的性能对比

http://www.salmanq.com/blog/net-and-node-js-performance-comparison/2013/03/

http://www.hanselman.com/blog/InstallingAndRunningNodejsApplicationsWithinIISOnWindowsAreYouMad.aspx

谢谢。

于 2013-07-01T14:11:45.413 回答