最近在使用akka,写了一个基于akka的分布式求累加和的例子,思路很简单,在本地机器上把求和的任务均匀分配给不同步的节点去计算,并且把计算结果返回到本地机器,然后在本地进行再次进行合并,得到最终结果.
本地Actor : Master
package com.yc
import akka.actor.{Actor, ActorLogging}
import akka.util.Timeout
import scala.collection.mutable.ArrayBuffer
import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
import akka.pattern.ask
/**
* Created by yc
*/
class MasterActor extends Actor with ActorLogging{
val worker1 = context.actorSelection("akka.tcp://Worker1@182.254.211.164:2553/user/worker1")
//val worker2 = context.actorSelection("akka.tcp://Worker2@10.175.37.91:2554/user/worker2")
// val worker3 = context.actorSelection("akka.tcp://Worker3@10.175.37.91:2555/user/worker3")
//val worker4 = context.actorSelection("akka.tcp://Worker4@10.175.37.91:2556/user/worker4")
val futureResult = new ArrayBuffer[Future[BigInt]]()
val start = System.nanoTime()
implicit val timeout = Timeout(100 seconds)
var res:BigInt = 0
override def receive={
case message:String=>{
futureResult += (worker1?"1,1000000000").mapTo[BigInt]
//futureResult += (worker2?"500000001,1000000000").mapTo[BigInt]
// futureResult += (worker3?"500000001,750000000").mapTo[BigInt]
//futureResult += (worker4?"750000001,1000000000").mapTo[BigInt]
//futureResult += (worker1?"500000001,1000000000").mapTo[BigInt]
futureResult.foreach(p=>res += Await.result(p,timeout.duration))
log.info("the result of 1 add to 1000000000 = "+res)
println("use time:"+Stopwatch.format(System.nanoTime() - start))
}
}
}
本地actor启动类 LocalNodeApplication
package com.yc
import akka.actor.{ActorSystem, Props}
import com.typesafe.config.ConfigFactory
/**
* Created by yc
*/
object MasterAppilcation extends App{
val system = ActorSystem("MasterApp",ConfigFactory.load().getConfig("Master"))
val master = system.actorOf(Props[MasterActor],name = "master")
master ! "start"
//Thread.sleep(100000)
system.shutdown()
}
application.conf
Master {
akka {
actor {
provider = "akka.remote.RemoteActorRefProvider"
}
}
}
build.sbt
name := "Master"
version := "1.0"
scalaVersion := "2.11.8"
libraryDependencies += "com.typesafe.akka" % "akka-remote_2.11" % "2.4.11"
libraryDependencies += "com.typesafe.akka" % "akka-actor_2.11" % "2.4.11"
libraryDependencies += "com.typesafe.akka" % "akka-kernel_2.11" % "2.4.11"
远程actor
package com.yc
import akka.actor.Actor
/**
* Created by yc
*/
class Worker1Actor extends Actor{
override def receive = {
case message:String =>
val args = message.split(",")
val start:BigInt = BigInt(args(0))
val end:BigInt = BigInt(args(1))
var result:BigInt = 0
println("from:"+start+"to:"+end)
(start to end).foreach{
result += _
}
sender ! result
case _=>
println("your argments is wrong")
}
}
驱动类
package com.yc
import akka.actor.{ActorSystem, Props}
import akka.kernel.Bootable
import com.typesafe.config.ConfigFactory
/**
* Created by yc
*/
class Worker1Application extends Bootable{
val system = ActorSystem("Worker1",ConfigFactory.load().getConfig("Worker1"))
override def startup() = {
system.actorOf(Props[Worker1Actor],name="worker1")
}
override def shutdown() = {
system.terminate()
}
}
application.conf
Worker1 {
akka {
actor {
provider = "akka.remote.RemoteActorRefProvider"
}
remote {
enabled-transports = ["akka.remote.netty.tcp"]
netty.tcp {
hostname = "10.175.37.91"
port = 2553
}
}
}
}
build.sbt
name := "Worker1"
version := "1.0"
scalaVersion := "2.11.8"
libraryDependencies += "com.typesafe.akka" % "akka-remote_2.11" % "2.4.11"
libraryDependencies += "com.typesafe.akka" % "akka-actor_2.11" % "2.4.11"
libraryDependencies += "com.typesafe.akka" % "akka-kernel_2.11" % "2.4.11"
示例源码:http://download.youkuaiyun.com/detail/tingibandequ/9672455
https://www.codeproject.com/Articles/1135973/Akka-remoting