akka设计模式系列-Aggregate模式
所谓的Aggregate模式,其实就是聚合模式,跟masterWorker模式有点类似,但其出发点不同。masterWorker模式是指master向worker发送命令,worker完成某种业务逻辑。而聚合模式则刚好相反,由各个worker完成某种业务逻辑后,把结果汇总发给某个actor,这个actor不一定是masterActor。
class AggregateMasterActor extends Actor{
override def receive: Receive = {
case cmd: AggregateCommand.Aggregate =>
// 将此次汇总结果汇报给from,为了简化,此处用self替代
val from = self
val backendActor = context.actorOf(Props(new AggregateMasterBackendActor(from,cmd.parallel)),s"AggregateMasterBackendActor-${cmd.at}")
backendActor ! cmd
case AggregateBackendEvent.WorkDone(sum) =>
val from = sender()
println(s"AggregateMasterActor [${self.path.name}] 收到 ${from.path.name} 汇总结果 $sum")
}
}
class AggregateMasterBackendActor(replyTo:ActorRef,parallel:Int) extends Actor{
var counter = 0
var sum = 0L
override def receive: Receive = {
case AggregateCommand.Aggregate(_) =>
println(s"AggregateMasterBackendActor [${self.path.name}] 开始工作,parallel $parallel,工作结果汇总给 ${replyTo.path.name}")
1 to parallel foreach { i =>
val worker = context.actorOf(Props(new AggregateWorker(self)),s"AggregateWorker-$i")
worker ! AggregateBackendCommand.Aggregate(i,parallel)
}
case AggregateWorkerEvent.WorkDone(result) =>
counter += 1
sum += result
if(counter == parallel){
replyTo ! AggregateBackendEvent.WorkDone(sum)
context.stop(self)
println(s"AggregateMasterBackendActor [${self.path.name}] 工作结束退出")
}
}
}
class AggregateWorker(replyTo:ActorRef) extends Actor{
def calcResult(index:Int,parallel:Int):Long = index * parallel
override def receive: Receive = {
case AggregateBackendCommand.Aggregate(index,parallel) =>
println(s"AggregateWorker [${self.path.name}] 开始工作 index=$index,工作汇总给 ${replyTo.path.name}")
val result = calcResult(index,parallel)
replyTo ! AggregateWorkerEvent.WorkDone(result)
println(s"AggregateWorker [${self.path.name}] 工作结束退出")
context.stop(self)
}
}
object AggregatePattern {
def main(args: Array[String]): Unit = {
val system = ActorSystem("AggregatePattern",ConfigFactory.load())
val aggregateMasterActor = system.actorOf(Props(new AggregateMasterActor),"AggregateMasterActor")
aggregateMasterActor ! AggregateCommand.Aggregate(3)
}
}
输出:
AggregateMasterBackendActor [AggregateMasterBackendActor-1531383454073] 开始工作,parallel 3,工作结果汇总给 AggregateMasterActor
AggregateWorker [AggregateWorker-1] 开始工作 index=1,工作汇总给 AggregateMasterBackendActor-1531383454073
AggregateWorker [AggregateWorker-2] 开始工作 index=2,工作汇总给 AggregateMasterBackendActor-1531383454073
AggregateWorker [AggregateWorker-3] 开始工作 index=3,工作汇总给 AggregateMasterBackendActor-1531383454073
AggregateWorker [AggregateWorker-1] 工作结束退出
AggregateWorker [AggregateWorker-3] 工作结束退出
AggregateWorker [AggregateWorker-2] 工作结束退出
AggregateMasterBackendActor [AggregateMasterBackendActor-1531383454073] 工作结束退出
AggregateMasterActor [AggregateMasterActor] 收到 AggregateMasterBackendActor-1531383454073 汇总结果 18
从代码来看该设计模式也比较简单,就是由Master创建以临时的子actor,此处命名为MasterBackend,将汇报对象的actorRef以构造函数的形式传递给MasterBackend,此处为了简单用self替代;MasterBackend根据并行参数,创建对应个数的workerActor,并把本身的actorRef以构造函数的形式传递给workerActor,workerActor执行具体的业务逻辑,并将汇总结果,发送给replyTo(也就是MasterBackend);MasterBackend收到workerActor的汇总结果,根据并行参数,判断所有子actor是否执行结束,若执行结束,此次计算完成,将汇总后的结果,发送给replyTo(也就是MasterActor)。
上面这种设计模式有一个明显的好处,就是Master可以迅速创建大量的聚合工作而不阻塞,因为它收到命令后,只是简单的创建MasterBackend,工作交给它去执行,这个过程非常快。如果某个聚合工作比较慢,并不会影响其他任务。
之所以说这个设计模式非常重要,是因为在spark/storm等大多分布式框架中都有它的影子。他们都选择将功能进行拆解,专门的节点或actor分别负责任务的接收、创建、执行、汇总这些工作,工作之间互不影响。如果能够深刻的理解这种设计模式,你将会设计出一个架构分层合理、互相解耦的高质量应用系统。
akka设计模式系列-Aggregate模式的更多相关文章
- akka设计模式系列-Backend模式
上一节我们介绍了Akka使用的基本模式,简单点来说就是,发消息给actor,处理结束后返回消息.但这种模式有个缺陷,就是一旦某个消息处理的比较慢,就会阻塞后面所有消息的处理.那么有没有方法规避这种阻塞 ...
- akka设计模式系列-While模式
While模式严格来说是while循环在Akka中的合理实现.while是开发过程中经常用到的语句之一,也是绝大部分编程语言都支持的语法.但while语句是一个循环,如果循环条件没有达到会一直执行wh ...
- akka设计模式系列-Chain模式
链式调用在很多框架和系统中经常存在,算不得上是我自己总结的设计模式,此处只是简单介绍在Akka中的两种实现方式.我在这边博客中简化了链式调用的场景,简化后也更符合Akka的设计哲学. trait Ch ...
- akka设计模式系列-基础模式
本文介绍akka的基本使用方法,由于属于基础功能,想不出一个很高大上的名称,此处就以基础模式命名.下文会介绍actor的使用方法,及其优劣点. class SimpleActor(name:Strin ...
- akka设计模式系列-慎用ask
慎用ask应该是Akka设计的一个准则,很多时候我们应该禁用ask.之所以单独把ask拎出来作为一篇博文,主要是akka的初学者往往对ask的使用比较疑惑. "Using ask will ...
- akka设计模式系列-消息模型(续)
在之前的akka设计模式系列-消息模型中,我们介绍了akka的消息设计方案,但随着实践的深入,发现了一些问题,这里重新梳理一下设计方法,避免之前的错误.不当的观点给大家带来误解. 命令和事件 我们仍然 ...
- akka设计模式系列
由于本人爱好Scala,顺便也就爱好Akka,但目前网上对Akka的介绍大多都是概念上或技术方向上的介绍,基本没有Akka设计模式或者Actor模型设计模式的资料.这对于Akka的普及非常不利,因为即 ...
- PHP设计模式系列 - 外观模式
外观模式 通过在必需的逻辑和方法的集合前创建简单的外观接口,外观设计模式隐藏了调用对象的复杂性. 外观设计模式和建造者模式非常相似,建造者模式一般是简化对象的调用的复杂性,外观模式一般是简化含有很多逻 ...
- akka设计模式系列-actor锚定
actor锚定模式是指使用actorSelection对acor进行锚定的设计模式,也可以说是一个对actor的引用技巧.在某些情况下,我们可能需要能够根据Actor的path锚定对应的实例.简单来说 ...
随机推荐
- asp.net mvc,基于aop实现的接口访问统计、接口缓存等
其实asp.net 上aop现有的框架应该蛮多的,比如静态注入式的PostSharp(新版本好像已经商业化了,旧版本又不支持.net4.0+),或者通过反射的(性能会降低). 本文则是通过mvc其中一 ...
- TestNG安装及配置
1. 在idea中新建一个maven项目 2. 在pom.xml中添加testng和reportng依赖 <dependencies> <!-- 添加testNG依赖 --> ...
- 【模板】51nod 1006 最长公共子序列Lcs
[题解] dp转移的时候记录一下,然后倒着推出答案即可. #include<cstdio> #include<cstring> #include<algorithm> ...
- nginx+keepalived+consul 实现高可用集群
继 负载均衡 之 nginx+consul+consul template,我这次将使用2台虚拟机,来做一个简单的双机负载均衡试验. 试验目标: 1. 当参加负载均衡的子节点服务,有任何其中一个或多个 ...
- SHA256兼容性
SHA-2是一个加密哈希(Cryptographic Hash)函数的一个集合,包括SHA-224,SHA256和SHA-512.在SHA-256中的256代表哈希(Hash)输出或者摘要的位尺寸(即 ...
- 【codeforces 709C】Letters Cyclic Shift
[题目链接]:http://codeforces.com/contest/709/problem/C [题意] 让你改变一个字符串的子集(连续的一段); ->这一段的每个字符的字母都变成之前的一 ...
- HDU 1176 DP
题目大意: 在0~10这11个点上面接饼 , 每秒最多往左或往移动一格,或者保持原地不动 令dp[i][j]表示在第 i 秒在 第 j 个点上最多能得到的饼的数量 dp[i][j] = max(dp[ ...
- poj 1562 简单深搜
//搜八个方向即可 #include<stdio.h> #include<string.h> #define N 200 char ma[N][N]; int n,m,vis[ ...
- WPF 有趣的动画效果
WPF 有趣的动画效果 这一次我要呈上一个简单的文章,关于给你的WPF apps加入美丽的光线动画,可是我对动画这东西可能有点入迷了. 实际上.我对动画如此的入迷,以至 ...
- socket实现web server
http://blog.csdn.net/u012734441/article/details/44801523 很好的一个例子,现在java程序原开发web服务端程序基本上都使用现成的web框架,这 ...