【AKKA 官方文档翻译】actor模型如何满足现代分布式系统的需求

actor模型如何满足现代分布式系统的需求

akka版本2.5.8
版权声明:本文为博主原创文章,未经博主允许不得转载。

正如之前所述,在构建现代的苛刻系统时,我们使用现在常见的编程模式并不能正确地去处理好它所遇到的问题。但是,actor模型以一种合理的方式解决了这些问题,使系统能够按我们想象的方式去运行,并且不需要改变我们之前的编程经验。Actor模型允许我们从信息交流的方式去考虑我们的代码,而不像传统编程中类似大型组织中的人员互相交流。

Actor模型允许我们:

1、在不使用锁的情况下维持封装的结构。

2、在协作的环境下,通过发送信号来改变协作实体的状态。通过相互发送信息来推动整个用应用的运行。

3、这个模型不会与我们之前的编程经验冲突。

使用消息传递的方式避免了锁和阻塞

Actor不同于过去方法调用的方式,而是通过相互发送信息进行交互。执行任务的线程不会通过信息被传递到接收者,所以一个actor实体可以在发送完信息之后继续运行其他的任务而不会被阻塞。因此,使用actor模型可以在相同时间内完成更多的工作。

在OOP编程里,当方法返回时,它将释放对执行线程的控制,actor模型在这点与OOP很相似。当actor实体执行完毕当前的信息之后,它会对信息做出响应并返回执行。通过这种方式,actor完成了我们想象中的对象执行过程:

这里写图片描述

信息传递和方法调用之间的一个重要的区别就是信息传递没有返回值。Actor通过发送信息来向其他actor委托任务,如果我们希望它有返回值,那么发送信息的actor就需要被阻塞或者在当前线程上运行接收者的任务。而actor模型的做法是让接收线程通过传递消息来传递运行结果。

第二个重要的方面就是actor模型恢复了对象的封装。Actor对消息的响应就如同调用对象的方法一样。不同的是,actor以序列的方式来处理消息,一次处理一个消息,并且消息的发送者和接受者可以独立地运行不受相互干扰。这种运行方式避免了传统多线程编程中多个线程并发对对象封装的破坏。因此每个actor按顺序执行它所接收到的消息,不同的actor就可以并行地工作,这样整个系统就可以充分发挥硬件的并行能力。

由于每个actor每个时刻只能处理一个消息,所以actor内的变量可以不需要同步,这就避免了对代码加锁:

这里写图片描述

总之,当一个actor接收到消息时会发生以下情况:

1、actor将消息放在队列的末尾

2、如果actor没有被安排执行,则标记它为准备执行

3、一个(隐藏的)调度器会将这个actor启动执行

4、Actor从队列的顶端获取消息

5、Actor更新内部状态,并且向其他actor发送消息

6、Actor被取消调度

为了完成这些工作,actor需要拥有:

1、邮箱(消息最终会到达的存储队列)

2、行为(actor的内部状态)

3、消息(表示信号的数据片段,就像方法调用参数一样)

4、执行环境(调用actor的消息处理代码使其能对消息作出回应的机制)

5、地址(后续会讲到)

当消息进入到actor的邮箱时,actor的行为表现了其对消息的响应方式。运行环境会对其拥有的线程池进行分配,从而驱动所有的actor运行,而这些对actor都是透明的。

Actor是一个很简单的模型,但是它解决了之前列举的问题:

1、通过信令传递的方式将执行程序解耦,从而维持了对象的封装(方法调用传递执行环境,但是消息传递不这么做)

2、没有必要使用锁,actor的内部状态只能通过传递消息来改变,并且同一时刻只有一个消息会被处理,这就消除了传统编程中线程争用导致的问题。

3、没有任何地方使用锁,并且消息发送者不会被阻塞。在十几个线程上可以有效安排数百万个actor。这充分发挥了现代CPU的潜力。通过消息进行任务委托是actor模型的常用操作模式。

4、Actor的内部状态是本地的,并且不被共享和改变。数据通过消息进行传递,就像现代存储的运行方式一样(which maps to how modern memory hierarchy actually works)。在很多情况下,这意味着可以通过高速缓存进行消息传递,而把本地状态和临时数据放在原始CPU核中。这个模型也恰好和远程通信类似:

将状态保存在本机的RAM中,变化/数据作为数据包在网络中传递。

Actor可以优雅地处理错误

由于我们不再通过调用栈来让发送者和接受者互相通信,我们就可以用一种不同的方式来处理错误。我们需要考虑以下两点:

1、第一种情况,如果是由于任务中的错误导致(通常是一些校验问题,比如用户标识不存在)任务的失败。在这种情况下,执行actor上的封装不会被错误破坏,只是这个任务是失败的。执行actor应该用消息来回复发件人,并说明错误的情况。这里没有什么特别的地方,错误是领域的一部分,因此就是一个普通的消息。

2、第二种情况,如果服务本身遇到了内部错误。Akka会强制所有actor被组织成一个树状层析结构,如果一个actor是被另一个actor创建的,那么它们就互为父子关系,创建者为被创建者的父actor。这就和操作系统组织其内部的进程树的结构是一样的。就像进程一样,如果一个actor失败了,它的父actor会被通知,这时候父actor就可以对这个错误作出反应。另外,如果父actor被停止了,那么其所有的子actor都会被停止。这种机制被称为监督,是akka的核心。

这里写图片描述

监管者(父actor)可以根据其子actor的错误类型来决定重启它的子actor还是将它彻底停止。子actor永远不会默默地死去(死循环除外),它们要么失败,在这种情况下父actor会对错误作出反应;要么停止(在这种情况下,感兴趣的人会被自动通知)。总会存在一个监管者来管理一个actor,就是它的父actor。Actor的重启是对外部透明的,actor在重启时,和其协作的actor依旧可以向它发送消息。

现在,我们来简单介绍下akka提供的功能。

转载于:https://www.cnblogs.com/wangbinquan/p/9061245.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值