让我们说我开始使用像这样的Akka Persistence系统:
case class MyMessage(x: Int)
class MyProcessor extends Processor {
def receive = {
case Persistent(m @ MyMessage) => m.x
//...
}
}
然后有一天我将其改为:
case class MyMessage(x: Int, y: Int)
class MyProcessor extends Processor {
def receive = {
case Persistent(m @ MyMessage) => m.x + m.y
//...
}
}
在部署新系统后,当MyProcessor
的实例尝试恢复其状态时,日志消息将属于前一个案例类。因为它期望后一种类型,它将抛出OnReplayFailure
,使处理器无用。问题是:如果我们假设缺席y
可以等于0
(或者其他什么),那么最好的做法是克服这个问题吗?例如,在恢复时可能使用implicit
从前一条消息转换为后一条消息?
答案 0 :(得分:1)
Akka默认使用Java序列化,并表示对于长期项目,我们应该使用适当的替代方案。这是因为Java序列化很难随着时间的推移而发展。 Akka建议使用Google Protocol Buffers,Apache Thrift或Apache Avro。
例如,对于Google协议缓冲区,在您的情况下,您将编写如下内容:
if (p.hasY) p.getY else 0
Akka在一篇很好的文章中解释了所有这些(不可否认,它不具备谷歌能力):
http://doc.akka.io/docs/akka/current/scala/persistence-schema-evolution.html
甚至解释了为现有消息类型添加新字段的特定用例:
http://doc.akka.io/docs/akka/current/scala/persistence-schema-evolution.html#Add_fields
Akka文档推荐用于比较不同序列化工具包的博客文章:
http://martin.kleppmann.com/2012/12/05/schema-evolution-in-avro-protocol-buffers-thrift.html