Actor模型与Akka


一. Actor模型

Actor模型概念

  • 一个概念模型,用于处理并发计算
  • Actor模型内部的状态由自己的行为维护,外部线程不能直接调用对象的行为,必须通过消息才能激发行为,这样就保证Actor内部数据只有被自己修改

Actor模型组成

Actor模型详解

  • 在Actor模型中,一切都可以抽象为Actor,一个Actor指的是一个最基本的计算单元,它能接收一个消息并且基于该消息执行计算
  • Actor封装状态和行为的对象,他们的唯一通讯方式就是交换消息,类比Object: 一个对象接收一条消息(方法调用),然后根据接收的消息做事(调用了哪个方法)
  • Actor重要特征在于Actors之间相互隔离,他们并不互相共享内存,这点儿又区别于上面的Object对象,也就是说一个Actor能维持一个私有的状态,并且这个状态不可能被另一个Actor改变
  • Actor交换的消息放在接收方的邮箱(Inbox)里,也就是说Actor之间并不直接通信,而是通过了消息来相互沟通,每一个Actor都把它要做的事情都封装在了它的内部
  • 每一个Actor是可以有状态也可以是无状态的
  • 当一个Actor接收到消息后,能做如下三件事中的一件: 创建其它Actors,向其它Actors发送消息,指定下一条消息到来的行为:就是Actors如何修改状态
  • 每一个Actor都拥有属于自己的轻量级线程,保护它们不会被系统中的其他部分影响,因此,我们在编写Actor时,就不用担心并发的问题
  • 通过Actor能够简化锁以及线程管理:
    • 提供一种高级的抽象,能够封装状态和操作,简化开发应用开发
    • 提供了异步的非阻塞的/高性能的事件驱动模型
    • 超级轻量级的线程事件处理能力

Actor系统

Actor的生命周期

  • ActorRef
    它是Actor的一个引用,作用是发送消息给它表示的Actor, 而Actor可以通过self()sender()方法来获取 到自身或者消息发送者的Actor引用,在Actor系统中,Actor之间永远都不能直接的通信,必须通过他们的代理ActorRef建立通信

Actor路径

  • 父子Actor
    树形结构,分层管理,通过递归把复杂的事务原子化

  • Actor Path:Actor System中唯一标识

    • 本地Actor
      "akka://my-sys/user/service-a/worker1"
    • 远程Actor
      "akka.tcp://my-sys@host.example.com:2552/user/service-b"
    • 集群Actor
      "cluster://my-cluster/service-c"
  • Actor Path的默认节点

    • root guardian是所有Actor的父Actor /
    • UserActor是所有用户创建的Actor的父Actor /user
    • SystemActor是所有系统创建的Actor的父Actor /system
    • 同级Actor /*

二. Akka

  • Akka是一个由Scala编写的,兼容Scala和Java,用于编写高可用和高伸缩性的Actor模型框架
  • 它基于了事件驱动的并发处理模式,性能非常高,并且有很高的可用性
  • 简化应用系统中开发并发处理的过程

Akka的开发过程

  • 定义消息模型
  • 创建Actor
    • 实现业务逻辑
  • 获取Actor
    • 需要使用Akka的地方获取到ActorSystem,然后根据业务的数据流,获取到合适的Actor,给Actor发送消息
  • 消息处理
    • 在Actor的实现中对接收到的消息进行具体的处理或转发,从而形成业务逻辑流

创建Actor

  • TypedActor

    • Active Object设计模式的应用: 当调用这个实例的方法,异步执行而不是同步执行
    • TypedActor并不使用消息,更多的是用来桥接Actor系统和非Actor
  • UnTypedActor

    • 更像是JAVA中的JMS调用
    • 方法的调用和执行完全依赖消息,通过消息的类型或内容来区别不同的执行
  • 在Akka中我们更多的倾向于使用UnTypedActor向Actor系统间传递消息

创建UnTypedActor

    public class GreetPrinter extends UntypedActor{@overridepublic void onReceive(Object message) throws Exception{if(message instanceof Greeting)System.out.println(((Greeting) message).message);}}

获取Actor

三种方法:

  • actorOf
    创建一个新的Actor,创建的Actor为调用该方法时所属的Context下的直接子Actor
    该方法会返回一个ActorRef来表示Actor的引用,包含一个UID和一个Path.这两个值共同的标识了一个Actor的唯一性,ActorRef的生命周期在Actor停止的时候结束
  • actorSelection
    当消息传递来时,只查找现有的Actor,而不会创建新的Actor,也不会验证目标Actors是否存在
    该方法值关心Path而不关心具体是哪一个Actor,如果要通过ActoSelection来获取一个具体的Actor,需要调用ActorSelection的resolveOne的方法来获取
  • actorFor
    只会查找现有的Actor,而不会创建新的Actor

Akka其它组件

Dispatcher 分发器

当Actor的数量比较多后,彼此之间的通信就需要协调,从而能更好的平衡整个系统的执行性能
特征: 在自己独立的线程上不断的进行协调,把来自各个Actor的消息分配到执行线程
四种不同的Dispatcher

  • Dispatcher:可以被多个Actor所共享,通过ThreadPool实现
    private List<ActorRef> createActors(int actorCount) { Props props = Props.create(WriterActor.class).withDispatcher("writer-dispatcher);List<ActorRef> actors = new ArrayList<>(actorCount);for(int i=0;i<actorCount;i++){actors.add(getContext().actorOf(props,"writer_"+i));}return actors;}
  • PinnedDispatcher
  • BalancingDispatcher
  • CallingThreadDispatcher
Router 路由器

当有多个目标时,Akka通过Router机制,来有效的分配消息给Actor来完成工作,被Router管理的Actor被称作Routee

Router的使用:

  • 可以在Actor内通过实例化Router对象的方式来使用
  • 也可以在Actor外通过withRouter的方式直接创建一个RouterActor来使用
Router router = new Router(new RoundRobinRoutingLogic());for(ActorRef actor : actors){
router = router.addRoutee(actor);
}
router.route("Insert",ActorRef.noSender());
  • Router路由策略
    ◦ RoundRobinPool:轮询方式分发消息
    ◦ RandomPool:随机方式分发消息
    ◦ BalancingPool:均衡分发消息
    ◦ SmallestMailboxPool:最少消息邮箱分发
    ◦ BroadcastPool:广播消息
    ◦ ScatterGatherFirstCompletedPool:所有子Routee发送,第一 个消息回复
    ◦ TailChoppingPool:随机延迟发送,第一个回复消息
    ◦ ConsistentHashingPool:一致性hash的方式来分发消息
Scheduler 调度器

Akka Demo

https://github.com/sunxiang0918/AkkaDemo

三. Akka分布式消息及在Spark中的应用

Akka远程调用

采用了端对端(peer-to-peer, P2P)的通信方式设计,简单透明:除了传递的消息需要可序列化以及创建和查找Actor的时候路径稍有不同外,没有其他的区别,Akka没有特别为Remoting提供专门的API,区别在于配置
最小配置:

    akka{actor{provider = "akka.remote.RemoteActorRefProvider"}remote{enabled-transports = ["akka.remote.netty.tcp"]netty.tcp{hostname = "127.0.0.1"port = 2552}}}

远程Actor

创建和获取远程Actor

远程路径:
akka.tcp://WCMapReduceApp@127.0.0.1:2552/user/remoteActor
创建方式:

    ActorSystem system = ActorSystem.create("WCMapReduceApp",ConfigFactory.load("application").getConfig("WCMapReduceApp"));aggregateActor = system.actorOf(Props.create(AggregateActor.class));

获取方式:

    final ActorRef remoteActor = system.actorFor("akka.tcp://WCMapReduceApp@127.0.0.1:2552/user/remoteActor")

远程Actor路由

  • 负载均衡和高可用
    Akka远程调用是基于点对点模型,不支持负载均衡等功能,但能通过Actor路由机制实现负载均衡和高可用
    ex: 当向/parent/remotePool发送消息的时候,,会轮询的把消息分发到不同的远程服务上
    akka.actor.deployment {/parent/remotePool{router = round-robin-poolnr-of-instances = 10target.nodes = ["akka.tcp://app@10.0.0.2:2552","akka://app@10.0.0.3:2552"]}}

Akka集群

  • Cluster调用
    Gossip协议
    反熵(Anti-Entropy): 在一个有界网络中,每个节点都随机地与其他节点通信,经过一番杂乱无章的通信,最终所有节点的状态都会达成一致
    ,具有去中心化,节点之间完全对等,不需要任何的中心节点,最终一致性的特点
    Gossip算法示例

    • Cassandra
    • redis

Akka的集群是基于Gossip协议实现的,支持服务自动失效检测,能够自动发现出现问题而离开集群的成员节点,通过事件驱动的方式,将状态传播到整个集群的其他成员节点中去,一个Akka集群是由一组成员节点组成的,每个成员节点都是通过hostname:port:uid来唯一标识,并且每个成员节点完全解耦合

  • 节点状态

  • 集群Leader

  • 集群配置

  • Spark中的Akka
    把Akka当做分布式系统中的RPC框架使用,很多组件封装为Actor,进行控制和状态通信,Spark中的CLient,Master和Worker都是一个Actor,Actor之间,消息发送端通过”!”符号发送消息,接收端通过receive方法中的case模式匹配接收和处理消息

Actor模型与Akka相关推荐

  1. Actor 模型及Akka简介

    Actor 模型 Actor 的基础就是消息传递,一个 Actor 可以认为是一个基本的计算单元,它能接收消息并基于其执行运算,它也可以发送消息给其他 Actor.Actors 之间相互隔离,它们之间 ...

  2. 《通过C#学Proto.Actor模型》之 HelloWorld

    在微服务中,数据最终一致性的一个解决方案是通过有状态的Actor模型来达到,那什么是Actor模型呢? Actor是并行的计算模型,包含状态,行为,并且包含一个邮箱,来异步处理消息. 关于Actor的 ...

  3. java actor akka_Actor 模型及Akka简介

    Actor 模型 Actor 的基础就是消息传递,一个 Actor 可以认为是一个基本的计算单元,它能接收消息并基于其执行运算,它也可以发送消息给其他 Actor.Actors 之间相互隔离,它们之间 ...

  4. Akka入门(二)Akka的Actor模型如何满足现代分布式系统需求

    Actor模型允许开发者: 在不诉诸锁定的情况下实施封装. 使用协作实体的模型对信号做出反应,改变状态,并相互发送信号以推动整个应用程序向前发展. 不要担心与我们的世界观不匹配的执行机制. (一) 消 ...

  5. akka linux 端口,Actor模型开发库 Akka

    Akka 是一个用 Scala 编写的库,用于简化编写容错的.高可伸缩性的 Java 和 Scala 的 Actor 模型应用. Actor模型并非什么新鲜事物,它由Carl Hewitt于上世纪70 ...

  6. spark 如何用netty实现akka的actor模型

    Spark的中,通过netty实现了类似akka的actor机制. 在spark中,一个EndPointData就类似一个akka中的actor. private class EndpointData ...

  7. Akka之actor模型

    一 定义Actor import akka.actor.{Props, ActorSystem, Actor} import akka.actor.Actor.Receive import akka. ...

  8. scala之Akka的Actor模型(上)

    原文地址:http://my.oschina.net/jingxing05/blog/287213 明确并行和并发 看两张图 并行parallelism 并发concurrency 关键点在于 多个任 ...

  9. 【Akka】Actor模型探索

    Akka是什么 Akka就是为了改变编写高容错性和强可扩展性的并发程序而生的.通过使用Actor模型我们提升了抽象级别,为构建正确的可扩展并发应用提供了一个更好的平台.在容错性方面我们采取了" ...

最新文章

  1. Visual C++ 2012/2013的内存溢出检測工具
  2. 《深度探索C++对象模型》--3 Data语意学
  3. [Python]元组与列表的区别及内建用法
  4. bzoj1601: [Usaco2008 Oct]灌水
  5. Spring简化Java开发_第1章—Spring之旅—简化Spring的java开发
  6. 《JavaScript高级程序设计》Chapter 10 DOM
  7. Android adb shell执行mv等操作时,提示:Read-only file system的解决办法
  8. 2019UI设计岗位最常见的面试题
  9. 欧洲专线运输方式有哪些?有哪些优势?
  10. 定位及overflow
  11. [项目管理]-- 项目开发流程(基本流程)
  12. 企业如何做好邮件归档稽核
  13. JAVA Calendar详解
  14. 刚刚从Java培训班出来以及初学者怎么样才能通过面试?
  15. 浅谈Python类的属性和方法
  16. 《问题背后的背后》一书 读后感(一)
  17. 系统平台如何解决常见问题
  18. Java编程案例:买飞机票
  19. Java 语言中的函数编程
  20. seo友情链接如何交换以及作弊方式

热门文章

  1. iOS小技能: 开发 uni 原生插件(支持iOS Extension)
  2. As的LogCat打开方法
  3. 超厉害的CSS3图片破碎爆炸效果!
  4. 【题解】昂贵的聘礼 POJ - 1062 (最短路 经典)⭐⭐⭐⭐
  5. 周易六十四卦详解 (通俗易懂版)
  6. Linux线程数和系统线程数查看
  7. 洛谷 P1873 砍树 (二分答案)
  8. 微信小程序码中间Logo修改
  9. date_sub的用法
  10. 【更好用的单片机】Stduino学习(三十三)面包板模块