• 容错
    • 邮箱
    • 重启策略
    • 升级策略
    • 停止策略
    • Dead letters
    • 主管设计

    容错

    Riker应用程序通过自我修复展现出容错行为。 这是通过监督实现的 - 每个Actor都有一个主管,负责确定如果Actor恐慌该怎么办。 在Riker中,Actor的父母是其主管。 这种“父母监督”是一种自然的契合,因为Actor系统是一个等级制度。

    Actor失败时,我们无法保证其状态未被破坏。 其父母有三种选择(策略):

    • 重启Actor
    • 升级到下一位主管
    • 停止Actor监督隔离故障和错误不会泄漏或级联。 相反,系统可以决定恢复到干净,工作状态或优雅停止的最佳方式。

    可以使用supervisor_strategy方法设置Actor应该用来监督其子女的监督策略:

    1. fn supervisor_strategy(&self) -> Strategy {
    2. Strategy::Stop
    3. }

    在这种情况下,如果子Actor失败,它会选择停止它。

    注意 : 如果未设置supervisor_strategy,则默认实现为Strategy :: Restart

    邮箱

    一个actor有自己的邮箱,邮件在邮件传递过程中排队。 当消息发送给actor时,它会被添加到actor的邮箱中,然后调度actor进行运行。 如果在处理消息期间,Actor失败(恐慌)消息仍然可以继续发送给Actor,因为邮箱是分开的。 这允许主管在不丢失消息的情况下处理故障 - 重新启动的actor将在重新启动后继续处理排队的消息。

    actor的邮箱继续存在,直到其actor停止或系统停止。

    重启策略

    1. fn supervisor_strategy(&self) -> Strategy {
    2. Strategy::Restart
    3. }

    重启策略尝试重新启动处于初始状态的actor,该状态被认为是未损坏的。

    接下来的顺序是:

    • Actor的邮箱被暂停。 可以接收消息,但不会处理它们
    • 失败的Actor的所有子Actor都被发送终止请求
    • 等待所有子Actor终止 - 非阻塞操作
    • 重启失败的actor
    • 恢复actor的邮箱和消息处理

    升级策略

    1. fn supervisor_strategy(&self) -> Strategy {
    2. Strategy::Escalate
    3. }

    升级策略将如何处理故障的决定移至主管的父母。 这可以通过使当前主管失败来实现,其父主将确定如何处理失败。

    接下来的顺序是:

    • Actor的邮箱被暂停。 可以接收消息,但不会处理它们
    • 主管升级并且其邮箱被挂起
    • 新主管决定采用哪种监督策略

    停止策略

    1. fn supervisor_strategy(&self) -> Strategy {
    2. Strategy::Stop
    3. }

    停止策略会停止失败的actor,从系统中删除它及其邮箱。

    Dead letters

    当一个actor被终止时,所有现有的ActorRef都会失效。 发送的消息(使用tell)会被重新路由到死信,这是一个专门的通道,向任何感兴趣的Actor发布无法传递的消息。 Riker有一个默认订阅者dl_logger,它只使用info!记录死信消息。

    主管设计

    良好的主管设计是设计弹性,容错系统的关键。 其核心是创建一个匹配消息流和依赖关系的actor层次结构。

    TODO提供良好的主管设计示例。

    接下来,我们将看到如何使用actor路径来消息actor,而无需actor参考并广播到actor层次结构的整个片段。