3

假设我从这样的 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在恢复时使用 an 从前者消息转换为后者?

4

1 回答 1

1

Akka 默认使用 Java 序列化,并表示对于长期项目,我们应该使用适当的替代方案。这是因为 Java 序列化很难随着时间的推移而发展。Akka 建议使用 Google Protocol Buffers、Apache Thrift 或 Apache Avro。

例如,使用 Google 协议缓冲区,在您的情况下,您将编写如下内容:

if (p.hasY) p.getY else 0

Akka 在一篇不错的文章中解释了所有这些(诚然,它不是很适合 Google):

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

于 2016-02-07T21:43:40.613 回答