哪些设计决策会偏向 Scala 的 Actor 而不是 JMS?

2022-08-31 12:16:50

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

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


答案 1

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

与参与者最接近的 JMS 是消息驱动的 Bean,它由非持久性、非事务性、非 pub/sub 队列提供支持。我称之为“简单的JMS豆”。

现在,回答您的问题。

性能是一件很难谈论的事情,因为JMS是一个规范而不是一个实现。在使用简单的JMS bean时,我希望性能大致相似,在时间和内存上可能与演员有点优势。当您向JMS添加功能(例如发布/订阅,事务等)时,性能自然会进一步下降,但随后您正试图将苹果与橙子进行比较。

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

一个更广泛的问题是,参与者做了什么,而JMS做不到的事情。好吧,如果没有内置的酒吧子或交易,演员似乎会从JMS中减去 - 从广义上讲,这是真的。但事情是这样的:actor需要的代码太少了,我可以愉快地将它们用于非常细粒度的并发。在普通的Java代码中,我可能会说:“我不想搞砸JMS及其依赖项或它需要的代码等,所以我只会生成一个线程,使用锁,并共享数据结构。对于Scala的演员,我更有可能说“我会鞭打一个演员,然后继续前进。

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

顺便说一句,对于一个Scala actor库,它可以更多地进入JMS所涵盖的领域,请参阅Akka。Akka还为许多常见的参与者层次结构策略带来了声明性方法。


答案 2

推荐