Akka的Hello World(三)Actor失败处理

父母和孩子在整个生命周期中都是相互联系的。每当一个actor失败(抛出异常或未处理的异常)时,它会暂时中止。如前所述,失败信息将传播到父级,然后父级决定如何处理子actor引起的异常。通过这种方式,父母可以担任孩子的监督员。默认的策略是停止并重新启动孩子。如果不更改默认策略,则所有失败都会导致重新启动。

让我们在一个简单的实验中观察默认策略。

(一)创建maven工程,添加依赖

    
        
            com.typesafe.akka
            akka-actor_2.12
            2.5.22
        
    

Akka的Hello World(三)Actor失败处理_第1张图片

(二)编写代码

import akka.actor.AbstractActor;
import akka.actor.AbstractActor.Receive;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;

class SupervisingActor extends AbstractActor {
    static Props props() {
        return Props.create(SupervisingActor.class, SupervisingActor::new);
    }

    ActorRef child = getContext().actorOf(SupervisedActor.props(), "supervised-actor");

    @Override
    public Receive createReceive() {
        return receiveBuilder()
                .matchEquals(
                        "failChild",
                        f -> {
                            child.tell("fail", getSelf());
                        })
                .build();
    }
}

class SupervisedActor extends AbstractActor {
    static Props props() {
        return Props.create(SupervisedActor.class, SupervisedActor::new);
    }

    @Override
    public void preStart() {
        System.out.println("supervised actor started");
    }

    @Override
    public void postStop() {
        System.out.println("supervised actor stopped");
    }

    @Override
    public Receive createReceive() {
        return receiveBuilder()
                .matchEquals(
                        "fail",
                        f -> {
                            System.out.println("supervised actor fails now");
                            throw new Exception("I failed!");
                        })
                .build();
    }
}
public class ActorHierarchyExperiments {
    public static void main(String[] args) throws java.io.IOException {
        ActorSystem system = ActorSystem.create("testSystem");
        ActorRef supervisingActor = system.actorOf(SupervisingActor.props(), "supervising-actor");
        supervisingActor.tell("failChild", ActorRef.noSender());
    }
}

(三)运行测试 

 Akka的Hello World(三)Actor失败处理_第2张图片

(四)分析

我们看到失败后,受监督的Actor被停止并立即重新启动。我们还看到一个日志条目,报告了处理的异常,在本例中是我们的测试异常。在这个例子中,我们使用preStart()和postStop(),它们的默认重新启动之前和结束之后被调用,所以我们不能从Actor内部区分首次启动或重启。这通常正确的做法是,重新启动的目的是将Actor设置为已知良好状态,这通常意味着一个干净的起始阶段。实际发生的是,虽然在preRestart()和postRestart()方法被调用,如果不重写,默认情况下分别委托postStop()和preStart()。您可以尝试覆盖这些其他方法,并查看输出如何更改。 

你可能感兴趣的:(Akka)