我从github下载了示例代码,并运行AtLeastOnceDelivery.sln 每次新运行都会发送消息。而且,如果我更改消息名称空间,它会显示一个错误,开头为
Error loading snapshot [SnapshotMetadata<pid: delivery, seqNr: 0, timestamp: 2018/09/24>], remaining attempts: [0]
如果我希望清除持久性,它将接受然后更改名称空间并重新启动消息传递ID。
答案 0 :(得分:2)
默认情况下,所有快照都直接作为文件存储在应用程序的./snapshots
目录中,而事件存储在内存中。因此,出于生产目的,您应该考虑使用akka.persistence插件之一。
发生问题是因为您使用的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
进行序列化/反序列化的消息类型的接口。