Akka framework现在已经是Scala语言的一部分了,用它编写分布式程序是相当简单的,本文将一步一步地讲解如何做到scale up & scale out。
- 简单的单线程程序
package com.newegg.demo
import scala.concurrent.duration._
import scala.collection.mutable.ListBuffer
object PerfectNumber {
def sumOfFactors(number: Int) = {
(1 /: (2 until number)) { (sum, i) => if (number % i == 0) sum + i else sum }
}
def isPerfect(num: Int): Boolean = {
num == sumOfFactors(num)
}
def findPerfectNumbers(start: Int, end: Int) = {
require(start > 1 && end >= start)
val perfectNumbers = new ListBuffer[Int]
(start to end).foreach(num => if (isPerfect(num)) perfectNumbers += num)
perfectNumbers.toList
}
def main(args: Array[String]): Unit = {
val list = findPerfectNumbers(2, 100)
println("\nFound Perfect Numbers:" + list.mkString(","))
}
}
- 多线程程序
这个示例中要用到的“消息”定义在Data.scala文件中,内容如下:
package com.newegg.demo
import akka.actor.ActorRef
sealed trait Message
case class StartFind(start: Int, end: Int, replyTo: ActorRef) extends Message
case class Work(num: Int, replyTo: ActorRef) extends Message
case class Result(num: Int, isPerfect: Boolean) extends Message
case class PerfectNumbers(list: List[Int]) extends Message
用面向对象的方式把程序改造一下,把PerfectNumber.scala其中的部分代码抽取到一个单独的Worker.scala文件中:
package com.newegg.demo
import akka.actor.Actor
import akka.actor.ActorRef
class Worker extends Actor {
private def sumOfFactors(number: Int) = {
(1 /: (2 until number)) { (sum, i) => if (number % i == 0) sum + i else sum }
}
private def isPerfect(num: Int): Boolean = {
num == sumOfFactors(num)
}
def receive = {
case Work(num: Int, replyTo: ActorRef) =>
replyTo ! Result(num, isPerfect(num))
print("[" + num + "] ")
}
}
一部分代码抽取到Master.scala文件中:
package com.newegg.demo
import scala.collection.mutable.ListBuffer
import akka.actor.Actor
import akka.actor.ActorRef
import akka.actor.Props
import akka.routing.FromConfig
import akka.routing.ConsistentHashingRouter.ConsistentHashable