akka设计模式系列(Actor模型)

简介:   谈到Akka就必须介绍Actor并发模型,而谈到Actor就必须看一篇叫做《A Universal Modular Actor Formalism for Artificial Intelligence 》的论文,它最早发表于1973年,提出了一种并发计算的理论模型,Actor就源于该模型。

  谈到Akka就必须介绍Actor并发模型,而谈到Actor就必须看一篇叫做《A Universal Modular Actor Formalism for Artificial Intelligence 》的论文,它最早发表于1973年,提出了一种并发计算的理论模型,Actor就源于该模型。

  在Actor模型中,actor是一个并发原语,简单的说,一个actor就是一个工人,与进程或线程一样都能够工作或处理任务。其实这还有点不好理解,我们可以把它想象成面向对象编程语言中的一个对象实例。在OOP中一个对象可以访问或修改另一个对象的属性,也可以直接调用另一个对象的方法。例如下图,person1给person2发送了一个消息,直接调用方法就行了。深入底层执行逻辑的话,结果就是JVM转到sayHello的代码区,一步步执行。

public class HelloWorld {
    private String name = "";
    public HelloWorld(String name){
        this.name = name;
    }
    public String getName(){
        return this.name;
    }
    public void sayHello(HelloWorld to, String msg){
        System.out.println(to.getName()+" 收到 "+name+" 的消息:"+ msg);
    }
}

public class OOPInvoke {
    public static void main( String[] args ) {
        HelloWorld person1 = new HelloWorld("Person1");
        HelloWorld person2 = new HelloWorld("Person2");
        person1.sayHello(person2,"Hello world");
    }
}

   sayHello在一个线程中执行基本没有问题,但是多个线程执行时,就可能出问题了,因为在执行sayHello的时候person2的name值可能被其他线程修改。这是一个name字段,意外修改没有关系,但如果是一个金额字段呢?

  actor和对象的不同之处在于,actor的状态不能直接读取、修改,actor的方法不能直接调用。actor只能通过消息传递的方式与外界通信。每个对象都有一个this指针,代表对象的地址,可以通过该地址调用方法或存取状态;与此类似,actor也有一个代表本身的地址,但只能向该地址发送消息。

  简单点说,actor通过消息传递的方式与外界通信。消息传递是异步的。每个actor都有一个邮箱,该邮箱接收并缓存其他actor发过来的消息,actor一次只能同步处理一个消息,处理消息过程中,除了可以接收消息,不能做任何其他操作。前面这段话,我加粗、倾斜、加下划线、还用红色字体标出,你就应该知道有多重要了,这就是actor模型的本质。

 

  Actor模型的另一个好处就是可以消除共享状态,因为它每次只能处理一条消息,所以actor内部可以安全的处理状态,而不用考虑锁机制。标红的这两句话如果可以理解透彻,基本上Actor模型的精髓你就掌握了。

  那么读者可能会问,每次只处理一个消息,这不是会严重的影响性能么?废话,一次处理一个消息当然影响性能了。不过,如果你恰当的运用Akka和Actor模型,完全可以不必关心性能的问题。下面是Actor模型的几个基本原则:
       (1)所有的计算都是在actor中执行的
       (2)actor之间只能通过消息进行通信交流
       (3)为了响应消息,actor可以进行下列操作
               a.  更改状态或行为
               b. 发消息给其他actor
               c. 创建有限数量的子actor

  看了上面几个基本原则,你是不是更加鉴定的认为Actor模型没啥用?嗯,这就对了,因为我当初也是这么认为的。一次处理一个消息,没有并发,怎么提高性能;如果actor只能更改状态或行为,发消息给其他actor,创建有限数量的子actor,那我的业务逻辑在哪里;actor之间只能通过消息通信,我怎么知道另外一个actor的地址。其实吧,如果你能问到这几个问题,那么恭喜你,你非常需要我这个博客系列,我会一一进行分析,把我之前的坑展示给你看,以确保你不会再掉进去。

 

  其实Actor模型出现的很早,而20世纪80年代,爱立信在Erlang中实现了Actor模型,用于嵌入式电信应用程序。该实现中引入了监督机制提供的容错性概念。爱立信使用Erlang和Actor模型实现了一款日后经常被提及的应用:AXD301。这玩意儿能提供99.9999999% 的可用性,看到没,7个9!!!绝对可以亮瞎人们的狗眼,这意味着在100年的时间中,AXD301只有3.1秒的时间会宕机。

  Actor模型的另一个重要的特性就是容错,它通过监督机制提供容错。这跟java中的throw exception有点类似,都是把处理响应错误的责任交给出错对象以外的实体。但在java中如果一个程序或者线程抛出了一个异常,你敢放心的恢复对应的程序或线程吗?你确保恢复之后还能正常的运行吗,毕竟需要很多资源需要重新创建。但Actor模型可以!

  

  如上图所示actor之间是有层级关系的,子actor如果出现了异常会抛给父actor,父actor会根据情况重新构建子actor,子actor从出现异常,到恢复之后正常运行,这段时间内的所有消息都不会丢失,等恢复之后又可以处理下一个消息。也就是说如果一个actor抛出了异常,除了导致发生异常的消息外,任何消息都不会丢失。这容错性当然好了。当然了,为了实现这种特性,akka或者Erlang需要做很多工作的。

  Akka中的Actor模型还有另外一个比较重要的两个特性:分布式与位置透明性。其实可以认为这是一个特性。Actor模型中一个很重要的概念就是actor地址,因为其他actor需要通过这个地址与actor进行通信。akka考虑到分布式的网络环境,对actor地址进行了抽象,屏蔽了本地地址和远程地址的差异,对于开发者来说基本上是透明的。由于actor地址是透明的,那么akka有引入了集群。当然了基于Actor模型和位置透明性,Akka还有其他很多有用的组件,这里就不介绍了,后面会详细说明。

  关于Actor模型就先介绍到这里,下一章节我们会介绍Actor模型的最基本的设计模式,以说明该模型的适用场景。

 

目录
相关文章
|
6月前
|
设计模式 算法 安全
【设计模式】RBAC 模型详解
随着软件系统的复杂性和规模的不断增长,权限管理成为了一个至关重要的问题。在大型多人协作的系统中,如何有效地管理不同用户的访问权限,确保系统的安全性和稳定性,是每一个开发者都需要面对的挑战。为了解决这一问题,业界提出了一种被广泛应用的权限管理模型——基于角色的访问控制(Role-Based Access Control,简称RBAC)。希望通过本篇博客的学习,您能够深入了解RBAC模型的核心思想和实现原理,掌握如何在实际项目中应用RBAC模型来提高系统的安全性和可维护性。
878 1
|
5月前
|
设计模式 人工智能 自然语言处理
【设计模式】MVVM模式在AI大模型领域的创新应用
【设计模式】MVVM模式在AI大模型领域的创新应用
73 0
|
6月前
|
设计模式 前端开发 安全
C++23种设计模式&软件设计模型
C++23种设计模式&软件设计模型
|
设计模式 安全 Java
设计模式总结(一):创建型模型
设计模式总结(一):创建型模型
102 1
|
设计模式 领域建模 数据库
提升代码质量的方法:领域模型、设计原则、设计模式
提升代码质量的方法:领域模型、设计原则、设计模式
|
设计模式 存储 前端开发
Python:设计模式之模型-视图-控制器-MVC复合模式
Python:设计模式之模型-视图-控制器-MVC复合模式
98 0
|
设计模式 安全 Java
java 设计模式实战,原始模型模式之写作业,克隆以后就是新的
通过给出一个原型对象指明所要创建的对象的类型,然后通过复制这个原型对象来获取的更多的同类型的对象。 这让我不由自主的想起克隆技术,还记得克隆羊吗?
java 设计模式实战,原始模型模式之写作业,克隆以后就是新的
|
设计模式 存储 前端开发
Python:设计模式之模型-视图-控制器-MVC复合模式
Python:设计模式之模型-视图-控制器-MVC复合模式
142 0
|
设计模式 Kubernetes Java
提升代码质量的方法:领域模型、设计原则、设计模式
我们可以列举出非常多质量差的代码的表现现象,其中最影响代码质量的两个表现是命名名不副实、逻辑可扩展性差,当一个新人阅读代码时,有时发现方法命名与实际逻辑对不上,这就让人感到非常疑惑,这种现象在平时工作并不少见;另一个就是逻辑扩展性差,一个新业务需求提出来后,发现要在多处改动,需要回归的业务逻辑比较多,造成研发效率不高。
提升代码质量的方法:领域模型、设计原则、设计模式
|
15天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式