什么样的设计决策会支持 Scala 的 Actor 而不是 JMS?

Posted

技术标签:

【中文标题】什么样的设计决策会支持 Scala 的 Actor 而不是 JMS?【英文标题】:What design decisions would favour Scala's Actors instead of JMS? 【发布时间】:2011-06-06 14:30:36 【问题描述】:

使用 Scala Actors 而不是 JMS 有什么区别?

例如,从性能和可扩展性的角度来看,与 JMS 相比,Scala Actor 模型增加了什么?在哪些情况下使用 Actors 而不是 JMS 更有意义,即 Actors 解决了哪些 JMS 无法解决的问题?

【问题讨论】:

【参考方案1】:

JMS 和 Scala 角色在理论上有相似之处,但并不认为它们必须在架构上解决相同的问题。 Actor 旨在成为共享内存并发的轻量级替代方案,其中竞争和死锁通常更难意外创建。 JMS 是一个复杂的 API,旨在跨越直接消息传递、发布/订阅、事务、EJB 集成等。

与参与者最接近的 JMS 是消息驱动的 bean,它由非持久性、非事务性、非发布/订阅队列支持。我称之为“简单的 JMS bean”。

现在,回答你的问题。

性能是一个很难谈论的事情,因为 JMS 是一种规范而不是一种实现。尽管如此,当使用简单的 JMS bean 时,我希望性能大致相似,并且可能在时间和内存方面对演员有一点优势。当您向 JMS 添加功能(例如 pub/sub、事务等)时,性能自然会进一步下降,但是您正在尝试将苹果与橙子进行比较。

至于可伸缩性,简单的 JMS bean 的伸缩方式应该与参与者的伸缩方式几乎完全相同。将事务添加到 JMS 组合中自然会在一定程度上损害可伸缩性,具体取决于事务的范围。

更广泛的问题是演员可以做什么而 JMS 不能。好吧,如果没有内置的 pub sub 或 transactions,actor 似乎会从 JMS 中减去 - 总的来说这是真的。但事情是这样的:actor 需要的代码非常少,以至于我可以很高兴地将它们用于非常细粒度的并发。在普通的 Java 代码中,我可能会说“我不想搞砸 JMS 及其依赖项或它需要的代码等,所以我只会产生一个线程,使用一个锁,并共享一个数据结构。”对于 Scala 演员,我更有可能说:“我会挑选一个演员然后继续前进。”

在设计上也存在哲学差异。 Actor 有一个简单的、内置的主管层次结构概念。 Actors 通常用于“让它崩溃”的设计。如果一个演员因某种原因死亡,那么另一个演员负责决定如何处理它,例如重新启动该演员,杀死一堆演员并重新启动所有演员,或者杀死一堆演员和自己,以便其他演员可以处理问题。这种东西可以附加到 JMS 上,但它不是 API 的核心,必须以某种方式在外部进行管理。

顺便说一句,有关更多进入 JMS 涵盖的领域的 Scala 演员库,请参阅 Akka。 Akka 还为许多常见的 Actor 层次结构策略带来了一种声明式方法。

【讨论】:

我想我已经涵盖了。我更新了最后几段以澄清这一点,我还解释了一些关于演员层次结构的内容。 克里斯蒂安,不完全是。 Akka actor 通常比 Scala actor 更轻量级。但是,它们的 API 和配置设置稍微复杂一些。当延迟/吞吐量不是问题时(例如,用于生成工作任务),我使用 Scala actor,而当它们存在时,或者我需要监督时,我使用 Akka actor。 我认为这里也值得注意的是,一般来说,JMS 实现需要一个外部代理,Akka/Actors 能够在没有外部代理的情况下运行。当然,如果您想要跨进程/主机消息传递,您将选择适当的。 span>

以上是关于什么样的设计决策会支持 Scala 的 Actor 而不是 JMS?的主要内容,如果未能解决你的问题,请参考以下文章

scala当中的Actor并发编程

Scala并发编程reactloop代码实战具体解释

Scala 中的多个 Actor 实现有何不同?

不同的 Scala Actor 实现概述

《Scala 语言》Scala 中的 Actor 编程

Scala并发框架Akka原理详解