Akka在Java中键入了演员

我不明白为什么不在Akka使用TypedActors 。 使用reflection(well .. instanceof )来弥补Java中缺少模式匹配是非常难看的。
据我所知, TypedActors应该像你的软件的“Akka world”和“Non Akka world”之间的门。 但是为什么我们不会抛弃所有的OO主体而只是使用reflection!
你为什么不想使用一个演员并确切地知道它应该响应什么? 或者为了保持演员模型的Akka,为什么不创建一个使用双调度的消息层次结构来激活actor中的正确方法(我知道你不应该将Actors作为参数传递并使用ActorRef代替)。
免责声明:我是Akka和这个模型的新手,我没有使用Akka编写一行代码,但只是阅读文档让我头疼。

在我们开始之前 :问题是关于已弃用的 “类型化演员”模块 。 这将很快被akka-typed取代,这是一个更优越的问题,这避免了以下解释的缺点 – 如果你对打字演员感兴趣,请看看akka-typed!


我将列举使用您引用的类型化actor实现的一些缺点。 请注意,我们刚刚合并了一个新的akka类型模块,它将类型安全带回了akka演员的世界。 为了这篇文章,我不会深入探讨开发打字版本是如此艰难的挑战的原因,让我们现在回答“为什么不使用(旧的)打字演员”的问题。

首先 ,它们从未被设计为工具包的核心。 它们建立在Akka提供的消息传递基础架构之上。 请注意,由于这个消息传递基础设施,我们能够实现位置透明度,以及Akka众所周知的性能。 他们大量使用reflection和JDK代理来转换消息发送方法和从消息发送方法转换。 这是非常昂贵的(时间方面),并且与普通的Akka Actors相比,将性能降低了大约10倍,参见下面的“乒乓”基准测试(使用两种风格实现,发送者告诉演员,演员回复 – 100.000次) :

 Unit = ops/ms Benchmark Mode Samples Mean Mean error Units TellPingPongBenchmark.tell_100000_msgs thrpt 20 119973619.810 79577253.299 ops/ms JdkProxyTypedActorTellPingPongBenchmark.tell_100000_msgs thrpt 20 16697718.988 406179.847 ops/ms Unit = us/op Benchmark Mode Samples Mean Mean error Units TellPingPongBenchmark.tell_100000_msgs sample 133647 1.223 0.916 us/op JdkProxyTypedActorTellPingPongBenchmark.tell_100000_msgs sample 222869 12.416 0.045 us/op 

(基准测试保存在akka / akka-bench-jmh中,并使用OpenJDK JMH工具,通过sbt-jmh插件运行。)

其次 ,使用方法来抽象分布式系统并不是一个很好的方法(哦,我记得RMI ……让我们不再去那里)。 使用这种“看起来像一种方法”会让你不再考虑消息丢失,重新排序以及分布式系统中可能发生的所有事情。 它还使用def getThing(id: Int): Thing类的签名鼓励(使其“ 容易做错def getThing(id: Int): Thing – 会生成阻塞代码 – 这对性能来说太可怕了! 你确实希望保持异步和响应 ,这就是为什么你在尝试与这些(基于代理的)类型的actor一起正常工作时最终会遇到大量的未来。

最后 ,你基本上失去了一个主要的Actorfunction 。 Actor可以执行的3个规范操作是1)发送消息2)启动子actor 3) 根据收到的消息改变它自己的行为 (参见Carl Hewitt关于Actor模型的原始论文)。 第三种function用于精美地建模状态机。 例如,您可以说(在简单的akka​​演员中) become(active)然后become(allowOnlyPrivileged) ,在receive实现之间切换 – 使得有限状态机实现(我们还有一个用于FSM的DSL )是一种乐趣。 您无法在JDK代理类型的actor中表达这一点,因为您无法更改公开方法的集合。 一旦您使用状态机进行思考和建模,这是一个重大的缺点。

新希望 (第1集):请看看即将推出的由Roland Kuhn撰写的akka类型模块 (预览很快将包含在2.4版本中),我很确定你会喜欢你会发现的安全明智。 此外,该实现最终将比当前的无类型演员更快(省略了impl细节,因为答案已经很久了 – 短版本:基本上我们将删除大量分配,这要归功于新的实现)。

我希望你会喜欢这个彻底的答案。 请随时在评论中或在akka-user上提出后续问题 – 我们的官方邮件列表。 快乐的哈金!

Typed Actors为您提供了根据域名定义的静态契约 – 您可以将其消息命名(将被委派给底层实施并异步执行)在您的域中有意义的操作,避免在您的域中使用reflectionpart(TypedActors使用JDK Proxies,所以仍然有reflection,你不必担心它,并且你根据传递给活动对象/类型的actor及其的参数获得类型检查返回类型。 文档非常清楚,但我知道对于那些基于actor的并发新手,其他的例子总是有帮助的,所以如果你仍然遇到麻烦,可以随意提出其他问题/评论。