Akka在Java中键入了演员 [英] Akka typed actors in Java

查看:231
本文介绍了Akka在Java中键入了演员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白为什么不在 Akka 中使用 TypedActors 。使用反射(好... instanceof )来弥补Java中缺少模式匹配是非常难看的。

据我所知, TypedActors 应该像你的软件的Akka world和Non Akka world之间的门。但是为什么我们不会抛出所有OO主体而只是使用反射!

为什么你不想使用一个演员并确切地知道它应该响应什么?或者为了保持演员模型的Akka,为什么不创建一个使用双调度的消息层次结构来激活actor中的正确方法(我知道你不应该将Actors作为参数传递并使用ActorRef)。 br>
免责声明:我是新来的 Akka 和这个模型,我还没有使用 Akka编写一行代码,但只是阅读文档让我头疼。

解决方案

在我们得到之前开始:问题是关于 已弃用打字演员模块。很快就会被 akka-typed 所取代采取问题,这避免了以下解释的缺点 - 如果你对打字演员感兴趣,请看看akka-typed!






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



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

 单位= ops / ms 
基准模式样本平均值误差单位
TellPingPongBenchmark.tell_100000_msgs thrpt 20 119973619.810 79577253.299 ops / ms
JdkProxyTypedActorTellPingPongBenchmark.tell_100000_msgs thrpt 20 16697718.988 406179.847 ops / ms

单位= us / op
基准模式样本均值平均误差单位
TellPingPongBenchmark.tell_100000_msgs样本133647 1.223 0.916 us / op
JdkProxyTypedActorTellPingPongBenchmark.tell_100000_msgs样本222869 12.416 0.045 us / op

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



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



最后,你基本上失去了一个主要的Actor功能。 Actor可以执行的3个规范操作是1)发送消息2)启动子actor 3)根据收到的消息改变它自己的行为(参见Carl Hewitt关于演员模型)。第三种功能用于精美地建模状态机。例如,您可以说(在普通的akka​​演员中)成为(活动)然后成为(allowOnlyPrivileged),切换在接收实现之间 - 进行有限状态机实现(我们还有一个用于FSM的DSL )使用起来很愉快。您无法在JDK代理类型的actor中表达这一点,因为您无法更改公开方法的集合。一旦你使用状态机进行思考和建模,这是一个主要的缺点。



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



我希望你会喜欢这个彻底的答案。欢迎在此处或 akka-user 上的评论中提出后续问题 - 我们的官方邮件列表。快乐的哈金!<​​/ p>

I don't understand why not to use TypedActors in Akka. Using reflection (well.. instanceof) to compensate for the lack of pattern matching in Java is quite ugly.
As far as I understand, TypedActors should be like a gate between the "Akka world" and the "Non Akka world" of your software. But why won't we just throw all OO principals and just use reflection!
Why wouldn't you want to use an actor and know exactly what it should respond to? Or for Akka's sake of keeping the actor model, why not create a message hierarchy that uses double-dispatch in order to activate the right method in the actor (and I know you shouldn't pass Actors as parameters and use ActorRef instead).
DISCLAIMER: I'm new to Akka and this model, and I haven't wrote a single line of code using Akka, but just reading the documentation is giving me a headache.

解决方案

Before we get started: The question is about the deprecated "typed actors" module. Which will soon be replaced with akka-typed, a far superior take on the problem, which avoids the below explained shortcomings - please do have a look at akka-typed if you're interested in typed actors!


I'll enumerate a number of downsides of using the typed actors implementation you refer to. Please do note however that we have just merged a new akka-typed module, which brings in type safety back to the world of akka actors. For the sake of this post, I will not go in depth into the reasons developing the typed version was such a tough challenge, let's for now answer the question of "why not use the (old) typed actors".

Firstly, they were never designed to be the core of the toolkit. They are built on top of the messaging infrastructure Akka provides. Please note that thanks to that messaging infrastructure we're able to achieve location transparency, and Akka's well known performance. They heavily use reflection and JDK proxies to translate to and from methods to message sends. This is very expensive (time wise), and downgrades the performance around 10-fold in contrast to plain Akka Actors, see below for a "ping pong" benchmark (implemented using both styles, sender tells to actor, actor replies - 100.000 times):

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

(Benchmarks are kept in akka/akka-bench-jmh and run using the OpenJDK JMH tool, via the sbt-jmh plugin.)

Secondly, using methods to abstract over distributed systems is just not a good way of going about it (oh, how I remember RMI... let's not go there again). Using such "looks like a method" makes you stop thinking about message loss, reordering and all the things which can and do happen in distributed systems. It also encourages (makes it "too easy to do the wrong thing") using signatures like def getThing(id: Int): Thing - which would generate blocking code - which is horrible for performance! You really do want to stay asynchronous and responsive, which is why you'd end up with loads of futures when trying to work properly with these (proxy based) typed actors.

Lastly, you basically lose one of the main Actor capabilities. The 3 canonical operations an Actor can perform are 1) send messages 2) start child actors 3) change it's own behaviour based on received messages (see Carl Hewitt's original paper on the Actor Model). The 3rd capability is used to beautifully model state machines. For example you can say (in plain akka actors) become(active) and then become(allowOnlyPrivileged), to switch between receive implementations - making finite state machine implementations (we also have a DSL for FSMs) a joy to work with. You can not express this nicely in JDK proxied typed actors, because you can not change the set of exposed methods. This is a major down side once you get into the thinking and modeling using state machines.

A New Hope (Episode 1): Please do have a look at the upcoming akka-typed module authored by Roland Kuhn (preview to be included in the 2.4 release soon), I'm pretty sure you'll like what you'll find there typesafety wise. And also, that implementation will eventually be even faster than the current untyped actors (omitting impl details here as the answer got pretty long already - short version: basically we'll remove a load of allocations thanks to the new implementation).

I hope you'll enjoy this thorough answer. Feel free to ask follow up questions in comments here or on akka-user - our official mailing list. Happy Hakking!

这篇关于Akka在Java中键入了演员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆