akka Circuit Breaker熔断

为了避免操作在异常情况下无限重试浪费资源,使用熔断让请求快速失败,避免浪费资源

                                                           circuit breaker状态图

closed状态: 正常情况熔断是关闭的,half-open状态中,如果调用成功进入closed状态。

open状态:达到预置条件后进开启熔断。

half-open状态: open状态后,达到预置时间会变为half-open.

 示例代码


public class CircuitDemo {

    public static void main(String[] args) {
        ActorSystem system = ActorSystem.create("sys");
        ActorRef ref = system.actorOf(Props.create(CircuitBreakerActor.class), "circuit");
        Scanner sc = new Scanner(System.in);
        while (true){
            System.out.println("input a num");
            int msg = sc.nextInt();
            ref.tell("sync" + msg, ActorRef.noSender());
        }
    }
}


public class CircuitBreakerActor extends UntypedAbstractActor {

    private ActorRef workerChild;
    private static SupervisorStrategy strategy = new OneForOneStrategy(20,
                    Duration.create(1, "minute"),
                    DeciderBuilder.matchAny(e -> SupervisorStrategy.resume()).build());

    @Override
    public SupervisorStrategy supervisorStrategy() {
        return strategy;
    }

    @Override
    public void preStart() throws Exception {
        super.preStart();
        workerChild = getContext().actorOf(Props.create(WorkerActor.class), "workerActor");
    }

    @Override
    public void onReceive(Object message) throws Throwable {
        workerChild.tell(message, getSender());
    }

}


public class WorkerActor extends UntypedAbstractActor {

    private CircuitBreaker circuitBreaker;

    @Override
    public void preStart() throws Exception {
        super.preStart();
        //熔断器 
        circuitBreaker = new CircuitBreaker(
                getContext().dispatcher(),
                getContext().system().scheduler(),
                5, //失败超过5次 开启
                Duration.create(2, "second"), //超过2秒中视为超时即失败
                Duration.create(1, "min")) //开启1分钟后允许重试,进入半开启
                //监听
                .addOnCallBreakerOpenListener(() -> System.out.println("Actor CircuitBreak 开启"))
                .addOnHalfOpenListener(() -> System.out.println(DateUtil.now() + "Actor CircuitBreak 半开启"))
                .addOnCloseListener(()-> System.out.println(DateUtil.now() + "Actor CircuitBreak 关闭"));
    }

    @Override
    public void onReceive(Object message) throws Throwable {
        if(message instanceof String){
            if(((String) message).startsWith("sync")){
                getSender().tell(circuitBreaker.callWithSyncCircuitBreaker(() -> {
                    System.out.println("msg : " + message);
                    long time = Integer.valueOf(((String) message).substring(4));
                    //模拟超时
                    Thread.sleep(time * 1000);
                    return message;
                }), getSelf());
            }
        }
    }
}

程序运行:

1秒时候正常执行

3秒时候出发超时,maxFailures计数器加1,达到5次后,再次输入提示开启,调用快速失败。

开启期间,发送正常消息(1),同样快速返回失败。1分钟后进入半开启,在次输入1成功处理后熔断关闭。

 

1
msg : sync1
[INFO] [akkaDeadLetter][07/08/2021 17:39:51.525] [sys-akka.actor.default-dispatcher-5] [akka://sys/deadLetters] Message [java.lang.String] from Actor[akka://sys/user/circuit/workerActor#-178031464] to Actor[akka://sys/deadLetters] was not delivered. [1] dead letters encountered. If this is not an expected behavior then Actor[akka://sys/deadLetters] may have terminated unexpectedly. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
3
msg : sync3
[WARN] [07/08/2021 17:39:56.321] [sys-akka.actor.default-dispatcher-5] [akka://sys/user/circuit/workerActor] Circuit Breaker Timed out.
3
msg : sync3
[WARN] [07/08/2021 17:40:00.455] [sys-akka.actor.default-dispatcher-6] [akka://sys/user/circuit/workerActor] Circuit Breaker Timed out.
3
msg : sync3
[WARN] [07/08/2021 17:40:04.707] [sys-akka.actor.default-dispatcher-8] [akka://sys/user/circuit/workerActor] Circuit Breaker Timed out.
3
msg : sync3
[WARN] [07/08/2021 17:40:09.244] [sys-akka.actor.default-dispatcher-5] [akka://sys/user/circuit/workerActor] Circuit Breaker Timed out.
3
msg : sync3
[WARN] [07/08/2021 17:40:15.984] [sys-akka.actor.default-dispatcher-6] [akka://sys/user/circuit/workerActor] Circuit Breaker Timed out.
3
Actor CircuitBreak 开启
[WARN] [07/08/2021 17:40:21.059] [sys-akka.actor.default-dispatcher-7] [akka://sys/user/circuit/workerActor] Circuit Breaker is open; calls are failing fast
1
Actor CircuitBreak 开启
[WARN] [07/08/2021 17:40:25.935] [sys-akka.actor.default-dispatcher-8] [akka://sys/user/circuit/workerActor] Circuit Breaker is open; calls are failing fast
2021-07-08 17:41:15Actor CircuitBreak 半开启
1
msg : sync1
2021-07-08 17:41:26Actor CircuitBreak 关闭
[INFO] [akkaDeadLetter][07/08/2021 17:41:26.574] [sys-akka.actor.default-dispatcher-5] [akka://sys/deadLetters] Message [java.lang.String] from Actor[akka://sys/user/circuit/workerActor#-178031464] to Actor[akka://sys/deadLetters] was not delivered. [2] dead letters encountered. If this is not an expected behavior then Actor[akka://sys/deadLetters] may have terminated unexpectedly. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
内容简介 本书将尝试帮助入门级、中级以及高级读者理解基本的分布式计算概念,并且展示 如何使用 Akka 来构建具备高容错性、可以横向扩展的分布式网络应用程序。Akka 是一 个强大的工具集,提供了很多选项,可以对在本地机器上处理或网络远程机器上处理的 某项工作进行抽象封装,使之对开发者不可见。本书将介绍各种概念,帮助读者理解 网络上各系统进行交互的困难之处,并介绍如何使用 Akka 提供的解决方案来解决这些 问题。 作者简介 Jason Goodwin 是一个基本上通过自学成才的开发者。他颇具企业家精神,在学校 学习商学。不过他从 15 岁起就开始学习编程,并且一直对技术保持着浓厚的兴趣。这对 他的职业生涯产生了重要的影响,从商学转向了软件开发。现在他主要从事大规模分布 式系统的开发。在业余时间,他喜欢自己原创电子音乐。 他在 mDialog 公司第一次接触到 Akka 项目。mDialog 是一家使用 Scala/Akka 的公司, 为主流出版商提供视频广告插入软件。这家公司最终被 Google 收购。他同时还是一名很 有影响力的“技术控”,将 Akka 引入加拿大一家主要的电信公司,帮助该公司为客户提 供容错性更高、响应更及时的软件。除此之 外,他还为该公司中的一些团队教授 Akka、 函数式以及并发编程等知识。 目录 第 1 章 初识 Actor:Akka 工具集以及 Actor 模型的介绍。 第 2 章 Actor 与并发:响应式编程。Actor 与 Future 的使用。 第 3 章 传递消息:消息传递模式。 第 4 章 Actor 的生命周期—处理状态与错误:Actor 生命周期、监督机制、Stash/ Unstash、Become/Unbecome 以及有限自动机。 第 5 章 纵向扩展:并发编程、Router Group/Pool、Dispatcher、阻塞 I/O 的处理以 及 API。 第 6 章 横向扩展—集群化:集群、CAP 理论以及 Akka Cluster。 第 7 章 处理邮箱问题:加大邮箱负载、不同邮箱的选择、熔断机制。 第 8 章 测试与设计:行为说明、领域驱动设计以及 Akka Testkit。 第 9 章 尾声:其他 Akka 特性。下一步需要学习的知识。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值