默认情况下 Akka.net 存储消息的位置?

By default where Akka.net stores its messages?

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

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

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

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

您的问题发生是因为您使用的是 akka.net 默认序列化器(专用于网络),它们不是很兼容版本 - 因此更改任何字段、它们的类型、class 名称或命名空间会使之前class 不可反序列化的版本 - 将来可能会发生变化。这也是为什么强烈建议不要使用默认序列化器来实现持久化

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

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

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 是分配给您想要 serialize/deserialize 和 MySerializer 的消息类型的接口。