我正在创建一个Akka远程处理项目,并且序列化有问题。我正在使用Akka的Artery远程处理,禁用Java序列化并使用Chill库进行序列化
假设有两个项目。第一个项目负责建设主演员。可以在远程位置创建所有子演员。因此,第二个项目位于远程位置,以便在那里启动儿童演员。
主要演员负责在偏远地区建立儿童演员。每个儿童演员都需要一个功能来完成其工作。因此,主演员将一个类(带有函数)放入道具中,并在远程位置创建带有该道具的孩子。 所有这些类扩展了在所有项目(第一和第二个项目)中都可用的特征。但是只有主人才具有特征的实现类(第一个项目)。让我向您展示一些代码(为了更好的理解而进行了简化):
这是第一个(主项目)和第二个(子项目)项目都可以使用的特征:
@SerialVersionUID(100L)
trait FuncTrait extends Serializable {
def doTheJob(input: Tuple): Tuple
}
仅在第一个(主)项目中实现:
class MyFunc(key: String) extends FuncTrait{
val rand = new Random()
override def doTheJob(input: Tuple): Tuple = {
val str = input.getString()
Tuple(key + " | Appending " + rand.nextInt() + " to + " str)
}
}
然后,主演员使用此道具创建孩子:
val myfunc: FuncTrait = new MyFunc("key")
Props(new ChildActor(myfunc))
但是即使在两个项目(远程位置)中都可以使用特征(FuncTrait),序列化也会因以下错误而失败(第二个/远程项目中的错误):
[kryo]无法使用kryo的ClassLoader加载com.mypackage.funcs.impl.MyFunc类。正在重试当前 [WARN] [05/17/2019 23:54:24.688] [RemoteSystem-akka.remote.default-remote-dispatcher-8] [Deserializer(akka:// RemoteSystem)]无法反序列化来自[akka:// MasterSystem@127.0.0.1:25520],序列号为[3],清单为[]。 java.lang.RuntimeException:无法序列化lambda
MyFunc类仅在第一个(主)项目中可用。
我认为仅将trait类放在所有项目中即可完成工作。但显然不是。似乎它也在第二个(子项)项目中寻找MyFunc(impl类),我认为仅将特征添加就够了
当我在第二个项目的确切程序包路径中放入相同的MyFunc(impl)类时,它可以反序列化它而没有任何问题。
我不确定是否可以做这样的事情。有什么办法可以使其工作?还是有更好的方法呢?还是应该在所有项目中都放入实现类(MyFunc)?顺便说一句,我也用Java序列化而不是chill测试了
这是我的序列化属性:
akka {
actor {
provider = remote
allow-java-serialization = off
serializers {
kryo = "com.twitter.chill.akka.AkkaSerializer"
}
serialization-bindings {
"java.io.Serializable" = kryo
"com.mypackage.tuple.Tuple" = kryo
}
}
remote {
artery {
enabled = on
transport = tcp
canonical.hostname = "127.0.0.1"
canonical.port = 25522
}
}
}
谢谢。