Node.js 事件系统与 Akka 的 Actor 模式有何不同?

Posted

技术标签:

【中文标题】Node.js 事件系统与 Akka 的 Actor 模式有何不同?【英文标题】:How is Node.js evented system different than the actor pattern of Akka? 【发布时间】:2012-11-30 13:35:17 【问题描述】:

我已经与Node.js 合作了一段时间,并认为自己对 Java 非常擅长。但我刚刚发现了Akka,并立即对它的actor模式感兴趣(据我了解)。

现在,假设我的 javascript 技能与我的 Scala/Java 技能相当,我想专注于这两个系统的实用性。尤其是在网络服务方面。

据我了解,Node 擅长处理许多并发操作。我想一个用于资产管理系统的优秀 Node Web 服务将擅长处理同时提交更改的许多用户(在大型、高流量的应用程序中)。

但是在阅读了 Akka 中的演员之后,它似乎会在同一件事上表现出色。我喜欢将工作减少到一口大小的想法。另外,几年前我涉足 Erlang 并爱上了它使用的消息传递系统。

我从事许多处理复杂业务逻辑的应用程序,我认为是时候更深入地研究其中之一了。尤其是升级旧版 Struts 和 C# 应用程序。

无论如何,避免圣战,这两个系统有什么根本不同?似乎两者都朝着同一个目标。也许 Akka 的“自我修复”架构具有优势。

编辑

看来我的票数接近了。请不要将此问题视为“哪个更好,node 还是 akka?”。我正在寻找的是事件驱动库(如 Node)和基于 Actor 的库(如 Akka)的根本区别。

【问题讨论】:

我投票支持你向所有亲密的选民说“走开”:) @cbmeeks 请问你选择了什么?你的选择对你有什么影响? 【参考方案1】:

我不确定这是一个公平的比较。我将其更多地阅读为“基于事件的系统与参与者模型相比如何?”。 Nodejs 可以支持演员模型,就像 Scala 在 Akka 中所做的那样,或者 C# 在 Orleans 中所做的那样,事实上查看 nactor,似乎有人已经在尝试它。

至于事件系统与参与者模型的比较,我会让更聪明的人来描述它。关于 Actor 模型的几点简要说明:

Actor 模型是基于消息的 Actor 模型往往适用于分布式系统(集群)。当然,基于事件的系统可以是分布式的,但我认为参与者模型在分布式计算方面具有内置的分布。新请求可以路由到不同孤岛中的新参与者,但不确定这在基于事件的情况下如何工作。 Actor 模型支持失败,因为如果集群 1 出现故障,观察者通常可以找到不同的筒仓来完成工作

另外,请查看drama。它是另一个 nodejs actor 模型实现。

【讨论】:

尝试用nodejs搭建一个集群,你需要docker、kubernetees和构建分布式系统。还尝试在 nodejs 中设置另外 1 个核心的使用。 Akka 旨在处理这些问题。还有 nodejs 本身的成熟度,安全性,以及需要另一个框架来做某事的编码方式,这是 nodejs 本身不能用于大型分布式系统的一点,但至少只能以 MSA 的方式使用。反正我的意见。【参考方案2】:

没有详细介绍(我对 Node.js 的情况了解得太少),主要区别在于 Node.js 仅支持并发而不支持并行,而 Akka 支持两者。这两个系统都是完全事件驱动的,并且可以扩展到大的工作负载,但是在 Node.js 中缺乏并行性使得它变得困难(即并行性是通过启动多个节点并相应地分派请求来显式编码的;因此它在运行时不灵活) ,而在 Akka 中由于其可调的多线程执行程序而非常容易。给定小的独立工作单元(actor 调用),Akka 会自动为您并行执行。

另一个重要的区别是 Akka 包含一个以结构化方式处理故障的系统(通过让每个 Actor 由其父级监督,这是强制性的),而 Node.js 依赖于作者的约定将错误条件从回调传递到打回来。潜在的问题是异步系统不能使用基于同步堆栈的系统所采用的标准异常方法,因为在回调错误发生时,“调用”代码将转移到不同的任务上。将故障处理内置到系统中使得构建在该系统上的应用程序更有可能是健壮的。

以上内容并不详尽,我相信还有很多不同之处。

【讨论】:

如果我决定使用 AKKA 构建 RESTful Web 应用程序,您认为使用 PLAY-FRAMEWORK 还是 SPRAY 是最好的方法? 是的,两者都是不错的选择。 Play 适合作为一个框架,为您提供完全集成的开发体验,但这意味着 Play 将运行您的应用程序。如果您只想在 Akka 应用程序中嵌入一个薄 REST 层,则 Spray 会更好。请注意,Spray 将在未来几个月内成为 akka-http。 另外要指出的是,您可以使用 Scala/Java 获得静态类型语言的所有优点,并且在 javascript 中没有回调地狱。 Java/Scala 会比 javascript 更容易调试。 在与节点的并行性方面,应该提到您可以使用其cluster 核心API 在运行时分叉进程。它会做你所说的并行演员的意思。 在我看来,这个 2012 年的答案现在已经过时了,因为很多事情都发生了变化,尤其是 Node 之后。看看 Node 中的npmjs.com/package/webworker-threads web workers,你可以将阻塞的密集工作移到一个并行进程中(都在同一个 Node 进程中)。【参考方案3】:

我还没有使用 Akka,但它似乎类似于 erlang,但在 java 中。在 erlang 中,所有进程都像 Akka 中的演员,它们有邮箱,你可以在它们之间发送消息,你有监督者等等。

Node.js 使用协作并发。这意味着您在允许时具有并发性(例如,当您调用 io 操作或某些异步事件时)。当您进行一些长时间的操作(在长循环中计算某些内容)时,整个系统都会阻塞。

Erlang 使用抢先式任务切换。当您有长循环时,系统可以暂停它以运行其他操作并在一段时间后继续。对于大规模并发,如果您只执行短操作,Node.js 就很好。两者都支持数百万客户: http://blog.caustik.com/2012/08/19/node-js-w1m-concurrent-connections/ http://blog.whatsapp.com/index.php/2012/01/1-million-is-so-2011/

在 java 中你需要线程来做任何并发,否则你不能像 erlang 那样在函数内部暂停执行(实际上 erlang 在函数调用之间会暂停,但这对所有函数都有影响)。您可以在消息之间暂停执行。

【讨论】:

好的,假设我需要记录来自许多不同来源的日志文件。每次应用程序生成日志条目时,我还需要将该条目发送到另一个应用程序进行记录。我假设这可能是一个长时间运行的过程,因为应用程序可能有数据库超时、http 失败等。所以在这个例子中,写入数据库的挂起会导致我的整个 Node 系统挂起? AKKA 会遇到同样的问题,还是我只是没有得到相关性? 两者都不会受到影响,因为在这种情况下,数据库访问通常是异步实现的。但如果你设法让同步库做到这一点,它们都会冻结。 谢谢。我正在努力不把它变成node vs akka 辩论,但我有一个真正的问题需要解决。我会说我的 Java/JavaScript 技能非常接近,但我对 Node 的经验很少,而对 AKKA(或 Scala)则没有。但是我有几个应用程序(现在是内部的,但以后是外部的),人们正在寻找搜索这些大量日志的方法。由于隐私问题,无法使用外部第三方选项。似乎两者都可以处理这项工作。但我喜欢 AKKA 的信息传递,所以我可能会对此进行探索。此外,Java 比 JS 更受推崇。谢谢。 如果您需要搜索大量日志,请尝试查看 logstash 或 graylog2。

以上是关于Node.js 事件系统与 Akka 的 Actor 模式有何不同?的主要内容,如果未能解决你的问题,请参考以下文章

Java Akka Actor 和流

Actor初识

如何系统地学习Node.js?

Node.js自定义对象事件监听与发射

用Akka解决Spark+ElasticSearch实时计算平台的瓶颈

Akka(24): Stream:从外部系统控制数据流-control live stream from external system