【问题标题】:Akka typed actors in JavaJava中的Akka类型化actor
【发布时间】:2015-04-15 11:30:00
【问题描述】:

我不明白为什么不在Akka 中使用TypedActors。使用反射(嗯..instanceof)来弥补 Java 中模式匹配的不足是相当难看的。
据我了解,TypedActors 应该就像您的软件的“Akka 世界”和“非 Akka 世界”之间的一扇门。但是我们为什么不直接抛出所有 OO 原则并使用反射!
为什么你不想使用一个演员并确切地知道它应该响应什么?或者为了 Akka 保持 Actor 模型,为什么不创建一个使用双重调度的消息层次结构以激活 Actor 中的正确方法(我知道您不应该将 Actors 作为参数传递并使用 ActorRef 代替)。 免责声明:我是Akka 和这个模型的新手,而且我还没有使用Akka 编写过任何代码,但是仅仅阅读文档就让我很头疼。

【问题讨论】:

标签: java akka


【解决方案1】:

开始之前:问题是关于deprecated "typed actors" module。很快就会被 akka-typed 取代,这是一个非常出色的解决方案,它避免了下面解释的缺点 - 如果您对类型化的 actor 感兴趣,请查看 akka-typed!


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

首先,它们从未被设计为工具包的核心。它们建立在 Akka 提供的消息传递基础设施之上。请注意,由于该消息传递基础架构,我们能够实现位置透明性和 Akka 众所周知的性能。他们大量使用反射和 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 中,并通过sbt-jmh 插件使用OpenJDK JMH 工具运行。)

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

最后,你基本上失去了一个主要的 Actor 能力。 Actor 可以执行的 3 种规范操作是 1) 发送消息 2) 启动子 Actor 3) 根据收到的消息改变自己的行为(请参阅 Carl Hewitt 在 Actor Model 上的原始论文)。第三种能力用于对状态机进行精美建模。例如,您可以说(在普通的 akka 演员中)become(active) 然后become(allowOnlyPrivileged),在receive 实现之间切换 - 使有限状态机实现(我们也有一个DSL for FSMs)成为工作的乐趣。您无法在 JDK 代理类型的 Actor 中很好地表达这一点,因为您无法更改公开的方法集。一旦您开始使用状态机进行思考和建模,这是一个主要的缺点。

新希望(第 1 集):请查看由 Roland Kuhn 撰写的 the upcoming akka-typed module(预览版将很快包含在 2.4 版本中),我很确定你我会喜欢你会在类型安全方面找到的东西。而且,该实现最终将比当前的无类型参与者更快(这里省略 impl 细节,因为答案已经很长了 - 简短版本:基本上我们将通过新实现删除大量分配)。

我希望您会喜欢这个详尽的答案。随时在 cmets 或akka-user(我们的官方邮件列表)中提出后续问题。哈金快乐!

【讨论】:

  • 首先...感谢您的出色回答。即使它更长,我也会继续阅读。其次,我希望看到该页面的 Java 版本 =)。我不是 Scala 开发人员
  • 你的意思是akka类型的项目?我们还没有将它移植到 java,但它会是(!),我认为它可能包含在 2.4 中......我们拭目以待。 :-)
  • 很好的解释,但对于一些使用类型化的 Actor 为低级开发人员提供反应式系统的框架,即使不知道 Akka 也是一个很好的优势。我也永远不会考虑将类型化的 Actor 用作实验开发人员,但是对于一群没有动力的开发人员来说,他们不想学习 Akka 并且只是呆在 confrot zone 中,这是一个很大的优势,即使他们不知道堆栈,也可以为他们提供这些功能跨度>
【解决方案2】:

Typed Actors 为您提供在您的域中定义的静态契约——您可以命名它们的消息(将被委托给底层实现并异步执行)在您的域中有意义的操作,避免使用您的反思(TypedActors 在后台使用 JDK 代理,因此仍然会进行反思,您不必担心它,并且您可以根据传递给活动对象/类型的参数进行类型检查actor 及其返回类型。documention 对此非常清楚,但我知道对于那些刚接触基于 actor 的并发的人来说,其他示例总是有帮助的,所以如果您仍然对区别。

【讨论】:

  • 感谢您的回答。我只是对文档中介绍的最佳实践感到困惑。我不会实现一个适用于所有可能消息的软件。除此之外,Java 不能使用与 Scala 相同的模式匹配。那么为什么我不应该使用 TypedActors 而不是 UntypedActors 作为我的 Actors 呢?这对我来说毫无意义......
【解决方案3】:

但是你们是否意识到,你们有大量的公司,他们没有专业的开发人员,但是有一个庞大的基础设施可以根据我们的需要横向扩展,所以性能并不总是最好的。 ” 而是响应式、消息驱动、弹性和弹性,这要归功于我们拥有的类型化actor,被对 Akka 或 Reactive 一无所知的开发人员使用 编程。

不要误会我的意思,我每天都在使用纯 Akka,但是对于交付团队,我们有这个使用类型化 Actor 的框架,我们的消费者使用 POJO,而不知道他们是在响应式编码系统。这是一个很棒的功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-25
    • 2020-09-26
    • 2023-04-02
    • 2014-09-29
    • 1970-01-01
    • 2012-03-10
    相关资源
    最近更新 更多