AKKA是什么

AKKA是一套开源库,用于设计跨处理器和跨网络的可扩展弹性系统。Akka允许开发者专注于满足业务需求,而不是编写低级代码以提供可靠的行为,容错和高性能。

分布式系统环境中,组件崩溃而不响应,消息丢失而没有线路上的跟踪,并且网络延迟会发生波动。这些问题经常发生在精心管 理的数据中心内部环境中 - 在虚拟化体系结构中更是如此。

为了帮助您处理这些现实问题,Akka提供:

  • 多线程行为,不使用原子或锁等低级并发结构 - 使您甚至不必考虑内存可见性问题。
  • 系统及其组件之间的透明远程通信 - 使您免于编写和维护困难的网络代码。
  • 集群,高可用性架构,具有弹性,可按需扩展或扩展 - 使您能够提供真正的响应式系统。

为什么使用Akka(为什么现代系统需要一个新的编程模型)

(1)封装的挑战

OOP的核心支柱是封装。封装规定对象的内部数据不能直接从外部访问; 它只能通过调用一组策划方法来修改。该对象负责公开保护其封装数据的不变性的安全操作。

当我们分析OOP运行时行为时,我们有时会绘制一个消息序列图,显示方法调用的交互。例如:

不幸的是,上图不能准确地表示执行期间实例的生命线。实际上,线程执行所有这些调用,并且不变量的强制发生在调用该方法的同一线程上。使用执行线程更新图表,它看起来像这样:

但当多线程的情况下,我们整齐地绘制的图表变得不充分。有的时候会有多个线程访问同一个实例。

有一个执行部分,其中两个线程进入相同的方法。不幸的是,对象的封装模型并不保证该部分中发生的事情。两个调用的指令可以以任意方式交错。这种情况会在多线程的情况下更加复杂。

解决此问题的常用方法是围绕这些方法添加锁定。虽然这确保了在任何给定时间最多只有一个线程将进入该方法,但这是一个非常昂贵的策略:

  • 锁严重限制了并发性,它们在现代CPU架构上非常昂贵,需要从操作系统中重载以暂停线程并在以后恢复它。
  • 调用者线程现在被阻止,因此它无法执行任何其他有意义的工作。即使在桌面应用程序中这也是不可接受的,我们希望即使在长后台作业运行时,也要保持面向用户的应用程序部分(其UI)能够响应。在后端,阻塞是彻头彻尾的浪费。有人可能认为这可以通过启动新线程来补偿,但线程也是一种代价高昂的抽象。
  • Locks引入了一个新的威胁:死锁。

这些现实导致了一个局面:

此外,锁只能在本地很好地工作。在协调跨多台机器时,唯一的选择是分布式锁。不幸的是,分布式锁定的效率比本地锁定效率低几个级别,并且通常会在扩展时施加限制。分布式锁定协议需要在多台计算机上通过网络进行多次通信往返,因此造成大量延迟。

在面向对象语言中,我们很少考虑线程或线性执行路径。我们经常将系统设想为对象实例的网络,它们对方法调用作出反应,修改其内部状态,然后通过驱动整个应用程序状态的方法调用相互通信:

但是,在多线程分布式环境中,实际发生的是线程通过以下方法调用“遍历”此对象实例网络。

  • 没有足够的锁,状态就会被破坏。
  • 由于存在许多锁定,性能会受到影响并且很容易导致死锁。

总结

(2) 现代计算机体系结构中共享内存的错觉

  • 对象只能保证面对单线程访问时的封装(保护不变量),多线程执行几乎总会导致内部状态损坏。
  • 虽然锁似乎是支持多线程封装的自然补救措施,但实际上它们效率低,并且在任何实际规模的应用中都容易导致死锁。
  • 锁在本地工作,尝试使它们分布存在,但提供扩展潜力十分有限。

在现代架构上 - 如果我们稍微简化一下 - CPU正在写入缓存,而不是直接写入内存。这些高速缓存中的大多数都是CPU内核的本地高速缓存,也就是说,一个内核的写入不会被另一个内核看到。为了使本地更改对另一个核心可见,从而对另一个线程可见,需要将缓存行传送到另一个核心的缓存。

在JVM上,我们必须使用volatile标记或Atomic包装器明确表示要跨线程共享的内存位置。否则,我们只能在锁定的部分访问它们。为什么我们不将所有变量标记为volatile?因为跨核心运送缓存行是一项非常昂贵的操作!这样做会隐含地使所涉及的核心停止执行额外的工作,并导致高速缓存一致性协议(协议CPU用于在主存储器和其他CPU之间传输高速缓存线)的瓶颈。结果是放缓的幅度。

总结

(3)调用堆栈的错觉

当线程打算将任务委托给“后台”时会出现问题。实际上,这实际上意味着委托给另一个线程。通常发生的是,“调用者”将一个对象放入由工作线程(“被调用者”)共享的内存位置,然后工作线程在某个事件循环中将其拾取。这允许“调用者”线程继续前进并执行其他任务。

问题是:如何通知“调用者”完成任务?但是当任务因异常而失败时会出现更严重的问题。异常传播到哪里?它将传播到工作线程的异常处理程序,完全忽略了实际的“调用者”是谁:

  • 没有真正的共享内存,CPU核心就像网络上的计算机一样明确地将数据块(高速缓存行)传递给彼此。CPU间通信和网络通信比许多人意识到的更为共同。现在可以通过CPU或联网计算机传递消息。
  • 不是通过标记为共享或使用原子数据结构的变量隐藏消息传递方面,而是更有纪律和原则性的方法是将状态本地保持为并发实体,并通过消息显式地在并发实体之间传播数据或事件。

这是一个严重的问题。工作线程如何处理这种情况?它可能无法解决问题,因为它通常无视任务失败的目的。需要以某种方式通知“调用者”线程,但没有调用堆栈可以解除异常。失败通知只能通过旁道进行,例如将错误代码置于“调用者”线程否则预期结果准备好的位置。如果没有这个通知,“调用者”永远不会收到失败通知,任务就会丢失!这与网络系统如何在没有任何通知的情况下丢失/失败消息/请求的情况类似。

当事情出现问题时,这种糟糕的情况会变得更糟,并且由线程支持的工作人员遇到错误并最终处于无法恢复的状态。例如,由bug引起的内部异常会冒泡到线程的根目录并使线程关闭。这立即引发了一个问题,谁应该重新启动线程托管的服务的正常操作,以及如何将其恢复到已知良好的状态?乍一看,这似乎是可以管理的,但我们突然面临一个新的意外现象:线程当前正在处理的实际任务不再位于从中获取任务的共享内存位置(通常是队列) )。事实上,由于异常到达顶部,展开所有调用堆栈,任务状态完全丢失!我们已经丢失了一条消息,即使这是本地通信而没有涉及网络(消息丢失是预期的)。

综上所述:

本文翻译自akka官方文档,并添加了部分个人理解如有需要请参考  https://akka.io/docs/

  • 为了在当前系统上实现任何有意义的并发性和性能,线程必须以有效的方式在彼此之间委派任务而不会阻塞。使用这种任务委托并发方式(对于网络/分布式计算更是如此),基于调用堆栈的错误处理会中断,并且需要引入新的,明确的错误信令机制。失败成为域模型的一部分。
  • 具有工作委托的并发系统需要处理服务故障并具有从中恢复的原则性方法。此类服务的客户端需要知道任务/消息可能在重新启动期间丢失。即使没有发生丢失,由于先前排队的任务(长队列),垃圾收集造成的延迟等,响应可能会被任意延迟。面对这些,并发系统应该以超时的形式处理响应期限 ,像网络/分布式系统。

Akka入门(一)Akka简介与为什么使用Akka相关推荐

  1. akka入门系列-0. 概述

    0. 概述 本节类似图书里的前言,旨在说明这一系列文章的写作目的.目标读者等内容. 写作目的 本系列写作的最主要目的是用输出倒逼输入,协助自己理清思路,分享是其次的. 由于最近的项目里使用到了akka ...

  2. Scala进阶之路-并发编程模型Akka入门篇

    Scala进阶之路-并发编程模型Akka入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Akka Actor介绍 1>.Akka介绍 写并发程序很难.程序员不得不处 ...

  3. Akka 入门 实战

    疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 面试必备 + 面试必备 [博客园总入口 ] 疯狂创客圈 经典图书 : <Sprin ...

  4. Windows通用克隆系统入门基础知识简介

    Windows通用克隆系统入门基础知识简介 这里的Windows是指微软的Windows 2000/XP/2003(后文中未经说明的,凡是Windows均指这三种系统):所谓的通用克隆,俗名万能克隆, ...

  5. Matlab编程入门指南:简介、安装、学习路线和几十个编程案例分析。

    一.Matlab编程入门指南:简介.安装.学习路线和几十个编程案例分析. 1.Matlab编程语言是一种广泛应用于科学计算.工程计算.数据分析.统计分析.信号处理等领域的高级数值计算和数据可视化软件. ...

  6. HTML5菜鸟入门指导:简介、平台搭建、示例演示

    HTML5菜鸟入门指导:简介.平台搭建.示例演示 一.HTML5简介 1.  了解HTML (1).什么是HTML? HTML是用来描述网页的一种语言: HTML指超文本标记语言(Hyper Text ...

  7. Elasticsearch7从入门到精通(简介、部署、原理、开发、ELK)

    Elasticsearch7从入门到精通(简介.部署.原理.开发.ELK) 第1章.Elasticsearch简介 1-1.Elasticsearch介绍 Elasticsearch官方网站:http ...

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

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

  9. 【完整代码】Scala akka入门示例

    package com.zxl.akkaimport akka.actor.{Actor, ActorRef, ActorSystem, Props} //说明 //1. 当我们继承 Actor 后, ...

最新文章

  1. wxWidgets:向后兼容
  2. html上传预览图片原理,关于html中图片上传预览的实现
  3. Invalid bound statement (not found)解决办法
  4. .net byte转java byte_Java 最小值之谜
  5. SQL73 考试分数(二)
  6. 1.3 将临时变量内联化
  7. php中级联,php级联
  8. EWSA1.50.0.298栈溢出错误
  9. 同步时钟与异步时钟介绍
  10. 卡斯卡迪亚社区建设者奖:2017年获胜者公布
  11. Drupal项目实战-公司订餐系统
  12. 【香橙派4B】1、重刷系统
  13. Pinocchio——将.arith文件转换为qap及做相应的prove/verify操作
  14. zeroMQ支持PGM协议编译
  15. DMSP/OLS夜间灯光数据——应用
  16. sql trace基础
  17. python 图像批量png转jpg格式
  18. 实时流媒体视频监控系统——的流媒体客户端——视频解码处理
  19. 【概率论与数理统计】
  20. 软考 java程序设计,软考程序员考点Java语言程序设计之控制流语句分类

热门文章

  1. windows10访问ubuntu samba共享文件夹报错:不允许一个用户使用一个以上用户与服务器多重连接(没解决)
  2. linux ubuntu QT 下载和安装(Qt Creator)
  3. Jupyter notebook中用python matplotlib ax3.plot_surface绘制的三维图(3D图)(三维函数)无法旋转解决办法(%matplotlib notebook)
  4. python matplotlab在jupyter notebook中画图不显示怎么办?(%matplotlib inline)
  5. 给IDEA给类和方法添加注解
  6. linun——SElinux的简单理解
  7. Median断点法求区间-匹配-memset数组与vector
  8. SpringBoot @PostConstruct和@PreDestroy使用详解
  9. SpringCloud--Eureka服务注册与发现 Eureka 集群搭建 详细案例!!!
  10. java中dateformat类的作用_java-SimpleDateFormat类中可用的日期格式是什么?