akka入门与实践(读书摘要)

第1章 初识Actor

概述

Actor是一种并发计算的理论模型,akka是Actor模型的一种实现,通常是指一个分布式工具集,用于协调远程计算资源来进行一些工作。

Actor模型的起源

Actor模型来源于1973年发表的名为《A Universal Modular Acotr Formalism For Atrifical Intelligence》论文,该论文提出了并发计算的理论模型。在Actor模型中,actor是一个并发原语。

Actor模型的一些概念

  • Actor:表示一个节点的并发原语,同步处理接收到的消息。
  • 消息:actor之间通信的数据(数据载体)。
  • 消息传递:一种软件开发范式,通过传递消息来触发各种行为,包括状态的变更。
  • 邮箱地址:消息传递的目标地址。
  • 邮箱:存储消息的仓库,或者称之为消息队列。
  • Actor系统:多个Actor的集合。

好处:

  1. 使得并发事件分析变得清晰。
  2. 消除共享状态。

第2章 Actor与并发

响应式系统设计

Akka也被称作一种响应式平台,更具体的说,是typesafe响应式平台的一部分。响应式宣言四准则:灵敏性、伸缩性、容错性、事件驱动/消息驱动。

剖析actor

package com.example

import akka.actor.{Actor, ActorLogging, ActorSystem, Props, Status}


object PongActor {
  def props(resp:String):Props = Props.create(classOf[PongActor],resp)
}
class PongActor(val msg:String) extends Actor with ActorLogging{
  override def receive: Receive = {
    case "Ping" => {
      log.info(s"receive ping from (${sender()})")
    }
    case _ => sender() ! Status.Failure(new Exception("Unknown Message"))
  }
}
object AkkaPingPong extends App {
  val system = ActorSystem.create("pong")
  val pongActor1 = system.actorOf(PongActor.props("pong"),"hello")
  val ponpActor2 = system.actorSelection("akka://pong/user/hello")
  ponpActor2 ! "Ping"
  pongActor1 ! "Ping"
  pongActor1 ! "Pong"
}

actor路径

  • akka://ActorSystemName/user/HelloWorldActor
  • akka.tcp://ActorSystemName@remote-host:port/user/HelloWorldActor

注意: 该章节有个K-V数据库的实例,看完所有章节后可以代码实现一下。

第3章 传递消息

消息传递模式

  • Tell
  • Ask
  • Forward
  • Pipe

Ask消息模式

在调用ask向Actor发起请求时,ask会先返回一个Future作为结果第占位符,同事会创建一个临时Actor,sender()函数指向的即为这个临时Actor的引用,当计算技术,临时Actor会使用返回的相应来完成Future,注意,这种模式下,返回消息并不直接传递给sender邮箱。该模式下,需要设置超时时间。注意Future回调函数的执行是在另一个线程上。

Tell消息模式

tell是一种称为fire and forgetd的非阻塞的调用方式,tell之后,消息只是被放在receiver的邮箱中,该模式需要填充sender,如果不填充,不设置任何默认邮箱(DeadLetters),

Forward消息模式

当一个actor接受到一个消息时,将该消息转发给另一个actor,sender()指向的还是原始的发送者而非当前转发者,除此之外,和tell模式并无区别。

Pipe消息模式

该模式旨在将Future转发给sender()或者另一个Actor。该模式产生的背景在于Future中如果需要使用Sender,需要临时存储sender()的值,原因在于sender()返回结果跟上下文有关,而Future回调函数的执行是在另一个线程中,故而产生pipe这种模式。

第4章 Actor的生命周期

分布式计算的8个误区

  • 网络是可靠的
  • 没有延迟
  • 带宽是无限的
  • 网络是安全的
  • 网络拓扑不会改变
  • 只有一个管理员
  • 网络传输没有开销
  • 网络是同构的

监督

Akka借鉴了ErLang的监督机制,采用层级监督,每个Father监督所有的Children,顶层的Actor节点为/,actorOf创建的actor都在/user下面,监督事件都发生在/system下的actor。

监督策略:

  • 继续(resume):Actor继续处理下一条消息。
  • 停止(stop):停止Actor,不再做任何操作。
  • 重启(restart):新建一个Actor,代替原来的Actor。
  • 向上反应(esclate):将异常消息传递给上一个监督者。

默认监督策略

  • Actor运行过程中发生异常:reatart
  • Actor运行过程中发生错误:esclate
  • Actor初始化过程中发生异常:stop
  • ActorKilledException:stop

Actor生命周期

preRestart和postRestart只在重启的时候会调用,preRestart默认会调用postStart,postRestart默认调用preStart。

终止或kill一个Actor

  • ActorSystem.stop(actorRef)
  • ActorContext.stop(actorRef)
  • 给Actor发送一条PosionKill消息
  • 给Actor发送一条Kill消息

调用context.stop或system.stop会导致Actor立即停止;发送PosionKill消息会在Actor处理完给消息后才停止,和普通消息并没有区别;kill并不会马上停止Actor,会导致Actor抛出一个ActorKillException异常,由监督机制来决定。

生命周期监控

Actor可以对其他任何Actor进行监控,采用context.watch(actorRef)即可做到这一点,调用context.unwatch(actorRerf)可以取消监控,当被监控Actor终止时,负责监控当Actor会收到一条Terminated(actorRef)消息。

状态

改变Actor行为的机制

  • 基于Actor状态的条件语句
  • 热交换(become/unbecome)
  • 有限状态机

注意:akka提供stash操作,如果当前状态不可用,可以采用stash,将某些消息放在一个独立的队列中,消息该队列一处,当状态可用是,采用unstash操作,将独立队列中的消息重新放回邮箱。

第5章 纵向扩展

akka提供了两种多核并发编程的抽象:Future和Actor。

Router

Router是一个用于负载均衡和路由的抽象,分为Group和Pool两种。

路由逻辑

 

dispatcher

Dispatcher解析

Dispatcher基于Executor,将如何执行任务和何时执行任务解耦,一般来说,dispatcher会包含一些线程,这些线程负责调度并运行任务,比如处理Actor的消息以及线程中的Future事件。

Executor

  • ThreadPool Executor:有一个工作队列,包含了要分配给各线程的任务,允许线程重用,减少了线程创建与销毁的开销。
  • ForkJoinPool Executor:使用一种分治算法,递归的将任务分解成一系列子任务,由各线程执行子任务,并合并结果。因为某些任务无法被递归分解成子任务,因此又提供了一种窃取算法,允许某些空闲线程窃取另一个线程的工作。一般情况下,该方案比ThreadPool效率要高。

dispatcher分类

  • Dispatcher:默认的Dispatcher,将使用定义的Executor。
  • PinnedDispatcher:给每个Actor都分配自己独有的线程,每个Actor一个ThreadPoolExecutor,该线程池只有一个线程,一般用于需要处理很多重要的工作场景。
  • CallingThreadDispatcher:没有Executor,在发起调用的线程上执行,一般用于测试。
  • BalancingPoolDispatcher:Pool中的所有Actor都共享一个邮箱,该方式目前已不推荐使用。

第6章 横向扩展

集群

是一组松散或紧密连接在一起工作的计算机。由于这些计算机协同工作,在许多方面它们可以被视为单个系统。 --维基百科

失败检测

akka通过在节点建发送心跳消息并接受相应来进行失败检测,节点只和相邻的几个节点发送心跳消息。当发现事故后,通过gossip协议进行传播,以达到最终一致性。

CAP

  • Consistency
  • Availability
  • Partition Tolerance

CP系统-一致性优先

Redis和具有冗余备份当RDBMS都属于这种。

AP系统-可用性优先

Cassandra和Riak属于这种。

使用Akka Cluster构建系统

配置

种子节点

当一个节点想要加入集群时,需要先连接种子节点,由种子节点通过gossip协议将其地址发布到整个集群,如果第一个连接失败,尝试连接第二个,一般而言,最少需要两个种子节点。

集群成员状态

  • joining(leader将其标记为up)
  • up
  • leaving(leader将其标记为removed)
  • removed
  • memberUnreachable(leader将其标记为down)
  • down(只能重启,重新加入集群)

第7章 邮箱

熔断

熔断机制会监控应用程序某些部分的响应延迟或者错误。消息会首先发送给熔断器,熔断器会监控相应时间,最初状态为关闭,如果监控到响应时间超过上线,则熔断器状态改为开启。

 

熔断器处于开启状态,会拒绝所有收到到请求。 

一段时间后,熔断器会将状态改为半开,尝试者接受请求,如果很快能得到相应,则认为已经恢复,状态改为关闭。

 

思维导图

阅读文档:《akka入门与实践》

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内容简介 本书将尝试帮助入门级、中级以及高级读者理解基本的分布式计算概念,并且展示 如何使用 Akka 来构建具备高容错性、可以横向扩展的分布式网络应用程序。Akka 是一 个强大的工具集,提供了很多选项,可以对在本地机器上处理或网络远程机器上处理的 某项工作进行抽象封装,使之对开发者不可见。本书将介绍各种概念,帮助读者理解 网络上各系统进行交互的困难之处,并介绍如何使用 Akka 提供的解决方案来解决这些 问题。 作者简介 Jason Goodwin 是一个基本上通过自学成才的开发者。他颇具企业家精神,在学校 学习商学。不过他从 15 岁起就开始学习编程,并且一直对技术保持着浓厚的兴趣。这对 他的职业生涯产生了重要的影响,从商学转向了软件开发。现在他主要从事大规模分布 式系统的开发。在业余时间,他喜欢自己原创电子音乐。 他在 mDialog 公司第一次接触到 Akka 项目。mDialog 是一家使用 Scala/Akka 的公司, 为主流出版商提供视频广告插入软件。这家公司最终被 Google 收购。他同时还是一名很 有影响力的“技术控”,将 Akka 引入加拿大一家主要的电信公司,帮助该公司为客户提 供容错性更高、响应更及时的软件。除此之 外,他还为该公司中的一些团队教授 Akka、 函数式以及并发编程等知识。 目录 第 1 章 初识 Actor:Akka 工具集以及 Actor 模型的介绍。 第 2 章 Actor 与并发:响应式编程。Actor 与 Future 的使用。 第 3 章 传递消息:消息传递模式。 第 4 章 Actor 的生命周期—处理状态与错误:Actor 生命周期、监督机制、Stash/ Unstash、Become/Unbecome 以及有限自动机。 第 5 章 纵向扩展:并发编程、Router Group/Pool、Dispatcher、阻塞 I/O 的处理以 及 API。 第 6 章 横向扩展—集群化:集群、CAP 理论以及 Akka Cluster。 第 7 章 处理邮箱问题:加大邮箱负载、不同邮箱的选择、熔断机制。 第 8 章 测试与设计:行为说明、领域驱动设计以及 Akka Testkit。 第 9 章 尾声:其他 Akka 特性。下一步需要学习的知识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值