资讯专栏INFORMATION COLUMN

Akka系列(一):Akka简介与Actor模型

PingCAP / 1647人阅读

摘要:是一个构建在上,基于模型的的并发框架,为构建伸缩性强,有弹性的响应式并发应用提高更好的平台。上述例子中的信件就相当于中的消息,与之间只能通过消息通信。当然模型比这要复杂的多,这里主要是简洁的阐述一下模型的概念。模型的出现解决了这个问题。

Akka是一个构建在JVM上,基于Actor模型的的并发框架,为构建伸缩性强,有弹性的响应式并发应用提高更好的平台。本文主要是个人对Akka的学习和应用中的一些理解。

Actor模型

Akka的核心就是Actor,所以不得不说Actor,Actor模型我通俗的举个例子,假定现实中的两个人,他们只知道对方的地址,他们想要交流,给对方传递信息,但是又没有手机,电话,网络之类的其他途径,所以他们之间只能用信件传递消息,很像现实中的的邮政系统,你要寄一封信,只需根据地址把信投寄到相应的信箱中,具体它是如何帮你处理送达的,你就不需要了解了,你也有可能收到收信人的回复,这相当于消息反馈。上述例子中的信件就相当于Actor中的消息,Actor与Actor之间只能通过消息通信。当然Actor模型比这要复杂的多,这里主要是简洁的阐述一下Actor模型的概念。

Akka中Actors模型

对并发模型进行了更高的抽象

异步、非阻塞、高性能的事件驱动编程模型

轻量级事件处理(1GB内存可容纳百万级别个Actor)

为什么Actor模型是一种处理并发问题的解决方案?

一开始我也不怎么理解,脑子里的一贯思维是处理并发问题就是如何保证共享数据的一致性和正确性,为什么会有保持共享数据正确性这个问题呢?无非是我们的程序是多线程的,多个线程对同一个数据进行修改,若不加同步条件,势必会造成数据污染。那么我们是不是可以转换一下思维,用单线程去处理相应的请求,但是又有人会问了,若是用单线程处理,那系统的性能又如何保证。Actor模型的出现解决了这个问题。

Actor模型概图:

从上图中我们可以看到,Actor与Actor之前只能用消息进行通信,当某一个Actor给另外一个Actor发消息,消息是有顺序的,你只需要将消息投寄的相应的邮箱,至于对方Actor怎么处理你的消息你并不知道,当然你也可等待它的回复。

JVM中的Actor有以下几个特点:

每个Actor都有对应一个邮箱

Actor是串行处理消息的

Actor中的消息是不可变的

其实只从上面一些描述来看,并不能看出Actor在处理并发问题上的有什么优势。

但我总结了两点:简化并发编程提升程序性能

1.简化并发编程:

我们一开始说过并发导致最大的问题就是对共享数据的操作,我们在面对并发问题时多采用的是
用锁去保证共享数据的一致性,但这同样也会带来其他相关问题,比如要去考虑锁的粒度(对方法,程序块等),锁的形式(读锁,写锁等)等问题,这些问题对并发程序来说是至关重要的,但一个初写并发程序的程序员来说,往往不能掌控的很好,这无疑给程序员在编程上提高了复杂性,而且还不容易掌控,但使用Actor就不导致这些问题,首先Actor的消息特性就觉得了在与Actor通信上不会有共享数据的困扰,另外在Actor内部是串行处理消息的,同样不会对Actor内的数据造成污染,用Actor编写并发程序无疑大大降低了编码的复杂度。

2.提升程序性能:

我们之前说过既然用单线程处理,那如何保证程序的性能?首先Actor是非常轻量级的,你可以再程序中创建许多个Actor,而且Actor是异步的,那么如何利用它的这个特性呢,我们要做的就是把相应的并发事件尽可能的分割成一个个小的事件,让每个Actor去处理相应的小事件,充分去利用它异步的特点,来提升程序的性能。

其实Scala中原生的Actor并不能完成很多事,不是一套完整的并发解决方案,不适合用于生产环境,比如错误恢复,状态持久化等,所以在较新版本的Scala类库中,Akka包已经取代了原生的Actor。

Akka

那下面我们来简单说说Akka吧,Akka作为一套成熟的并发解决方案,已经被业界大量采用,尤其是在金融,游戏等领域,Akka中的容错机制,持久化,远程调用,日志等都是很重要的模块,这些内容都会在这个系列的后续文章里一一讲解。下面就以一个入门Akka程序来结束本篇文章吧。现在我们假设有一个家居机器人,我们只需要给它发送消息它便会帮我们处理相应的事情,现在我们用程序来模拟这个场景:源码链接

本示例使用Scala语言,构建工具为SBT,IDE为IntelliJ IDEA.

1.首先创建一个基于SBT的Scala工程

build.sbt配置:

name := "Example_01"

version := "1.0"

scalaVersion := "2.11.8"

val akkaVersion   = "2.4.16"

libraryDependencies +=
  "com.typesafe.akka" %% "akka-actor" % akkaVersion

2.我们来定义一些消息:

trait Action{
  val message: String
  val time: Int
}

case class TurnOnLight(time: Int) extends Action {   // 开灯消息
  val message = "Turn on the living room light"
}

case class BoilWater(time: Int) extends Action {   // 烧水消息
  val message = "Burn a pot of water"
}

3.我们利用Actor来实现一个模拟机器人:

class RobotActor extends Actor {
  val log = Logging(context.system, this)
  def receive: Receive = { //机器人接受指令
    case t: TurnOnLight => log.info(s"${t.message} after ${t.time} hour")
    case b: BoilWater => log.info(s"${b.message} after ${b.time} hour")
    case _ => log.info("I can not handle this message")
  }
}

4.我们去测试这个机器人:

object Example_01 extends App {
  val actorSyatem = ActorSystem("robot-system") 
  val robotActor = actorSyatem.actorOf(Props(new RobotActor()), "robotActor") //创建一个机器人
  robotActor ! TurnOnLight(1) //给机器人发送一个开灯命令
  robotActor ! BoilWater(2) //给机器人发送一个烧水命令
  robotActor ! "who are you" //给机器人发送一个任意命令
  actorSyatem terminate ()
}

5.运行结果

[INFO] [03/19/2017 13:48:05.622] [robot-system-akka.actor.default-dispatcher-4] [akka://robot-system/user/robotActor] Turn on the living room light after 1 hour
[INFO] [03/19/2017 13:48:05.622] [robot-system-akka.actor.default-dispatcher-4] [akka://robot-system/user/robotActor] Burn a pot of water after 2 hour
[INFO] [03/19/2017 13:48:05.622] [robot-system-akka.actor.default-dispatcher-4] [akka://robot-system/user/robotActor] I can not handle this message

上面是一个非常简单的Akka例子,我们首先创建了一个机器人的Actor,然后通过向它发送不同指令,让它根据指令去做相应的事情,大家可以自己尝试去写一写相似的例子。

这篇就先到这里了,下一篇主要给大家讲讲Akka中Actor的分层结构。有兴趣的同学也可以关注我的个人博客

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69953.html

相关文章

  • Akka系列(二):Akka中的Actor系统

    摘要:模型作为中最核心的概念,所以在中的组织结构也至关重要,本文主要介绍中系统。这里主要是演示可以根据配置文件的内容去加载相应的环境,并应用到整个中,这对于我们配置环境来说是非常方便的。路径与地址熟悉类系统的同学应该对路径这个概念很熟悉了。 Actor模型作为Akka中最核心的概念,所以Actor在Akka中的组织结构也至关重要,本文主要介绍Akka中Actor系统。 Actor系统 Act...

    BlackFlagBin 评论0 收藏0
  • 关于分布式计算的些概念

    摘要:关于三者的一些概括总结离线分析框架,适合离线的复杂的大数据处理内存计算框架,适合在线离线快速的大数据处理流式计算框架,适合在线的实时的大数据处理我是一个以架构师为年之内目标的小小白。 整理自《架构解密从分布式到微服务》第七章——聊聊分布式计算.做了相应补充和修改。 [TOC] 前言 不管是网络、内存、还是存储的分布式,它们最终目的都是为了实现计算的分布式:数据在各个计算机节点上流动,同...

    Ververica 评论0 收藏0
  • Akka系列(四):Akka中的共享内存模型

    摘要:共享内存相信对并发有所了解的同学都应该知道在推出后,对内存管理有了更高标准的规范了,这使我们开发并发程序也有更好的标准了,不会有一些模糊的定义导致的无法确定的错误。 通过前几篇的学习,相信大家对Akka应该有所了解了,都说解决并发哪家强,JVM上面找Akka,那么Akka到底在解决并发问题上帮我们做了什么呢? 共享内存 众所周知,在处理并发问题上面,最核心的一部分就是如何处理共享内存,...

    baukh789 评论0 收藏0
  • Akka系列(七):Actor持久化之Akka persistence

    摘要:源码链接进阶持久化插件有同学可能会问,我对不是很熟悉亦或者觉得单机存储并不是安全,有没有支持分布式数据存储的插件呢,比如某爸的云数据库答案当然是有咯,良心的我当然是帮你们都找好咯。 这次把这部分内容提到现在写,是因为这段时间开发的项目刚好在这一块遇到了一些难点,所以准备把经验分享给大家,我们在使用Akka时,会经常遇到一些存储Actor内部状态的场景,在系统正常运行的情况下,我们不需要...

    miguel.jiang 评论0 收藏0
  • Akka系列(六):Actor解决了什么问题?

    摘要:原文链接解决了什么问题使用模型来克服传统面向对象编程模型的局限性,并应对高并发分布式系统所带来的挑战。在某些情况,这个问题可能会变得更糟糕,工作线程发生了错误但是其自身却无法恢复。 这段时间由于忙毕业前前后后的事情,拖更了很久,表示非常抱歉,回归后的第一篇文章主要是看到了Akka最新文档中写的What problems does the actor model solve?,阅读完后觉...

    Carson 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<