聊聊Akka

Akka简介

当前社会,人们越来越享受互联网带来的种种便利,同时也对互联网产品有了更高的要求,比如更快的响应速度和更稳定的服务;另一方面,互联网产品在不断发展的过程中也面临着非常多的技术挑战,比如服务化、分布式、并行计算等,那么,Akka在其中的哪些领域可以一展身手呢?

技术背景

在产品不断发展的过程中,一个不可忽视的挑战是大数据带来的存储和计算问题,存储暂且不表(Akka不直接提供数据存储的方案,当然,在Akka的基础上也可以实现类似的分布式文件存储系统),我们来看看数据的计算问题。

在一个系统中,数据的来源非常广,比如用户交易数据、历史记录、系统日志等,当数据积累到一定程度后(变成Big Data),我们就得考虑挖掘其价值。

以电商为例,当用户打开浏览器输入域名并按下回车键的那一刻开始,系统就默默地在记录用户数据了,比如访问时间、终端设备类型、用户ip等;当用户看到某个商品并点击链接后,系统会收集并更新商品点击数(当然,也有可能是广告);当用户满怀期望地加入购物车后,系统会把该商品记录到用户的“意向清单”;当用户毫不犹豫地完成支付时,系统已经生成订单数据并考虑向你推荐其他匹配商品了(笑)。这是笔者虚拟出来的一个数据收集场景,在实际项目中,收集的数据维度只会比这更多,生成的数据量也会更大。很多大型的电商平台(比如亚马逊、淘宝等)都有自己的“个性化推荐系统”,该系统会根据大量的历史数据(比如浏览、购买、交易,评论等)预测(计算)出用户可能的喜好,以此做出合理的商品推荐,进而提升购买转化率。

面对大量的计算任务,系统怎样才能快速实时地得到想要的结果呢?很显然,依靠单核CPU的处理能力已不足以进行如此密集的计算(摩尔定律的失效),一般情况下,我们的解决方案是:把计算拆分成多个子任务实现并行(单机多核或分布式集群)执行。在Java中,我们可以通过Fork/Join等框架来实现单机的并行程序,但是假如想要在单机或分布式都能以相同的模式去处理计算,很明显这些框架是远远不够的,除此之外,我们还必须考虑多节点计算时的容错,分布式通信等问题。

由此可见,要从头实现这样一个解决方案并非易事,很多时候,我们希望选择一款设计精良,易于使用的框架来处理这些问题,而Akka正是为此而生!

Akka是什么

Akka是一款高性能高容错性的分布式&并行应用框架,遵循Apache 2开源许可,底层通过JVM上另外一个流行的语言Scala实现,提供Java&ScalaAPI(本书采用Java进行代码演示)。它基于经典的Actor并发模型(即所有的消息都是基于Actor组件进行传递,后面我们会作详细介绍),拥有如下特点:

  • 并行与并发:提供对并行与并发的高度抽象。
  • 异步非阻塞:Akka-Actor消息通信都是基于异步非阻塞。
  • 高容错性:为跨多JVM的分布式模型提供强劲的容错处理,号称永不宕机。
  • 持久化:Actor携带的状态或消息可以被持久化,以便于在JVM崩溃后能恢复状态。
  • 轻量级:每个Actor大约只占300bytes,即1G内存可容纳接近300万个Actor。

基本上,Akka从底层就解决了我们大多数分布式&并行程序常见的难题,让工程师更专注于业务实现,同时,它也保留了多个扩展接口及配置,便于满足个性化定制的需要!

Akka应用场景

目前Akka已经在多家互联网&软件公司广泛使用,比如eBay、Amazon、VMWare、PayPal、阿里、惠普、豌豆荚等,所涉行业包括游戏、金融投资、医疗保健、数据分析等。

使用场景包括:

  • 服务后端,比如rest web,websocket服务,分布式消息处理等。
  • 并发&并行,比如日志异步处理,密集数据计算等。

总之,对高并发和密集计算的系统,Akka都是适用的!

Akka架构体系

Akka采用Scala开发,运行于JVM之上,提供了Scala和Java两种API,目前所属Lightbend公司(原名Typesafe)。它实现了经典的Actor模型,同时也提供了丰富的组件,比如邮箱(MailBox),路由(Routing),持久化(Persistence),网络(包括远程、集群)等等,在底层对分布式&并行模式进行了高度且统一的抽象,使得工程师用很少的代码,就可以实现一个完整的分布式应用。本节我将为大家介绍Akka的整个体系结构以及相关概念。

Actor模型

Actor模型最早在1973年由Carl Hewitt提出,它高度抽象了分布式并行程序的运行模式,从底层屏蔽了线程和锁机制的管理,为开发者提供了简单可依赖的开发方式。

Actor模型认为,并行计算的最小单元就是一个Actor实例,而每个实例拥有自己的状态和行为,在一个大型系统中,可能存在成千上万个Actor实例,他们之间通过消息的方式进行通信,每个Actor都能发送消息给其他Actor,也能从其他Actor接收消息。当我们在执行某个计算任务时,会给对应的Actor实例发送一个相关的消息,该Actor在接收消息后开始执行计算任务,由于整个消息通信的过程是异步的,所以不用等到Actor执行完毕整个过程才能执行下一步(发送消息后会马上返回),这种异步通信的方式大大提高了程序的响应性。

Actor异步消息通信如图1-3所示。

图1-3 Actor的异步消息通信

体系结构

Actor是Akka最核心的概念,也是最基本的执行单元,所以对Actor管理和监控的有效性是极为重要的。在Akka中,每个Actor都有自己的监管对象,即该Actor的创建者,它们通常会负责子Actor的失败处理,另外,某些Actor也需要对生命周期进行监控(比如该Actor的终止),以便及时的响应并作正确处理,这些监督和监控者本身也都是一个Actor。在Akka中,整个Actor体系被抽象成一个ActorSystem,它是一个层级的结构,拥有公共行为的配置和管理。

在ActorSystem基础上,Akka也提供了一些配套的组件,比如持久化,Http服务,网络服务等,他们都是构建高可用分布式应用不可或缺的部分,基本架构体系和周边产品如图1-4所示。

图1-4 Akka基本架构体系及周边产品

Actor组件

在Akka中,Actor是一个高度抽象的对象引用,它包含以下几个要素:

  • 引用(ActorReference) Actor的引用不同于普通对象的引用,也不能通过传统的“new”的方式直接创建一个Actor对象。很多时候需要通过actorOf或者actorSelection等方式返回一个ActorRef对象,该对象有可能存在于本地,也可能存在于远程节点,对我们来说,它是位置透明的。Actor之间的通信和执行任务都是通过消息驱动的(而不是API的调用)。
  • 状态(State) Actor在不同时刻可能有着不同的状态,这些状态用变量来表示。在底层实现上,Actor是运行于线程池之上的,肯定会存在多个Actor共享同一个线程的情况,那么会不会出现并发问题呢?实际上,Akka为每个Actor都抽象出一个轻量级的执行“线程”(不是真的线程),在底层已经实现了隔离性,所以基本上不用担心该问题的出现。
  • 另外,当JVM崩溃时,为了避免Actor状态的丢失,我们可以借助持久化方案来对状态进行持久化操作。
  • 行为(Behavior) Actor都有接收和发送消息的能力,每当它接收到一个消息后,就可以执行某个业务操作,同时也可以把消息转发到其他节点进行处理。
  • 监管策略(SupervisorStrategy) Actor系统是一个层级结构,当任务被某个Actor分摊到子Actor时,父Actor就拥有监管子Actor的义务。在监管时,我们需要根据不同的情况选择不同的处理方案(比如停止、重启、恢复或者失败上溯)和策略(比如1 vs 1、1 vs N策略)。

邮箱 (Mailbox)

每个Actor都有自己的邮箱,所有其他Actor发送过来的消息都会进入该邮箱。Akka自带多种邮箱类型,也提供自定义邮箱的接口。

路由(Routing)

消息除了通过普通的Actor发送之外,也可以通过路由进行发送。当通过路由发送消息时,我们可以根据需求来选择不同的路由策略,比如轮询、广播等。

持久化(Persistence)

任何程序都可能有失败的可能,即便是JVM如此强大稳定的平台也都一样。当程序出错, JVM崩溃时,任何关键状态的丢失,对我们后续的业务来讲都可能是致命的打击,所以状态数据的持久化变得非常重要。Akka提供了Actor状态的持久化方案,以便我们在必要时恢复数据。

网络(远程和分布式集群)

网络功能是实现远程Actor和分布式集群的基础,这其中包含I/O、网络通(TCP/UDP)、序列化配置、分布式通信协议(Gossip)、节点(node)管理、集群分片等内容。

HTTP模块

Akka提供了简单易用的Http模块,支持完整的Http服务端与客户端开发,可以帮助我们快速构建性能极强的Rest Web服务。

相关开源项目

Akka具有高性能、可扩展、设计友好等诸多优点,非常被适合用来作为分布式应用的基础框架,而且由于对Http有非常好的支持,也让它在web服务领域占有一席之地。目前业界已经有多个基于Akka实现的开源项目,项目类型涵盖了Web开发、微服务、分布式文件或计算服务等。下面是Akka中两个具有代表性的开源项目:

Play框架

  • 一款大名鼎鼎的Web开发框架。它不同于其他Servlet系的框架,比如Struts或者SpringMVC,底层基于Akka构建,天生拥有异步的特点,具有极佳的性能。
  • 它默认提供restful风格的API,同时也对WebSocket有不错的支持。

Lagom框架

在目前IT界,最火爆的概念要属"微服务"了,微服务的理念是:把业务功能拆成小的、独立的单元,他们之间能够互相通信而且支持水平扩展。Lagom就是这样一款微服务框架,它基于异步的消息驱动,对分布式集群、持久化(如 JPA、NoSql)都有良好的支持。同时,它也拥有完整的集成开发环境,非常便于在线部署和管理。

小结

随着互联网的高速发展,开发分布式&并行应用将不再是某些巨头公司的“专利”,而对大部分研发团队来讲,从零开发自己的分布式架构又会面临诸多挑战,此时选择Akka作为分布式并行服务的基础框架将是极好的! Akka底层采用Scala语言实现(JVM上另外一款明星语言),它基于Actor模型,在底层帮助开发者屏蔽了异步、消息通信、容错处理、网络服务、分布式集群等实现细节。在Akka基础上,也诞生了Play、Lagom等应用框架,让开发者更容易打造自己的高可用分布式系统。

——本文摘自《Akka实战:快速构建高可用分布式应用》

Akka实战:快速构建高可用分布式应用

原文发布于微信公众号 - 猿天地(cxytiandi)

原文发表时间:2018-06-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Crossin的编程教室

【我问Crossin】学会 Python 离成为一名程序员还差多远?

1 运行代码时报错:SyntaxError :invalid syntax Crossin: SyntaxError 为语法错误,新手常见的问题可能有: 忘记在...

29150
来自专栏架构说

如何阅读源码

从哪里开始读起,怎么读 这个问题简单,程序从哪里开始就哪里开始读起。譬如,C 代码,当然是从 main(),其他语言也是类似的。但阅读的时候,要带着问题去读。...

64450
来自专栏程序员互动联盟

作为一名软件工程学生想要自学Linux,可以从哪方面开始学习?

很多linux初学者的首选书籍,linux学习先从基础的命令行入手,常用的命令大约20个,然后慢慢切入学习

8910
来自专栏机器学习算法与Python学习

Python:10篇不可错过的~热文~》》真的很热》》

以下是精选了“ Python开发者” 5月份的10篇 Python 热文。其中有基础知识,项目实战等。 《Python 爬虫建站入门手记(1):环境搭建》 本文...

32830
来自专栏企鹅号快讯

学习Python语言,这些酷毙的工具你知道几个?

工欲善其事必先利其器,一个好的工具能让起到事半功倍的效果,Python社区提供了足够多的优秀工具来帮助开发者更方便的实现某些想法,下面这几个工具给我的工作也带来...

25580
来自专栏Python数据科学

Python爬虫之入门学习

大家好,相信点进来看的小伙伴们都对爬虫非常感兴趣,博主也是一样的。博主刚开始接触爬虫的时候,就被深深吸引了,因为感觉SO COOL啊!每当敲完代码后看着...

19530
来自专栏恰童鞋骚年

操作系统核心原理-1.操作系统导论

PS:操作系统原理是大学计算机专业最为重要的一门专业基础课程之一,对于操作系统核心原理的理解对于一个合格的程序员来说十分重要,于是我继续我的“三大原理,两个协议...

12720
来自专栏Web 开发

如何把捏前端模板颗粒度

今晚看到一篇博文,其原文是讲AngularJS的模板的,但觉得该作者讲的很多思路,不仅仅是AngularJS适用。凡是想在前端进行模板组织的,都可借鉴,故写下读...

8000
来自专栏喵了个咪的博客空间

zephir-(1)开篇介绍

#zephir-开篇介绍# ? ##前言## 先在这里感谢各位zephir开源技术提供者 笔者在学习phalcon的过程中了解到,phalcon2.x版本通过了...

39290
来自专栏存储

集群NAS和对象存储的区别

这个话题乍一看可能有些奇怪,因为一个是集群NAS存储,一个是对象存储,没什么相同的地方,为啥还要比较? 而实际上,在考察两种技术的实际应用场景时,我们会发现,两...

485100

扫码关注云+社区

领取腾讯云代金券