0

我已经从github下载了一个示例代码并运行 AtLeastOnceDelivery.sln 每次新运行它都会发送消息。如果我更改消息命名空间,它会显示以

Error loading snapshot [SnapshotMetadata<pid: delivery, seqNr: 0, timestamp: 2018/09/24>], remaining attempts: [0]

如果我可以清除持久性,希望它会接受然后更改命名空间并重新启动消息传递 ID。

4

1 回答 1

3

默认情况下,所有快照都作为文件直接存储./snapshots在应用程序的目录中,而事件存储在内存中。因此,您应该考虑将 akka.persistence 插件之一用于生产目的。

出现问题是因为您使用的 akka.net 默认序列化程序(专用于网络)对版本的容忍度不高 - 因此更改任何字段、它们的类型、类名或命名空间会使以前版本的类不可反序列化 - 并且在未来会有所改变。这也是为什么强烈建议不要使用默认序列化程序进行持久化的原因。

如何制作自定义 Akka.NET 序列化器

虽然有计划改进序列化器 API,但目前(Akka.NET v1.3.9),要制作自己的序列化器,您需要简单地从Akka.Serialization.Serializer类继承:

public sealed class MySerializer : Serializer
{
    public MySerializer(ExtendedActorSystem system) : base(system) { }
    public override int Identifier => /* globaly unique serializer id */;
    public override bool IncludeManifest => true;

    public override byte[] ToBinary(object obj)
    {
        // serialize object
    }

    public override object FromBinary(byte[] bytes, Type type)
    {
        // deserialize object 
    }
}

请记住,Identifier属性在集群范围内必须是唯一的 - 通常 akka.net 内部序列化程序使用低于 100 的值,因此最好使用更高的值。

如何绑定序列化程序以用于给定类型

按照惯例,Akka.NET 使用空接口来标记应该被序列化的消息类型。然后你可以设置你的 HOCON 配置来为给定的接口使用一个特定的序列化器:

akka.actor {
    serializers {
        my-serializer = ""MyNamespace.MySerializer, MyAssembly""
    }
    serialization-bindings {
        ""MyNamespace.MyInterface, MyAssembly"" = my-serializer
    }
}

接口在哪里MyInterface分配给您要序列化/反序列化的消息类型MySerializer

于 2018-09-29T14:49:12.970 回答