设为首页 加入收藏

TOP

Akka(4): Routers - 智能任务分配(一)
2017-10-09 14:10:01 】 浏览:7661
Tags:Akka Routers 智能 任务 分配

    Actor模式最大的优点就是每个Actor都是一个独立的任务运算器。这种模式让我们很方便地把一项大型的任务分割成若干细小任务然后分配给不同的Actor去完成。优点是在设计时可以专注实现每个Actor的功能,在实际运算时由于每个Actor都在独立的线程里运行,能充分利用多核CPU的优势实现相似并行运算的效率。我们同样可以把一个独立的功能按不同的输入分配给多个Actor去完成以达到同样的效率提高目的,这就是Akka的Routing模式了。Routing模式的特点是所有运算Actor的运算逻辑都是相同的,分别对不同的输入进行相同的运算。不过我们应该知道运算结果的顺序是无法预计的,毕竟Actor模式是典型的无序运算。Routing模式由Router和Routee组成:Routee是负责具体运算的Actor(因为运算逻辑必须在Actor的receive里实现),Router的主要功能是把外界发来的运算指令按照某种指定的方式分配给Routee去运算。可以说Router不是标准的Actor,因为它不需要实现任何其它的功能,基本功能是预设嵌入的。Router的信箱直接代表了任务分配逻辑,与标准Actor逐个运算信箱中消息相比,能大大提高任务分配效率。Akka自带许多现成的任务分配模式,以不同的算法来满足不同的任务分配要求。这些算法的配置可以在配置文件或者代码中定义。Router又可分Pool和Group两种模式:在Router-Pool模式中Router负责构建所有的Routee。如此所有Routee都是Router的直属子级Actor,可以实现Router对Routees的直接监管。由于这种直接的监管关系,Router-Pool又可以按运算负载自动增减Routee,能更有效地分配利用计算资源。Router-Group模式中的Routees由外界其它Actor产生,特点是能实现灵活的Routee构建和监控,可以用不同的监管策略来管理一个Router下的Routees,比如可以使用BackoffSupervisor。从另一方面来讲,Router-Group的缺点是Routees的构建和管理复杂化了,而且往往需要人为干预。

下面我们先做个示范:

import akka.actor._ import akka.routing._ import scala.annotation.tailrec object FibonacciRoutee { case class FibonacciNumber(nbr: Int) def props = Props[FibonacciRoutee] } class FibonacciRoutee extends Actor with ActorLogging { import FibonacciRoutee._ override def receive: Receive = { case FibonacciNumber(nbr) => val answer = fibonacci(nbr) log.info(s"${self.path.name}'s answer: Fibonacci($nbr)=$answer") } private def fibonacci(n: Int): Int = { @tailrec def fib(n: Int, b: Int, a: Int): Int = n match { case 0 => a case _ => fib(n - 1, a + b, b) } fib(n, 1, 0) } } object RouterDemo extends App { import FibonacciRoutee._ val routingSystem = ActorSystem("routingSystem") val router = routingSystem.actorOf( FromConfig.props(FibonacciRoutee.props) ,"balance-pool-router") router ! FibonacciNumber(10) router ! FibonacciNumber(13) router ! FibonacciNumber(15) router ! FibonacciNumber(17) scala.io.StdIn.readLine() routingSystem.terminate() }

在这个例子里我们用3个Routees来根据指示计算Fibonacci。FibonacciRoutee只有一项功能:就是按输入计算Fibonacci数。我们看到,Router构建过程十分简单。在我们的例子里只需要读出配置文件内容就可以了。balance-pool-router是配置文件里的一个定义项:

akka { prio-dispatcher { mailbox-type = "PriorityMailbox" } actor { deployment { /balance-pool-router { router = balancing-pool nr-of-instances = 3 pool-dispatcher { 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 = 3 # Parallelism (threads) ... ceil(available processors * factor) parallelism-factor = 2.0 # Max number of threads to cap factor-based parallelism number to parallelism-max = 3 } # Throughput defines the maximum number of messages to be # processed per actor before the thread jumps to the next actor. # Set to 1 for as fair as possible. throughput = 1 } } } } }

Routing模式设置的完整标识是akka.actor.deployment{/balance-pool-router}。完成构建router后我们直接向router发送计算指令,运算结果如下:

[INFO] [05/30/2017 20:13:52.323] [routingSystem-BalancingPool-/balance-pool-router-5] [akka://routingSystem/user/balance-pool-router/$b] $b's answer: Fibonacci(13)=233
[INFO] [05/30/2017 20:13:52.323] [routingSystem-BalancingPool-/balance-pool-router-7] [akka://routingSystem/user/balance-pool-router/$a] $a's answer: Fibonacci(10)=55
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Akka(5): ConsistentHashing R.. 下一篇Akka(3): Actor监管 - 细述Bac..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目