文档章节

Akka实战:分散、聚合模式

羊八井
 羊八井
发布于 2015/11/26 00:16
字数 964
阅读 3568
收藏 83

分散与聚合:简单说就是一个任务需要拆分成多个小任务,每个小任务执行完后再把结果聚合在一起返回。

代码 http://git.oschina.net/yangbajing/akka-action

分散与聚合图

实例背景

本实例来自一个真实的线上产品,现将其需求简化如下:

  1. 传入一个关键词:key,根据key从网上抓取相关新闻
  2. 可选传入一个超时参数:duration,设置任务到期时必须反回数据(返回实际已抓取数据)
  3. 若超时到返回实际已爬取数据,则任务应继续运行直到所以数据抓取完成,并存库

设计

根据需求,一个简化的分散、聚合模式可以使用两个actor来实现。

  • NewsTask:接收请求,并设置超时时间
  • SearchPageTask:执行实际的新闻抓取操作(本实例将使用TimeUnit模拟抓取耗时)

实现

NewsTask

https://github.com/yangbajing/akka-action/blob/master/src/main/scala/me/yangbajing/akkaaction/scattergather/NewsTask.scala

  override def metricPreStart(): Unit = {
    context.system.scheduler.scheduleOnce(doneDuration, self, TaskDelay)
  }

  override def metricReceive: Receive = {
    case StartFetchNews =>
      _receipt = sender()
      (0 until NewsTask.TASK_SIZE).foreach { i =>
        context.actorOf(SearchPageTask.props(self), "scatter-" + i) ! SearchPage(key)
      }

    case GetNewsItem(newsItem) =>
      _newses ::= newsItem
      if (_newses.size == NewsTask.TASK_SIZE) {
        logger.debug(s"分散任务,${NewsTask.TASK_SIZE}个已全部完成")

        if (_receipt != null) {
          _receipt ! NewsResult(key, _newses)
          _receipt = null
        }
        self ! PoisonPill
      }

    case TaskDelay =>
      if (_receipt != null) {
        _receipt ! NewsResult(key, _newses)
        _receipt = null
      }
  }

metricPreStart方法中设置定时方法,调用时间为从代码运行开始到doneDuration时间为止。定时被触发时将向当前Actor发送一个TaskDelay消息。

metricReceive方法中,分别对StartFetchNewsGetNewsItemTaskDelay三个消息进行操作。

在收到StartFetchNews消息时,actor首先保存发送者actor的引用(结果将返回到此actor)。再根据TASK_SIZE生成相应子任务

GetNewsItem消息的处理中,每收到一个消息就将其添加到_newses列表中。并判断当_newses个数等于TASK_SIZE时(所有子任务已完成)将结果发送给_receipt

self ! PoisonPill,这句代码停止actor自身。它将把“毒药”发送到NewsTask Actor的接收邮箱队列中。

TaskDelay消息被触发时,将直接返回已完成的新闻_newses。返回数据后并不终止当前还未运行完任务。

SearchPageTask

https://github.com/yangbajing/akka-action/blob/master/src/main/scala/me/yangbajing/akkaaction/scattergather/SearchPageTask.scala

  override def metricReceive: Receive = {
    case SearchPage(key) =>
      // XXX 模拟抓取新闻时间
      TimeUtils.sleep(Random.nextInt(20).seconds)

      val item = NewsItem(
        "http://newssite/news/" + self.path.name,
        "测试新闻" + self.path.name,
        self.path.name,
        TimeUtils.now().toString,
        "内容简介", "新闻正文")

      taskRef ! GetNewsItem(item)
      context.stop(self)
  }

SearchPageTask的代码逻辑就比较易懂了,这里使用sleep来模拟实际抓取新闻时的耗时。生成结果后返回数据给`taskRef`,并终止自己。

执行测试

./sbt
akka-action > testOnly me.yangbajing.akkaaction.scattergather.ScatterGatherTest

总结

这是一个简单的Akka实例,实现了任务分发与结果聚合。提供了一种在指定时间内返回部份有效数据,同时任务继续执行的方式。这种分散、聚合的模式在实际生产中很常用,比如对多种数据源的整合,或某些需要长时间运行同时对返回数据完整性无强制要求的情况等。

MetricActor演示了怎么自定义Actor,并为其提供一些侦测点的方式。以后有时间会写篇详文介绍。

© 著作权归作者所有

羊八井

羊八井

粉丝 93
博文 41
码字总数 51095
作品 0
朝阳
技术主管
私信 提问
加载中

评论(13)

羊八井
羊八井 博主

引用来自“天天天”的评论

只能单机玩
用akka-actor-remote可以扩展多机,akka也带了cluster
天天天
天天天
只能单机玩
Narcissu5
Narcissu5
两年前学了akka,现在还没有用上
壹峰
壹峰

引用来自“Erp管理员_付强”的评论

引用来自“红薯”的评论

代码扔到 git.oschina.net 吧 :)

不行,有github为啥不用
心尖偏左
心尖偏左
[79]
jacksu
jacksu
jacksu
jacksu
欢迎大家关注: [scala工具库](https://github.com/jacksu/utils4s) ,里面包含各种库的测试用例和使用说明文档
欢迎一起学习
Fancy2015
Fancy2015
Scala写多线程还是挺爽
羊八井
羊八井 博主

引用来自“Erp管理员_付强”的评论

引用来自“红薯”的评论

代码扔到 git.oschina.net 吧 :)

不行,有github为啥不用
两边都放
erpadmin
erpadmin

引用来自“红薯”的评论

代码扔到 git.oschina.net 吧 :)

不行,有github为啥不用
2015总结暨2016展望

2015已过去,2016到来。展望未来也总结过去。 2015 2015年到了一家新的公司,是一家做大数据服务的创业公司(准备说是2014年底)。刚到公司时我们只有几人,到现在已经成为一家50人左右的中小...

羊八井
2016/01/07
121
2
熟练的掌握Scala语言系列课程

课程名字:熟练的掌握Scala语言系列课程 课程网盘下载: http://pan.baidu.com/s/1pJuRAsV 密码: ahr3 课程内容: 共10章,58课时,总时长944分钟 想要深入研究spark,掌握好scala至关重要,目...

混坛魔王
2015/01/09
844
4
Scala 技术周刊 | 第 24 期

这里有最新的 Scala 社区动态、技术博文。 微信搜索 「scalacool」关注我们,及时获取最新资讯。 深度阅读 Resolve me, Implicitly 依赖注入 Refined types, what are they good for? 让类型...

ScalaCool
2017/10/23
0
0
分享一套Netty&ZeroMQ视频实战教程

该视频教程来源于微信群友分享,现在免费分享给大家,希望对你们有用。 视频教程目录结构如下: │ ├─1、课程介绍 │ │ 1-1 课程介绍.avi │ │ 1-2 初始设计.avi │ │ 1-课程介绍.pdf ...

架构之路
2018/01/04
0
0
《Akka应用模式:分布式应用程序设计实践指南》读书笔记3

分布式领域驱动设计   DDD领域驱动设计,应该就是一种系统设计的方法论,可以知道人们设计软件。其实老外就喜欢总结一些方法论用于指导实践,这一点还是很重要的。 DDD概述   DDD是一套关...

gabrywu
2018/06/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

和领导相处的5个“潜规则”,让你段位越来越高,值得收藏

在职场中很多伙伴把握不好分寸,不能判断与领导之间合适的距离,造成一些没有必要的误会。和领导相处一定要记住这5个潜规则,让你段位越来越高,早早实现自己的价值。 勇敢说出自己的想法 跟...

cenfeng123
10分钟前
0
0
maven配置阿里镜像库

maven配置指南 打开maven的配置文件(windows机器一般在maven安装目录的conf/settings.xml),在<mirrors></mirrors>标签中添加mirror子节点: <mirror> <id>aliyunmaven</id> <mirror......

观海562
13分钟前
0
0
包含 min 函数的栈

定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的 min 函数。 思路:利用两个栈,Data 栈和 Min 栈 压入过程中,min 栈随着 Data 栈一起增长。 如果压入一个 5 ,当前数和 min ...

Garphy
14分钟前
0
0
做好一名linux运维工程师

如何做好一个合格的运工程师,运维工程师前景怎么样呢?就这些问题,与大家交流一下。首先对于运维工程师的要求是十分严苛的了,运维工程师不但要针对不同的问题做出响应,而且需要不断的补充...

xiangyunyan
15分钟前
0
0
docker 安装 sonar

docker run --name db -e POSTGRES_USER=sonar -e POSTGRES_PASSWORD=sonar -d postgres docker run --name sq --link db -e SONARQUBE_JDBC_URL=jdbc:postgresql://db:5432/sonar -p 9000:9......

qiang123
27分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部