Akka监督策略

监督策略

Akka框架给予了我们足够的控制权。在Akka框架内,父Acotr可以对子Actor进行监督,监控Actor的行为是否有异常,监督策略可以分为两种:一种是OneForOneStrategy策略的监督(只会对出问题的子Actor进行处理),另外一种是AllForOneStrategy(会对出问题的子Acotr及它所有的兄弟都进行处理,适合各个Actor联系非常紧密的场景)策略的监督。

自定义的监督策略(supervisorStrategy)

定义一个OneForOneStrategy策略的监督。在这个监督策略中,运行Actor遇到错误后,在1分钟内进行3次重试,如果超过这个频率,就直接杀死Actor。当遇到ArithmeticException异常时(比如除以0的错误),继续指定这个Actor,不做任何处理;当遇到空指针时,进行重启。如果遇到IlleganArgumentException,直接停止Acotr

public class Supervisor extends UntypedAbstractActor {

    private static SupervisorStrategy strategy=
            new OneForOneStrategy(3, Duration.create(1, TimeUnit.MINUTES), //一分钟重试3次
                    new Function<Throwable, SupervisorStrategy.Directive>() {
                @Override
                public SupervisorStrategy.Directive apply(Throwable param) throws Exception {
                    if(param instanceof ArithmeticException){
                        System.out.println("meet ArithmeticException,just resume");
                        return SupervisorStrategy.resume();
                    }else if(param instanceof  NullPointerException){
                        System.out.println("meet NullPointerException,restart");
                        return SupervisorStrategy.restart();
                    }else if(param instanceof IllegalArgumentException){
                        return SupervisorStrategy.stop();
                    }else {
                        return SupervisorStrategy.escalate();
                    }
                }
            });

    public static SupervisorStrategy getStrategy() {
        return strategy;
    }

    @Override
    public void onReceive(Object message) throws Throwable {
        if(message instanceof Props){
            getContext().actorOf((Props) message,"restartActor");
        }else {
            unhandled(message);
        }
    }
}
public class RestartActor extends UntypedAbstractActor {

    public enum Msg{
        DONE,RESTART;
    }

    @Override
    public void preStart() throws Exception {
        System.out.println("preStart hashcode:"+this.hashCode());
    }

    @Override
    public void postStop() throws Exception {
        System.out.println("postStop hashcode:"+this.hashCode());
    }

    @Override
    public void postRestart(Throwable reason) throws Exception {
        super.postRestart(reason);
        System.out.println("postRestart hashcode:"+this.hashCode());
    }

    @Override
    public void preRestart(Throwable reason, Optional<Object> message) throws Exception {
        System.out.println("preSRestart hashcode:"+this.hashCode());
    }

    @Override
    public void onReceive(Object message) throws Throwable {
        if(message==Msg.DONE){
            getContext().stop(getSelf());
        }else if(message==Msg.RESTART){
            System.out.println("--------");
            double a=0/0;//resume
        }
        unhandled(message);
    }

    public static void main(String[] args) {
        ActorSystem system = ActorSystem.create("lifeStyle");
        ActorRef a=system.actorOf(Props.create(Supervisor.class),"supervisor");
        a.tell(Props.create(RestartActor.class),ActorRef.noSender());

        ActorSelection sel=system.actorSelection("akka://lifeStyle/user/supervisor/restartActor");

        for (int i = 0; i < 100; i++) {
            sel.tell(Msg.RESTART,ActorRef.noSender());
        }
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到preStart表示RestartActor正在初始化,它的hashcode是1276294244,当遇到空指针异常时,根据自定义的策略,导致它重启,在重启前调用了preRestart方法,此时hashcode还是1276294244,生成了新的实例之后,preStart的hashcode变成了99731995,并且返回postRestart方法的hashcode也是99731995,原有的实例因为重启而被挥手。这说明同一个Actor在系统工作始终未必能保持同一个实例。

选择Actor

在一个ActorSystem中,可能存在大量的Actor。如何才能有效地对大量Actor进行批量的管理和通信呢?Akka为我们提供了一个ActorSelection类,用来进行批量消息发送。

for(int i=0;i<WORDER_COUNT;i++){
	workers.add(system.actorOf(Props.create(MyWorker.class,i),"worker_"+i));
}

ActorSelection selection=getContext().actorSelection("/user/worker_*");
selection.tell(5,getSelf());

上述代码批量生成了大量Actor,我们要给这些worker发送消息,通过actorSelection()方法提供的选择通配符,可以得到代表所有满足条件的ActorSelection。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值