架构解密从分布式到微服务:聊聊分布式计算,初识Akka
ccwgpt 2024-10-15 08:54 29 浏览 0 评论
初识 Akka
虽然Akka基于Scala而非Java语言编写而成,但由于Scala最终还是被编译为Java字节码并运行在JVM之上,所以我们可以认为Akka属于Java领域。
Akka官方对Akka的介绍如下。
●是对并发、并行程序的简单的高级别的抽象。
●是异步、 非阻塞、高性能的事件驱动编程模型。
●是非常 轻量的事件驱动处理机制(1GB内存可容纳约270万个Actor)。
通过7.2节对μJavaActors的讲解,我们知道,一 一个实际的Actor 系统是由许多个Actor实例组成的-一个复杂的树状结构,父Actor负责子Actor的生命周期并对它们实施必要的监管与控制,Akka项目则更加清晰地描述和定义了与之相关的编程模型。如下所示给出了Akka中的Actor层级与监管的示意图。
从上图中还可以看到,Akka中的每个Actor都有一个Path (路径),对于一个Actor子系统ActorSystem (类似于μJavaActors中的- -个ActorManager,维护-一个Actor 命名空间)来说,顶级根路径是“/”,下面有两个子路径, 分别是user (用户空间)路径与system (系统空间)路径,在前者的路径分支上挂接了我们自己开发的Actor,后者则是Akka本身的系统级的Actor所在的路径。
如下所示是一个典型的Akka Actor 的Path层级的结构示意图,我们看到每个下一层级的Actor的Path全路径的名称都是从根节点出发的完整路径,类似于文件目录结构的设计思路。
而将user空间与system空间分离的做法,又借鉴了Linux内核的思想,将系统级的Actor识别出来,从而针对性地实现了精细化调度及增强系统内核的稳定性与容器能力。
在Akka的Actor Path设计里还融入了URL的思想,使得Akka天然具备了分布式计算的能力。下面是Actor Path的完整定义方式:
akka://<actorsystemname>@ <hostname>: <port>/<actor path>
如果我们要访问位于一个远程机器10.0.0.1. 上的某个Actor,则可以这样引用:
ActorRef actor = context.actorFor ("akka:/ /app@10.0.0.1:2552/user/actorxxxx") ;
在分布式系统中,在通常情况下我们会部署多个Actor实例来响应某个业务请求,Akka 为此提供了基于Router组件派发请求的解决思路。如下所示是一个使用Router的原理图。
首先,我们定义一个Router (其实也是-一个Actor),然后为这个Router设置后端的转发路
由(routee), 客户端在发送消息时,要先获取Router的Path,并将消息发到Router上,最后由
Router将消息转发到后端的某个具体Actor.上。如下所示是来自Akka官网的一段Router配置
代码:
akka. actor . deployment {
/parent/ remoteGroup {
router = round- robin-group
routees .paths = [
"akka. tcp:/ /app@10.0.0.1:2552/user/workers/w1",
"akka. tcp:/ /app@10.0.0.2:2552/user/workers/w1",
"akka. tcp:/ /app@10.0.0.3:2552/user/workers/w1"]
}
}
从上面的介绍中我们看到了Akka的强大能力,那么它是如何运转的呢?下图给出了生动、直观的解释。
首先,用户应用(StudentSimulatorApp) 要通过Actor System这个Akka里最重要的组件来实现具体Actor的创建、引用(通过ActorRef)及消息发送等逻辑。消息投递过程中最重要的组件则是Message Dispatcher,它首先把收到的消息放入队列中,然后驱动派发线程去执行每个Actor的收件动作,收件动作就是把每个Actor自己的消息从队列中转移到自己的MailBox中,最后回调Actor的消息处理接口以完成消息的处理逻辑。如下所示为更详细的Akka运作原理图。
我们知道Message Dispatcher用到了线程池,那么具体用的是什么线程池呢?答案就在下面这段Akka的Message Dispatcher的配置信息里:
my-di spatcher
# Dispatcher is the name of the event-based dispatcher
type = Dispatcher
# What kind of ExecutionService to use
executor = "fork-join-executor"
# Configuration for the fork join pool
fork-join-executor {
牛Min number of threads to cap factor-based parallelism number to
parallelism-min = 2
牛Parallelism (threads) . . . ceil (available processors ★factor)
parallelism-factor = 2.0
# Max number of threads to cap factor-based parallelism number to
parallelism-max = 10
}
# Throughput defines the maximum number of messages to be
# processed per actor before the thread jumps to the next actor.
#Setto1foras
fair as possible.
throughput = 100
}
没错,Akka 用的就是JDK 7提供的新的并发框架一Fork/Join, 如下图所示。
下面这张图给出了Akka测试java.util.concurrent.ThreadPoolExecutor与ForkJoinPool时的性能对比结果。
ThreadPoolExecutor的性能之所以低于ForkJoinPool很多,主要的-一个原因是:在高并发情况下多线程锁竞争(来自共享的LinkedBlockingQueue)及由此引发的大量上下文切换,会导致系统并发上不去,而ForkJoinPool 的每个工作线程都有自己的任务队列,所以在这种高度竞争的情况下表现非常突出。再看看下面这张ForkJoinPool 的原理图,你可能会理解更深刻。
最后以一个编程案例来说明如何使用Akka库(Java)进行编程,该案例对应的Actor的拓扑图如下图所示。
这个例子为模拟标准的请求应答调用这种常见场景。首先,我们创建两个Actor,分别是SenderActor和ReceiverActor, SenderActor在启动后发送一个Hello消息给ReceiverActor,后者在收到消息后再发送相应的Hello Ack消息给SenderActor , SenderActor在收到应答后关闭自己,同时结束程序。
下面展示完整的Actor代码。
首先是SenderActor的代码:
import akka. actor . UntypedActor;
public class SenderActor extends UntypedActor {
@Override
public void onReceive (Object msg) {
System. out.println("received done ");
if (msg == ReceiverActor . Msg. DONE) {
getContext () .stop(getSelf()) ;
getContext() . system() .shutdown() ;
} else {
unhandled (msg) ;
}
}
}
接着是ReceiverActor的代码:
import akka. actor . UntypedActor;
public class ReceiverActor extends UntypedActor {
public static enum Msg {
GREET, DONE
}
@Override
public void onReceive (Object msg) {
if (msg == Msg . GREET) {
System. out.println("Hello World!");
getSender () . tell (Msg.DONE, getSelf());
} else{
unhandled (msg) ;
}
}
}
import akka. actor . ActorRef;
import akka. actor . ActorSystem;
import akka.actor. Props;
最后是主程序的代码:
public class Starter
public static void main(String[] args) {
// Create an Akka system
ActorSystem system
ActorSystem. create ("HellowSystem") ;
/ / create the sender actor
final ActorRef sender = system. actorOf (new Props (SenderActor.class) ,
"sender") ;
/ / create the receiver actor
final ActorRef greeter = system. actorOf (new Props (ReceiverActor.class) ,
"greeter") ;
greeter. tell (ReceiverActor .Msg. GREET, sender) ;
}
}
本文给大家讲解的内容是架构解密从分布式到微服务:聊聊分布式计算,初识Akka
- 下篇文章给大家讲解的是架构解密从分布式到微服务:聊聊分布式计算,适用面很广的 Storm ;
- 觉得文章不错的朋友可以转发此文关注小编;
- 感谢大家的支持!
相关推荐
- RACI矩阵:项目管理中的角色与责任分配利器
-
作者:赵小燕RACI矩阵RACI矩阵是项目管理中的一种重要工具,旨在明确团队在各个任务中的角色和职责。通过将每个角色划分为负责人、最终责任人、咨询人和知情人四种类型,RACI矩阵确保每个人都清楚自己...
- 在弱矩阵组织中,如何做好项目管理工作?「慕哲制图」
-
慕哲出品必属精品系列在弱矩阵组织中,如何做好项目管理工作?【慕哲制图】-------------------------------慕哲制图系列0:一图掌握项目、项目集、项目组合、P2、商业分析和NP...
- Scrum模式:每日站会(Daily Scrum)
-
定义每日站会(DailyScrum)是一个Scrum团队在进行Sprint期间的日常会议。这个会议的主要目的是为了应对Sprint计划中的不断变化,确保团队能够有效应对挑战并达成Sprint目标。为...
- 大家都在谈论的敏捷开发&Scrum,到底是什么?
-
敏捷开发作为一种开发模式,近年来深受研发团队欢迎,与瀑布式开发相比,敏捷开发更轻量,灵活性更高,在当下多变环境下,越来越多团队选择敏捷开发。什么是敏捷?敏捷是一种在不确定和变化的环境中,通过创造和响应...
- 敏捷与Scrum是什么?(scrum敏捷开发是什么)
-
敏捷是一种思维模式和哲学,它描述了敏捷宣言中的一系列原则。另一方面,Scrum是一个框架,规定了实现这种思维方式的角色,事件,工件和规则/指南。换句话说,敏捷是思维方式,Scrum是规定实施敏捷哲学的...
- 敏捷项目管理与敏捷:Scrum流程图一览
-
敏捷开发中的Scrum流程通常可以用一个简单的流程图来表示,以便更清晰地展示Scrum框架的各个阶段和活动。以下是一个常见的Scrum流程图示例:这个流程图涵盖了Scrum框架的主要阶段和活动,其中包...
- Mockito 的最佳实践(mock方法)
-
记得以前面试的时候,面试官问我,平常开发过程中自己会不会测试?我回答当然会呀,自己写的代码怎么不测呢。现在想想我好像误会他的意思了,他应该是想问我关于单元测试,集成测试以及背后相关的知识,然而当时说到...
- EffectiveJava-5-枚举和注解(java枚举的作用与好处)
-
用enum代替int常量1.int枚举:引入枚举前,一般是声明一组具名的int常量,每个常量代表一个类型成员,这种方法叫做int枚举模式。int枚举模式是类型不安全的,例如下面两组常量:性别和动物种...
- Maven 干货 全篇共:28232 字。预计阅读时间:110 分钟。建议收藏!
-
Maven简介Maven这个词可以翻译为“知识的积累”,也可以翻译为“专家”或“内行”。Maven是一个跨平台的项目管理工具。主要服务于基于Java平台的项目构建、依赖管理和项目信息管理。仔...
- Java单元测试框架PowerMock学习(java单元测试是什么意思)
-
前言高德的技术大佬在谈论方法论时说到:“复杂的问题要简单化,简单的问题要深入化。”这句话让我感触颇深,这何尝不是一套编写代码的方法——把一个复杂逻辑拆分为许多简单逻辑,然后把每一个简单逻辑进行深入实现...
- Spring框架基础知识-第六节内容(Spring高级话题)
-
Spring高级话题SpringAware基本概念Spring的依赖注入的最大亮点是你所有的Bean对Spring容器的存在是没有意识的。但是在实际的项目中,你的Bean必须要意识到Spring容器...
- Java单元测试浅析(JUnit+Mockito)
-
作者:京东物流秦彪1.什么是单元测试(1)单元测试环节:测试过程按照阶段划分分为:单元测试、集成测试、系统测试、验收测试等。相关含义如下:1)单元测试:针对计算机程序模块进行输出正确性检验工作...
- 揭秘Java代码背后的质检双侠:JUnit与Mockito!
-
你有没有发现,现在我们用的手机App、逛的网站,甚至各种智能设备,功能越来越复杂,但用起来却越来越顺畅,很少遇到那种崩溃、卡顿的闹心事儿?这背后可不是程序员一拍脑袋写完代码就完事儿了!他们需要一套严谨...
- 单元测试框架哪家强?Junit来帮忙!
-
大家好,在前面的文章中,给大家介绍了以注解和XML的方式分别实现IOC和依赖注入。并且我们定义了一个测试类,通过测试类来获取到了容器中的Bean,具体的测试类定义如下:@Testpublicvoid...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 框架图 (58)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- jpa框架 (47)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- java日志框架 (61)
- JAVA集合框架 (47)
- mfc框架 (52)
- abb框架断路器 (48)
- ui自动化框架 (47)
- beego框架 (52)
- java框架spring (58)
- grpc框架 (65)
- ppt框架 (48)
- 内联框架 (52)
- cad怎么画框架 (58)
- ps怎么画框架 (47)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)
- oracle提交事务 (47)