package com.ws.akka
// 启动消息
case object StartOkMsg
// 注册成功消息
case object RegistOkMsg
// 注册信息消息
case class RegistMsg(id: String, memory: Int, core: Int)
// 自己给自己的心跳信息
case object HeartbeatSelfMsg
// 心跳信息
case class HeartbeatMsg(id: String)
// 移出超时的worker信息
case object RemoveErroActorMsg
注册信息类
package com.ws.akka
class RegistInfo(val id: String, var memory: Int, var core: Int) {
var hearTime: Long = _
}
worker类
package com.ws.akka
import java.util.UUID
import akka.actor.{Actor, ActorSelection, ActorSystem, Props}
import com.typesafe.config.ConfigFactory
import scala.concurrent.duration._
class Worker extends Actor {
val id: String = UUID.randomUUID().toString
var masterprox: ActorSelection = _
override def preStart(): Unit = {
masterprox = context.actorSelection("akka.tcp://MASTER_ACTOR_SYSTEM@localhost:8888/user/MASTER_ACTOR")
println("WORKER去这里注册了" + "akka.tcp://MASTER_ACTOR_SYSTEM@localhost:8888/user/MASTER_ACTOR")
masterprox ! RegistMsg(id, 4096, 8)
}
override def receive: Receive = {
case RegistOkMsg =>
// 注册成功后 向master定时通讯报活
import context.dispatcher
context.system.scheduler.schedule(0 millisecond, 5000 millisecond, self, HeartbeatSelfMsg)
case StartOkMsg => println("WORKER启动完成")
case HeartbeatSelfMsg =>
println("Master我还活着")
masterprox ! HeartbeatMsg(id)
}
}
object Worker {
def main(args: Array[String]): Unit = {
val hostname = "localhost"
val port = 9999
val confstr: String =
s"""
|akka.actor.provider = "akka.remote.RemoteActorRefProvider"
|akka.remote.netty.rpc.hostname="$hostname"
|akka.remote.netty.rpc.port="$port"
|""".stripMargin
val conf = ConfigFactory.parseString(confstr)
val workeractorsystem = ActorSystem("WORKER_ACTOR_SYSTEM", conf)
val workeractor = workeractorsystem.actorOf(Props[Worker], "WORKER_ACTOR")
workeractor ! StartOkMsg
}
}
Master类
package com.ws.akka
import akka.actor.{Actor, ActorSystem, Props}
import com.typesafe.config.ConfigFactory
import scala.collection.mutable
import scala.concurrent.duration._
class Master extends Actor {
val registInfo = new mutable.HashMap[String, RegistInfo]()
override def preStart(): Unit = {
import context.dispatcher
context.system.scheduler.schedule(0 millisecond, 10 * 1000 millisecond, self, RemoveErroActorMsg)
}
override def receive: Receive = {
case RegistMsg(id, memory, core) =>
registInfo.put(id, new RegistInfo(id, memory, core))
println("Worker注册成功,ID:" + id + "--->内存:" + memory + "--->cpu核数:" + core)
sender() ! RegistOkMsg
case StartOkMsg => println("Master启动完成")
case HeartbeatMsg(id) =>
if (registInfo.contains(id)) {
registInfo(id).hearTime = System.currentTimeMillis()
println("收到心跳信息")
}
case RemoveErroActorMsg =>
val errs = registInfo.values.filter(System.currentTimeMillis() - _.hearTime > 10000)
errs.foreach(registInfo -= _.id)
println("当前worker个数----" + registInfo.size)
}
}
object Master {
def main(args: Array[String]): Unit = {
val hostname = "localhost"
val port = "8888"
val confstr: String =
s"""
|akka.actor.provider = "akka.remote.RemoteActorRefProvider"
|akka.remote.netty.tcp.hostname="$hostname"
|akka.remote.netty.tcp.port="$port"
|""".stripMargin
val config = ConfigFactory.parseString(confstr)
val masteractorsys = ActorSystem("MASTER_ACTOR_SYSTEM", config)
val mact = masteractorsys.actorOf(Props[Master], "MASTER_ACTOR")
mact ! StartOkMsg
}
}