有没有办法将用我自己的 类 键入的消息发送到 Akka 远程 actor?

Is there a way to send messages typed with my own classes to an Akka remote actor?

有没有办法将我自己输入的消息 类 发送到远程参与者?
例如,我希望能够在我的远程 actor 中收到这样的消息:

case myClass: MyClass => doSomething()

但是我得到一个错误 local class incompatible 因为 serialVersionUID 不同。

我发现发送 MyClass 类型消息的唯一方法是在 Json 中对其进行序列化。但是我必须 serialize/deserialize 它,而且问题更大,我没有一个干净的方法来接收两种类型的消息...

那么有没有办法向远程参与者发送强类型消息?如果不是,解决方法是什么?

来自 Serializable javadoc:

it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization.

因此,您应该在消息 类 中定义 serialVersionUID,如下所示:

@SerialVersionUID(42L)
class Message extends Serializable

你当然可以!

通过网络发送对象时,必须在一端将它们转换为字节,在另一端转换回对象。这叫做'Serialization'.

在 Akka 中,用于从一个 actor 系统传输到另一个 actor 系统的消息的序列化机制是高度可配置的:你不应该在你自己的 actor 中这样做,而是将它留给 Akka 的序列化基础设施(并根据你的喜好进行配置) ).

默认情况下,akka 使用内置的 'Java serialization'。这主要是可行的,但正如您所注意到的,对于在连接的两侧使用完全相同的 class 非常挑剔。而且,它不是特别快。您应该在日志记录中看到警告:

Using the default Java serializer for class [{}] which is not recommended because of performance implications. Use another serializer or disable this warning using the setting akka.actor.warn-about-java-serializer-usage

要解决您的问题,您可以:

  • 继续使用 Java 序列化,至少按照 Vitaliy 的回答中的描述固定 serialVersionUID
  • 切换到另一种序列化机制,例如 Protobuf。

如果您不太关心性能并且不希望做 'rolling upgrades'(您可能需要在同一消息的不同版本之间进行转换),Java 序列化是当然是最简单的。不过,了解它的局限性很重要。

可以在 http://doc.akka.io/docs/akka/current/scala/serialization.html#serialization-scala

找到有关如何配置 akka 序列化机制的更多文档