上次我们在“懵 B”的状态下,聊了聊 Actor 模型的理论知识。稍微再补充两句,如上图所示在 Actor 模型系统中,主要有互不依赖的 Actor 组成(图中圆圈),Actor 之间的通信是通过消息来实现的,其中每个 Actor 都有一个 MailBox 来存储接收到的消息,每个 Actor 都维护着自己的状态。

说实话,聊 Actor 模型其实有点醉翁之意不在酒,项庄舞剑意在 Akka。

Actor 模型还有点懵 B,又出来个Akka,这又是个什么玩意儿?估计你心里一直在犯嘀咕。

好了,不闲扯,请准备好小板凳,我们的分享开始。

1.

Akka 是啥?

Akka 是一个用 Scala 编写的库,用于简化编写容错的、高可伸缩性的 Java 和 Scala 的 Actor 模型应用。它已经成功运用在电信行业。系统几乎不会宕机(高可用性 99.9999999 % 一年只有 31 ms 宕机)。Akka 是 JAVA 虚拟机 JVM 平台上构建高并发、分布式和容错应用的工具包和运行时。Akka 用 Scala 语言写成,同时提供了 Scala 和 JAVA 的开发接口——摘自百度百科。

上面是度娘的答复,那咱们尝试用自己的话回答一下,其实 Akka 是 Actor 模型的一种实现,是一个用来开发支持并发、容错、扩展性的应用程序框架,So Easy!!

2.

Akka 咋用?

好了,让我们抛开苦涩的概念,让我们写一个超级简单的 HelloWorld 了解一下 Akka 的魅力吧。

先定一下 HelloWorld 完成的目标:实现简易的WordCount,按照空格拆分一句话,并统计每个单词出现的次数。

第一步:让我们从全局认识一下,我们要用 Akka 生撸的 HelloWorld(看到截图不得不说是相当之简单)

第二步:引入依赖,考虑到方便你本机测试,遂把依赖 copy 一份给你。

<dependencies>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor_2.12</artifactId>
<version>2.6.0-M5</version>
</dependency>
</dependencies>

  

第三步:伏笔买了这么久,终于可以施展代码了。

来自于内心的疑问:Actor 与 Actor 之间通过消息进行通讯,那么用于传输的消息实体该如何定义?

来自于灵魂的碰撞 1:拆分一句话的 Actor,该如何定义?

来自于灵魂的碰撞 2:统计每个单词出现次数的 Actor,该如何定义?

来自内心 + 灵魂的发问:该如何攒到一起?

第四步:代码写完了,是该一览尊荣的时候了。

效果达到预期,杠杠滴!为了体现我是一个负责任的分享者,还是需要把全部代码分享出来,以便你快速上手(捂嘴笑)。

import akka.actor.*;
import java.io.IOException;
import java.util.*; public class WordCountAkka { public static void main(String[] args) {
//1、创建Actor系统,名字为wordcount
ActorSystem actorSystem = ActorSystem.create("wordcount");
try {
//2、创建SplitActor,用于拆分每行的单词
ActorRef splitActor = actorSystem.actorOf((Props.create(SplitActor.class)), "SplitActor");
//2.1、创建CountActor,用于统计单词的次数
ActorRef countActor = actorSystem.actorOf((Props.create(CountActor.class)), "CountActor"); //3、创建消息
//TODO 接收的消息串,可以修改为从控制台输入,本次就直接写死了
Message msg = new Message("Hello Akka Akka Hello");
//4、给SplitActor发消息
splitActor.tell(msg, ActorRef.noSender()); //5、按回车退出应用
System.out.println(">>> Press ENTER to exit <<<");
System.in.read();
} catch (IOException e) {
} finally {
actorSystem.terminate();
}
} /**
* 定义 SplitActor 用于拆分每行的单词
*/
static class SplitActor extends AbstractActor {
@Override
public Receive createReceive() {
return receiveBuilder().match(Message.class, t -> {
System.out.println(self() + " 收到来自于 " + sender() + " 的消息: " + t);
//按照空格拆分数据
String[] words = String.valueOf(t.getContent()).toLowerCase().split("\\W+");
//封装消息请求给CountActor
Message msg = new Message(words);
System.out.println(self() + " 发送消息 : " + Arrays.toString(words));
//根据路径查找下一个处理者
ActorSelection countActorRef = getContext().actorSelection("/user/CountActor");
//将消息发给下一个处理者CountActor
countActorRef.tell(msg, self());
}).build();
}
} /**
* 定义 CountActor 用于统计每个单词出现的次数
*/
static class CountActor extends AbstractActor {
@Override
public Receive createReceive() {
return receiveBuilder().match(Message.class, t -> {
//收到消息
String[] words = (String[]) t.getContent();
System.out.println(self() + " 收到来自于 " + sender() + " 的消息: " + Arrays.toString(words)); //统计处理
Map<String, Integer> conutMap = new HashMap<>();
for (String word : words) {
Integer num = conutMap.get(word);
conutMap.put(word, num == null ? 1 : num + 1);
}
System.out.println(self() + " 每个单词出现次数的统计结果为 : " + conutMap);
}).build();
}
} /**
* 定义消息
*/
static class Message { private Object content; public Message(Object content) {
this.content = content;
} public Object getContent() {
return content;
} public void setContent(Object content) {
this.content = content;
}
}
}

  

其实代码中的注释,已经写的非常之清晰了,但是为了让你更清晰明了,我还是稍微再总结 Akka 的代码研发流程。

1、采用 ActorSystem.create("wordcount") 创建一个名字为 wordcount 的 Actor 系统;
2、定义 XxActor extends AbstractActor,实现 createReceive() 方法完成业务逻辑处理;
3、通过 actorSystem.actorOf((Props.create(SplitActor.class)), "SplitActor") 创建业务逻辑处理的 Actor;
4、通过 getContext().actorSelection("/user/CountActor") 选择下一个逻辑处理的 Actor;
5、采用 countActorRef.tell(msg, self()) 来发送消息。

  

3.

好了,结合本次的 Akka 分享 + 上次的 Actor 模型的分享,你多多少少应该对 Actor 模型有点概念了吧。

相信通过这两次的分享,我们再去深入架构源码,虽谈不上平步青云,但是也会好风凭借力送你上青云(捂嘴笑)。

调皮的我又找一张 flink 运行时的架构图,你有没有发现 Actor System 担任了整个架构通讯的角色啊!!!!

4.

最后,主要想说一下,授人以鱼不如授人以渔,尝试结合个人在面对新技术时的一个研究思路,先从整体上了解个梗概,然后再逐个了解七七八八,遇到没见过的新名词、新技术不要放弃,暂时屏蔽,当时抽取 Resin 核心源码就如此,见到 Actor 字眼,当时也没深究,到现在才开始了解 Actor ,但是当时抽取的项目架构已在业务上平稳运行,所以遇到不懂的,莫阻碍全局,到秋后再(补)算账,也未尝不是一个好的方式方法。其实核心思想说简单点就是「时间紧,任务重,先出活,其它都白扯!」

苦涩的技术我该怎么学?Akka 实战的更多相关文章

  1. 30分钟手把手教你学webpack实战

    30分钟手把手教你学webpack实战 阅读目录 一:什么是webpack? 他有什么优点? 二:如何安装和配置 三:理解webpack加载器 四:理解less-loader加载器的使用 五:理解ba ...

  2. php中CURL技术模拟登陆抓取数据实战,抓取某校教务处学生成绩。

    这两天有基友要php中curl抓取教务处成绩的源码,用于微信公众平台的开发.下面笔者只好忍痛割爱了.php中CURL技术模拟登陆抓取数据实战,抓取沈阳工学院教务处学生成绩. 首先,教务处登录需要验证码 ...

  3. [转] Akka实战:构建REST风格的微服务

    [From] http://www.yangbajing.me/2015/11/27/akka%E5%AE%9E%E6%88%98%EF%BC%9A%E6%9E%84%E5%BB%BArest%E9% ...

  4. 每天记录一点:NetCore获得配置文件 appsettings.json vue-router页面传值及接收值 详解webpack + vue + node 打造单页面(入门篇) 30分钟手把手教你学webpack实战 vue.js+webpack模块管理及组件开发

    每天记录一点:NetCore获得配置文件 appsettings.json   用NetCore做项目如果用EF  ORM在网上有很多的配置连接字符串,读取以及使用方法 由于很多朋友用的其他ORM如S ...

  5. rodert教你学FFmpeg实战这一篇就够了

    rodert教你学FFmpeg实战这一篇就够了 建议收藏,以备查阅 pdf阅读版: 链接:https://pan.baidu.com/s/11kIaq5V6A_pFX3yVoTUvzA 提取码:jav ...

  6. Python图文识别技术【入门必学】

    Python图文识别技术分享 使用 tesseract-ORC 识别文字,识别率不算太高,需要自我训练 tessdata 数据,才能更精确的识别你想要让电脑认识出来的文字!ps:另外很多人在学习Pyt ...

  7. Spark技术学院-进去能学到啥?

    Spark技术学院是什么? 主要是浪尖,前腾讯现阿里的大神一起搞的知识分享基地,旨在帮助大家由入门到精通spark,hbase,kafka大数据重要的框架,还有给入门小白指点入门方法,分享入门资料,对 ...

  8. [js高手之路]Node.js模板引擎教程-jade速学与实战1

    环境准备: 全局安装jade: npm install jade -g 初始化项目package.json: npm init --yes 安装完成之后,可以使用 jade --help 查看jade ...

  9. [js高手之路]Node.js模板引擎教程-jade速学与实战1-基本用法

    环境准备: 全局安装jade: npm install jade -g 初始化项目package.json: npm init --yes 安装完成之后,可以使用 jade --help 查看jade ...

随机推荐

  1. JS中的reduce()详解

    reduce()作为一个循环使用.接收四个参数:初始值(上一次返回值),当前元素值,当前元素下标,原数组. 应用  作为累加器使用 var a=[4,5,6,7,8] //item代表一次回调的值 初 ...

  2. nes 红白机模拟器 第8篇 USB 手柄支持

    买了一个支持 USB OTG, 蓝牙 连接的 安卓手柄. 接到 ubunto 上 dmesg 可以看到识别出来的信息,内核已经支持了. usb - using uhci_hcd usb - usb - ...

  3. py2.7 批量转换文件为 utf8 编码

    source insight 不支持 utf8 ,但是在 linux 上查看的时候是 utf8 编码,就会显示不正常,所以写了个 python 小脚本,可以批量转换 py2.7 #coding:utf ...

  4. Aircrack-ng无线审计工具破解无线密码

    Aircrack-ng工具 Aircrack-ng是一个与802.11标准的无线网络分析的安全软件,主要功能有网络探测.数据包嗅探捕获.WEP和WPA/WPA2-PSK破解.Aircrack可以工作在 ...

  5. Java自学路线图之Java基础自学

    自学Java要从Java基础语法开始自学,自学Java的过程中打好基础是很重要的!首先自学:面向对象基础,API基础,集合基础.这些对Java小白的数学和英语能力的要求门槛不高,在学习的过程中积累相应 ...

  6. Python模块一

    logging模块 我们来说一下这个logging模块,这个模块的功能是记录我们软件的各种状态,你们现在和我一起找到红蜘蛛的那个图标,然后右键找一找是不是有个错误日志.其实每个软件都是有错误日志的,开 ...

  7. 数据结构 - Collection接口

    简介 Collection继承自Iterable,Collection接口是Java集合两大分支中的一支,Queue.List.Set都是Collection的扩展:集合大类分为了Collection ...

  8. 用 jQuery 实现表单验证(摘抄)——选自《锋利的jQuery》(第2版)第5章的例题 5.1.5 表单验证

    5.1.5 表单验证 表单(form)作为 HTML 最重要的一个组成部分,几乎在每个网页上都有体现,例如用户提交信息.用户反馈信息和用户查询信息等,因此它是网站管理者与浏览者之间沟通的桥梁.在表单中 ...

  9. 计算机网络 Computer Networks​ 期末复习总提纲

    平时不学习,期末火葬场. 一周时间靠王道考研和各路 pdf 自学计网,留下的提纲都在这里了.全是干货.全文 pdf 可以在这里下载:http://cloud.billc.io/s/xNHarppQPG ...

  10. java 泛型简介(转载)

    原文出处: absfree 1. Why ——引入泛型机制的原因 假如我们想要实现一个String数组,并且要求它可以动态改变大小,这时我们都会想到用ArrayList来聚合String对象.然而,过 ...