Actor监控与容错机制

深入解析actor 模型(一): actor 介绍及在游戏行业应用 1 介绍 1.1 什么是actor 对于刚接触actor的我,第一感觉就像redis一样,每个actor就是一个redis 实例,都有自己消息队列,actor相互通信通过将消息发给对方,消息发送进对方的消息队列,等待对方线程处理。来看看我们之前做项目的痛点。 游戏服务器通常分为多个服,每个服上有多个玩家。假设玩家与玩家数据交互操作,这时怎么避免数据竞争?两种解决方案: 1、将数据写入redis 首先redis效率高,也是单线程模型,不存在数据竞争,但是也有它的不足之处,操作redis 会受网络影响 阅读详情

       在如今的IT行业中,如果一个系统不具备高可用以及稳定性,那么它迟早会被淘汰的。也许有时出现故障并不是代码本身的问题,网络(连接超时、读超时等)、服务器故障、用户操作有误等原因,也不能影响用户的体验。程序发生故障时,我们要尽可能保证用户体验不受影响,这就需要我们的系统具有良好的容错机制,能保证服务在不可用时自我修复。

     监督策略

       Actor作为Akka中最基本的执行单元,是所有业务的核心,如若发生故障,可能产生不可估量的后果,这就需要拥有一套容错机制。前面我们已经提到,Actor系统具有监控机制,父级对子级进行管理,子级如果出现异常情况,父级可以通过处理逻辑来确定子级是重启、恢复、还是停止。

       Akka提供了两种监督策略,分别是One-For-One Strategy和All-For-One Strategy。关于这两种策略的区别如下:

策略

描述

One-For-One Strategy

子Actor出现异常,只针对该Actor处理。

All-For-One Strategy

子Actor出现异常,对所有子级Actor进行处理。

       在程序中,当我们没有为Actor指定管理策略,Akka提供了一套默认的策略:

  • 抛出ActorInitializationException、ActorKilledException 、DeathPactException 时,停止子Actor运行。
  • 抛出Exception时,重启子Actor。
  • 其它类型的Throwable异常时,会上溯到父级。

       实际项目中,我们可能自定义了许多异常,以此来区分不同的情况。针对这些不同的异常,我们处理Actor方式或许不一样,这就需要我们自定义监督策略。SupervisorStrategy是自定义监督策略核心类,构造函数如下:

public OneForOneStrategy(int maxNrOfRetries, java.time.Duration withinTimeRange, PartialFunction<Throwable, Directive> decider)

      我们可以看到它有三个参数,分别是maxNrOfRetries、withinTimeRange、decider。其中maxNrOfRetries和withinTimeRange表明在一段时间的重启次数,超过次数则stop。第三个参数是一个Function对象,我们可以在里面定义监督指令,使用DeciderBuilder构建工厂可以快速编写,监督指令有:

指令

描述

API

重新启动

会在旧实例上调用preRestart方法,停掉所有子级actor并调用postStop方法,然后在新实例上调用postRestart方法(默认会调用preStart方法),不会保留旧实例的状态,保留邮箱(消息)。

SupervisorStrategy.restart()

恢复运行

出现异常,不会抛出,保留之前的状态。

SupervisorStrategy.resume()

停止运行

销毁actor相关资源,后续消息不会接受。

SupervisorStrategy.stop()

上溯父级

父级无法处理异常消息,并把异常上报上一级父级。

SupervisorStrategy.escalate()

       下面,我们写一个示例来观察这几个指令,示例如下:

         监控者SupervisorActor类:

public class SupervisorActor extends AbstractActor {
    /**
     * 自定义OneForOneStrategy监督策略
     */
    private static SupervisorStrategy strategy = new OneForOneStrategy(3, Duration.ofMinutes(1),
            DeciderBuilder.match(IOException.class, e -> SupervisorStrategy.resume())
                    .match(NullPointerException.class, e -> SupervisorStrategy.restart())
                    .match(IllegalArgumentException.class, e -> SupervisorStrategy.stop())
                    .matchAny(o -> SupervisorStrategy.escalate())
                    .build());
    private final LoggingAdapter logger = Logging.getLogger(getContext().getSystem(), this);


    public static void main(String[] args) throws InterruptedException {
        ActorSystem system = ActorSystem.create("system");
        ActorRef supervisor = system.actorOf(Props.create(SupervisorActor.class), "supervisor");
        supervisor.tell("IOException", ActorRef.noSender());
        //supervisor.tell("NullPointerException", ActorRef.noSender());
        //supervisor.tell("IllegalArgumentException", ActorRef.noSender());
        supervisor.tell("get", ActorRef.noSender());
    }

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

    @Override
    public void preStart() throws Exception {
        ActorRef childActor = getContext().actorOf(Props.create(ChildActor.class), "childActor");
        //监控
        getContext().watch(childActor);
    }

    @Override
    public Receive createReceive() {
        return receiveBuilder().match(String.class, s -> {
            Option<ActorRef> childActor = getContext().child("childActor");
            ActorRef child = childActor.get();
            if ("IOException".equals(s)) {
                child.tell(new IOException(), getSelf());
            } else if ("NullPointerException".equals(s)) {
                child.tell(new NullPointerException("空指针异常"), getSelf());
            } else if ("IllegalArgumentException".equals(s)) {
                child.tell(new IllegalArgumentException(), getSelf());
            }else if("get".equals(s)){
                child.tell("get", getSelf());
            }
        }).match(Terminated.class, t -> {
            logger.info("监控到" + t.getActor() + "停止了");
        }).matchAny(other -> {
            logger.info("state= " + other);
        }).build();
    }
}

子类ChildActor ,我们重写preStart、postStop、preRestart、postRestart四个方法,方便我们观察不同指令下的流程:

public class ChildActor extends AbstractActor {
    /**
     * 用来观察不同处理后的结果
     */
    private int state = 1;

    @Override
    public Receive createReceive() {
        return receiveBuilder()
                .match(Exception.class, e -> {
                    this.state++;
                    throw e;
                })
                .matchEquals("get", s -> {
                    this.state++;
                    getSender().tell(state, getSelf());
                })
                .matchAny(o -> {
                    this.state++;
                    unhandled(o);
                })
                .build();
    }

    @Override
    public void preStart() throws Exception {
        super.preStart();
        System.out.println("child preStart");
    }

    @Override
    public void postStop() throws Exception {
        super.postStop();
        System.out.println("child postStop");
    }

    @Override
    public void preRestart(Throwable reason, Optional<Object> message) throws Exception {
        System.out.println("child preRestart start: " + this.state);
        super.preRestart(reason, message);
        System.out.println("child preRestart end: " + this.state);
    }

    @Override
    public void postRestart(Throwable reason) throws Exception {
        System.out.println("child postRestart start: " + this.state);
        super.postRestart(reason);
        System.out.println("child postRestart end: " + this.state);
    }
}

      这里特别提醒一下,ChildActor的createReceive方法中的this.state++必须写在每个匹配项里,如若写在createReceive方法里,只会执行一次。

       运行SupervisorActor 的main方法,测试三种异常带来的不同状态结果(运行结果不贴出来了,大家可以运行一下示例),  结果说明如下:

异常

结果及说明

IOException

匹配到resume指令,childActor恢复继续运行,大家应该发现没有抛出异常,异常自动跳过。state值为3,说明之前的状态保留了下来。

NullPointerException

匹配到restart指令,childActor进行重启。根据运行结果,大家应该发现,会先调用旧实例的preRestart方法,然后调用postStop,之后在新实例上调用postRestart,调用preStart方法。重启后发现state=2,说明重启会清空之前的状态。

IllegalArgumentException

匹配到stop指令,childActor停止运行,后续获取state消息没有接受到,父类supervisor收到Terminated消息。

      正确的使用监控和容错机制,可以在程序出现异常或故障时,保证系统不崩溃,对于系统的高可用和稳定性提供极大的保障。

 

actor 模型原理 (二) 现在开始研究一下akka的actor模型是怎么实现的: 老外写了一个程序说明actor的工作机制,下图就是学生给老师发邮件的具体示意图,那么1-6一共6个步骤 1、学生创建actor system ,就是初始化了ActorSystem 2、学生发邮件,发邮件并不是妈的找个163的邮箱直接发一下,或者说并没有直接给邮件地址,而是采用代理的方式,什么意思呢? 就是为了让俩线程, 阅读详情

相关推荐

6、Ray分布式系统设计与优化全解析

本文深入解析了Ray分布式系统的设计与优化机制,涵盖故障容错、Ray对象管理、序列化技术、资源分配及内存使用等核心方面。详细介绍了远程函数与Actor的容错策略、对象生命周期与重建、cloudpickle与Arrow序列化差异、资源调度配置以及内存监控与调优方法,并提供了操作步骤、对比表格和流程图辅助理解。旨在帮助开发者构建高效、可靠的Ray应用,提升系统性能与稳定性。

blue42的博客 63

Akka(3): Actor监管 - 细述BackoffSupervisor

在上一篇讨论中我们谈到了监管:在Akka中就是一种直属父子监管树结构。父级Actor负责处理直属子级Actor产生的异常。当时我们把BackoffSupervisor作为父子监管方式的其中一种。实际上BackoffSupervisor与定义了supervisorStrategy的Actor有所不同。我们应该把BackoffSupervisor看作是一个一体化的Actor。当然,它的实现方式还是由一

TIGER_XC的专栏 838

Akka:Scala与Java的高性能并发框架

本文还有配套的精品资源,点击获取 简介:Akka是一个高性能、容错的并行计算框架,使用Scala编写,通过Actor模型实现分布式计算。其核心概念包括轻量级线程Actor,通过消息传递实现并发,监督和监控机制提供强大的容错能力,Cluster支持真正的分布式计算,而持久化特性确保了数据在系统崩溃后的可恢复性。Akka Streams提供声明式数据流处理,配合Play Fra...

weixin_42515842的博客 2722

17 | 分布式计算模式之Actor:一门甩锅的艺术

在第 10 篇文章“分布式体系结构之非集中式结构:众生平等”中,曾提到 Akka 框架基于 Actor 模型,提供了一个用于构建可扩展的、弹性的、快速响应的应用程序的平台。其中,Actor 类似于一个“黑盒”对象,封装了自己的状态和行为,使得其他 Actor 无法直接观察到它的状态,调用它的行为。多个 Actor 之间通过消息进行通信,这种消息类似于电子邮箱中的邮件。Actor 接收到消息之后,才会根据消息去执行计算操作。那么,Actor 模型又是什么呢?Actor 模型,代表一种分布式并行计算模型。

qq_37756660的博客 617

Matlab蒙特卡洛模拟二维伊辛模型相变过程

一、什么是伊辛模型 伊辛(Ising)模型是描述磁系统相变最简单的模型,但模型里自旋之间的相互作用赋予了它奇妙的特性,最有趣的就是对称性破缺。这一模型可以被推广用于研究连续的量子相变、基本粒子超弦理论、动力学临界行为等,甚至被认为可以描述深林火灾、交通拥堵、舆论传播等社会经济现象。 如图,每个格点的方向只有向上或向下两者状态,但临近的自旋之间有相互作用,而且点阵可以是一维、二维、三维、甚至更高维...

http://www.icfgblog.com/ 2万+

5分钟搞定SNMP工具安装:从Linux到Windows的snmpwalk/snmpget全攻略

本文提供了SNMP工具(snmpwalk/snmpget)在Linux和Windows系统上的快速安装与使用指南,涵盖从基础安装到高阶应用的全面解析。通过详细的命令示例和故障排查技巧,帮助用户快速掌握网络设备监控与诊断的核心技能,提升运维效率。

weixin_29248313的博客 557

akka学习之actor监护与监控

       在前面的章节akka学习之actor介绍中介绍了actor对ziactor有监护职责,同时actor对其他actor的生命周期等信息进行监控。这张将详细解释什么是监护和监控。 什么是监护(supervision) 在actor系统,一个actor(上司也可以成为监护人)可以创建子actor(下属),然后可以分配任务给他的下属去执行,同时也要对下属的错误负责,上司也是下属的监护...

iteye_9153的博客 319

squirrel校园二手交易平台

squirrel校园二手交易平台 (适合寻找SSM项目练手的你。) 项目起源:   期末的课程设计,三人一组,我和两个舍友,一时起兴,决定做一个校园二手交易平台,一开始兴致与激情满满,可是后期时间上的冲突,让我们三个人对于这个项目有点累。   这个项目刚定题两天,BezosLee由于通过了360的网上在线笔试,收到了360公司的免费培训邀请,要去北京的360总部进行培训一周,值得庆...

K.SHI的博客 5万+

php容错机制,Actor监控与容错机制

在如今的IT行业中,如果一个系统不具备高可用以及稳定性,那么它迟早会被淘汰的。也许有时出现故障并不是代码本身的问题,网络(连接超时、读超时等)、服务器故障、用户操作有误等原因,也不能影响用户的体验。程序发生故障时,我们要尽可能保证用户体验不受影响,这就需要我们的系统具有良好的容错机制,能保证服务在不可用时自我修复。监督策略Actor作为Akka中最基本的执行单元,是所有业务的核心,如若发生故障,可...

weixin_35649605的博客 235

vue3 - element-plus表格组件el-table实现鼠标拖曳排序功能,vue3 Table表格拖拽排序,表格每行使用鼠标拖动进行排序功能,表格拖拽排序实现(详细示例代码,一键复制开箱即用

vue3,elementPlus,el-table,typescript,表格组件,Table表格,表格拖动排序,表格拖曳排序,鼠标拖拽表格进行排序功能,elementplus表格如何实现拖动每行进行排序操作,表格拖动改变顺序,鼠标拖曳,表格内的数据项拖拽排序,vue3如何实现element-Plus表格组件进行表格内的数据项拖拽排序,列表拖拽排序效果,实现table动态拖拽,鼠标拖着排序,vue3 element Plus 表格拖曳拖动拖拽 排序,el-table拖拽排序实现,表格内容拖拽重新排序,树形表

✅ 精选推荐文章 1万+

uniapp - 详细解决 H5 网页报错 Uncaught Error: Async component timed out after ? ms.(移动端h5页面白屏或加载缓慢失败,超时报错处理)

uni-app,vue3,网页,h5,移动端,手机H5页面,浏览器,报错,uniapp报错,Asynccomponenttimedoutafter,如何解决这个问题,vue3Asynccomponenttimedoutafter,异步组件超时了怎么办,async,详细解决方案,AsyncComponents异步组件,导致页面打不开了,白屏什么也不显示,网页载入非常慢卡顿,vue3网站报错,超时,nuxt3,详细解决方案,浏览器控制台报错,爆红并且页面卡住了,依旧报错,找不到异步组件的报错

🏆 前端领域优质创作者 3782

Proto.Actor故障恢复与容错机制:Supervision策略深度解析

Proto.Actor是一个超快速的分布式Actor框架,其故障恢复与容错机制是构建可靠分布式系统的关键。在分布式系统中,故障是不可避免的,而Proto.Actor通过强大的Supervision策略为开发者提供了完善的故障处理方案。本文将深入解析Proto.Actor的Supervision机制,帮助你构建更加健壮的应用程序。🚀 ## 为什么需要Supervision策略? 在Actor模

gitblog_01011的博客 979

用 ABAP LSMW 的 Standard Batch / Direct Input 稳准快迁移物料主数据:从 MM01 录制到 RMDATIND 直入的落地指南

本文详细介绍了SAP数据迁移中LSMW工具的使用方法,重点分析了物料主数据迁移的两种主要路径:Batch Input Recording和Standard Batch/Direct Input。前者通过录制事务操作实现快速起步,后者通过调用预置接口程序实现稳定高效的批量处理。文章深入解析了Standard Direct Input的具体实施步骤,包括对象属性设置、源结构定义、字段映射规则等关键环节,并特别强调了迁移前的准备工作(如编号策略、视图策略等)对项目成功的重要性。通过对比两种方法的优缺点,为不同业务

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 155

Proto.Actor从入门到精通:10个实用技巧构建你的第一个Actor系统

Proto.Actor是一个超快速的分布式Actor框架,支持Go、C#和Java/Kotlin语言。本文将为你提供10个实用技巧,帮助你快速入门并构建高效的Actor系统。 ## 1. 了解Proto.Actor核心组件 Proto.Actor的核心组件包括`Proto.Actor`项目,它提供了基础的Actor系统、Props、邮箱、事件流和监控等功能。这些组件是构建任何Actor系统的基

gitblog_00907的博客 909

药物吸收仿真软件:Caco-2_(9).Caco-2模型在药物开发中的案例分析

通过以上五个案例,我们可以看到Caco-2模型在药物开发中的重要作用。它不仅能够帮助我们预测药物的肠道吸收情况,还能够用于优化药物配方、评估代谢稳定性、研究药物相互作用以及转运蛋白的影响。这些体外实验和仿真分析的结果为药物的进一步临床研究提供了重要的参考依据,有助于缩短药物开发周期,提高研发效率。

kkchenjj的博客 864

基于Python的房地产评估数据抓取与分析 —— 房价走势与市场报告

在房地产行业中,了解和分析房产价格的变化趋势、各个地区的房价差异以及市场评价报告,可以帮助投资者、购房者以及政策制定者做出更加明智的决策。本文介绍了如何使用Python爬虫技术抓取房地产平台上的房产评估报告、价格走势等数据,并对抓取的数据进行分析。通过这些技术,您可以自动化抓取房地产平台的数据,分析房价走势,获取市场报告,为房地产投资决策提供数据支持。假设我们要从链家网抓取某个房产的价格、房产描述以及历史成交价格,首先需要获取目标房产页面的URL,并发送HTTP请求。伪装为常见浏览器,避免被识别为爬虫。

2201_76125261的博客 848

KillrWeather容错机制:如何构建异步事件驱动的故障容忍数据管道

在当今大数据时代,构建可靠的时间序列数据处理系统面临着前所未有的挑战。KillrWeather作为一个基于Apache生态系统的参考应用程序,展示了如何巧妙地将Apache Spark Streaming、Apache Cassandra、Apache Kafka和Akka集成在一起,构建一个真正**容错**的异步事件驱动数据管道。本文将深入探讨KillrWeather的**容错机制**如何确保系

gitblog_00200的博客 302

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Multi-Agent系统容错机制:原理与实践优化

分布式系统中的容错机制是保障系统高可用的核心技术,尤其在Multi-Agent系统中更为关键。容错机制通过心跳检测、状态快照和任务重试等策略,确保系统在节点故障或网络分区时仍能稳定运行。其技术价值在于提升系统鲁棒性,减少停机时间,适用于金融交易、物流调度等高可用性场景。本文结合工业级实践,详细探讨了自适应心跳检测、增量式检查点等优化方案,并分享了在电商推荐系统和订单处理系统中的具体应用案例。通过分层设计的容错策略,系统可在硬件故障、资源耗尽等复杂场景下保持99.98%的可用性。

weixin_33393017的博客 101

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Proto.Actor与ASP.NET Core集成:构建高性能微服务架构的终极指南 [特殊字符]

在当今的微服务架构中,**Proto.Actor**作为一款超快速分布式Actor框架,为.NET开发者提供了构建高性能、可扩展系统的强大工具。本文将深入探讨如何将Proto.Actor与ASP.NET Core完美集成,帮助您掌握构建现代微服务架构的最佳实践。 ## 为什么选择Proto.Actor构建微服务? 🤔 Proto.Actor是一个专为Go、C#和Java/Kotlin设计的分

gitblog_01116的博客 970

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Akka Actor模型在分布式系统中的应用与优化

Actor模型作为一种并发计算模型,通过将计算单元抽象为独立的Actor,采用消息传递机制实现通信,有效解决了传统线程和锁模型在高并发场景下的局限性。其核心原理包括状态封装、异步消息处理和位置透明性,特别适合构建高可扩展的分布式系统。在电商秒杀、物联网设备管理等实际应用中,Akka框架的Actor模型展现出显著性能优势,如通过集群分片技术实现负载均衡,结合事件溯源保证数据一致性。对于开发者而言,理解不可变消息传递、监督策略等关键机制,能够避免常见并发问题并提升系统稳定性。

weixin_32576389的博客 246

Ractor监督树实战教程:构建容错系统的终极方案

在构建高可用、容错的分布式系统时,Ractor监督树是Rust Actor框架中最重要的容错机制。Ractor监督树提供了**构建容错系统**的终极解决方案,让您的应用程序能够优雅地处理故障并自动恢复。本文将带您深入了解Ractor监督树的**监督树实战**技巧,帮助您构建真正可靠的系统。 ## 🎯 什么是Ractor监督树? Ractor监督树是一种层次化的**容错系统**架构,灵感来源于

gitblog_01021的博客 330

Gleam OTP工厂监督器(Factory Supervisor)详解:动态管理Actor的高效方案

Gleam OTP工厂监督器(Factory Supervisor)是Gleam语言基于OTP框架实现的动态进程管理工具,专为高效创建和监控Actor进程而设计。它允许开发者通过预定义模板动态启动子进程,在程序运行时根据需求灵活扩展系统容量,同时提供完善的故障恢复机制,是构建容错多核程序的核心组件。 ## 什么是工厂监督器? 工厂监督器本质上是一种特殊的监督进程,采用Erlang/OTP中的`

gitblog_00019的博客 1001

Akka Essentials - 2

Actors Defining an actor class MyActor extends Actor { def receive = { } } In Scala, the receive block is actually a partial function, which allows the usage ...

weixin_33978044的博客 159

Erlang语言的线程

Erlang是一种函数式编程语言,由乔阿基姆·阿姆斯特朗(Joe Armstrong)在1980年代开发,旨在支持分布式、并发和容错的系统。Erlang的设计初衷是用于电信系统的开发,因此其在处理大量并发任务和容错方面具有独特的优势。本文将深入探讨Erlang语言中的“线程”概念,以及其如何在现代编程范式中发挥作用。

2501_91313831的博客 380

从 Hello World 到进程通信:Riot 示例教程全解析

Riot 是一个为 OCaml 5 设计的 actor 模型多核调度器,它让开发者能够轻松构建并发应用程序。本教程将通过官方示例,带您从最基础的 "Hello World" 程序逐步深入到进程间通信,掌握 Riot 的核心概念和使用方法。 ## 1. 快速入门:Hello World 程序 🚀 每个 Riot 程序都以 `Riot.run` 函数开始,它接受一个函数作为输入并且不会自行终止,

gitblog_00142的博客 490

构建高可扩展分布式系统:Protoactor-go实战案例全解析 [特殊字符]

Protoactor-go是一个基于Go语言的分布式Actor框架,它可以帮助开发者轻松构建高并发、高可扩展的分布式系统。这个强大的工具让Go语言开发者能够利用Actor模型的优势,实现解耦并发、分布式部署和容错处理等功能。在本文中,我们将深入探讨Protoactor-go的核心特性、架构设计以及如何在实际项目中应用这一框架。 ## 为什么选择Actor模型构建分布式系统? 🤔 Actor模

gitblog_01122的博客 1100
上一篇: Actor简介(二)
下一篇: 线程调度(Dispatcher)
西红柿丶番茄
博客等级 码龄10年 21粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值