【问题标题】:Does actor state have to be serializable?演员状态是否必须可序列化?
【发布时间】:2015-01-03 16:17:18
【问题描述】:
class MyActor(val service1: MyService1, val service2: MyService2) extends Actor {
  ...
}

我计划通过 akka-cluster 扩展在集群中的路由器后面使用我的 actor。一些父演员将创建这些演员的“池”。 因此,这个“池”的创建将类似于:

context.actorOf(Props(classOf[MyActor], service1, service2), "myActor")

在部署部分的配置文件中,我将为这个actor指定路由器选项。

但我想要让它工作 MyService1 和 MyService2 必须是可序列化的,不是吗? 也许这个要求不直接与演员有关,而是与它的道具有关?

【问题讨论】:

    标签: scala serialization akka


    【解决方案1】:

    如果您尝试过使用集群分片扩展(它建立在集群之上),您就会意识到,当您创建远程参与者时,您在某种程度上丧失了对他们的控制程度创建。所以,一般来说,如果你想要 props,你需要它们是可序列化的。

    如果你想查看你的actors/props/messages是否可序列化,你可以进入akka的配置并启用这两个标志(更多信息here):

    akka {
      actor {
        serialize-messages = on
        serialize-creators = on
      }
    }
    

    我宁愿向您建议一种不同的方法,即使您必须使用集群分片(在参与者构造函数中不能有参数)也可以使用:通过消息初始化。

    你的演员会变成这样:

    class MyActor extends Actor {
      var service1: Option[MyService1] = None
      var service2: Option[MyService2] = None
    
      override def receive = {
        case Init(s1, s2) => service1 = Some(s1); service2 = Some(s2)
      }
    }
    

    请注意,在这种情况下,除非您通过事件源或快照来持久化您的演员,否则您需要在演员启动时重新发送初始化消息(当它死亡并再次启动或移动到另一台机器)。但通常你会使用持久性,这没什么大不了的。你还可以在你的actor中添加一个消息队列来保存在你收到init消息之前收到的所有“action”消息,然后在你收到你的init消息后提供它们。

    【讨论】:

    • 我知道这有点晚了,但是为了避免使用 Option[T] 服务,您可以使用状态机行为doc.akka.io/docs/akka/snapshot/scala/… 在收到初始化消息后将您的服务传递到成为状态.
    猜你喜欢
    • 2015-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 2019-04-23
    • 1970-01-01
    相关资源
    最近更新 更多