Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 克服Akka持久化中持久消息类的变化_Scala_Akka_Akka Persistence - Fatal编程技术网

Scala 克服Akka持久化中持久消息类的变化

Scala 克服Akka持久化中持久消息类的变化,scala,akka,akka-persistence,Scala,Akka,Akka Persistence,假设我从一个Akka持久性系统开始,如下所示: 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

假设我从一个Akka持久性系统开始,如下所示:

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
的实例尝试恢复其状态时,日志消息将属于前一个case类。因为它需要后一种类型,所以它将抛出一个OnReplayFailure
OnReplayFailure
,使处理器无用。问题是:如果我们假设一个缺席的
y
可以等于
0
(或其他什么),那么有没有克服这个问题的最佳实践?例如,可能在恢复时使用
隐式
将前一条消息转换为后一条消息?

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

例如,使用Google协议缓冲区,您可以编写如下内容:

if (p.hasY) p.getY else 0
Akka在一篇很好的文章中解释了这一切(无可否认,它不太适合谷歌搜索):

甚至解释了向现有消息类型添加新字段的特定用例:

Akka文档中的一篇博客文章建议对不同的序列化工具包进行比较:


如果没有消息丢失很重要,我会在切换后保留旧消息格式以实现向后兼容性(可能是另一个名称)一段时间(以便您可以将剩余的旧消息与新消息一起处理)。@Ashalynd在我的情况下,理论上,客户机可以在旧处理器失效数年后重新启动。保留旧代码以实现向后兼容性可能会变得非常臃肿。但如果没有其他办法,那就是解决办法了。这让事情变得很糟糕,但奥托,也许几年后这些信息就不再相关了。您还可以定义一个“全面”匹配器以实现向后兼容性。