供自己查看。。。。。。。。。。。。。。。。。。。。。。。
//这是NameNode节点
package scala
import akka.actor.{Actor, ActorSystem, Props}
import com.typesafe.config.{Config, ConfigFactory}
import scala.collection.mutable
import scala.concurrent.duration._
/**
* Created by Administrator on 2017/10/18.
*/
class Master(var masterHostName:String,var masterPort:Int) extends Actor{
private var id2workerInfo = new mutable.HashMap[String,WorkerInfo]()
private var workerInfos = mutable.HashSet[WorkerInfo]()
override def preStart(): Unit = {
//启动定时扫描
import context.dispatcher
context.system.scheduler.schedule(0 millis ,15000 millis,self,CheckTimeOut)
}
override def receive: Receive = {
case RegisterWorker(workerID,cpu,memory) =>{
val workerInfo = new WorkerInfo(workerID,cpu,memory)
id2workerInfo(workerID)=workerInfo
// id2workerInfo.put(workerID,workerInfo)
// id2workerInfo+=(workerID -> workerInfo)
workerInfos += workerInfo
sender() ! RegisteredWorker(s"${masterHostName}:${masterPort}")
}
case Heartbeat(workerID) => {
val currentTime = System.currentTimeMillis()
var workerInfo=id2workerInfo(workerID)
//更新上一次的心跳时间
workerInfo.lastHeartBeatTime=currentTime
id2workerInfo(workerID)=workerInfo
workerInfos +=workerInfo
}
case CheckTimeOut =>{
val currentTime= System.currentTimeMillis()
//true 代表这个数据我们要
//false 代表这个数据我们不要
val deadNode = workerInfos.filter( workerInfo => currentTime - workerInfo.lastHeartBeatTime > 15000 )
deadNode.foreach( w =>{
id2workerInfo -= w.workerId
workerInfos -= w
})
println("当前我们注册上来的worker的个数:"+workerInfos.size)
}
}
}
object Master{
val MASTER_ACTORSYSTEM="MasterActorSystem"
val MASTER_NAME="master"
def main(args: Array[String]): Unit = {
val hostname=args(0)
val port=args(1).toInt
val str=
s"""
|akka.actor.provider = "akka.remote.RemoteActorRefProvider"
|akka.remote.netty.tcp.hostname =${hostname}
|akka.remote.netty.tcp.port=${port}
""".stripMargin
val conf: Config = ConfigFactory.parseString(str)
val actorSystem = ActorSystem(MASTER_ACTORSYSTEM,conf)
actorSystem.actorOf(Props(new Master(hostname,port)),MASTER_NAME)
}
}
//这是DataNode节点
package scala
import java.util.UUID
import akka.actor.{Actor, ActorSelection, ActorSystem, Props}
import com.typesafe.config.ConfigFactory
import scala.concurrent.duration._
/**
* Created by Administrator on 2017/10/18.
*/
class Worker(var masterHostname:String,var masterPort:Int ,var cpu:Int,var memory:Int) extends Actor{
var masterRef:ActorSelection =_
// val name:String=_ //""
// val age:Int=_ // 0
var workerID:String=_
override def preStart(): Unit = {
//masterRef 的引用
masterRef= context.actorSelection(s"akka.tcp://${Master.MASTER_ACTORSYSTEM}@${masterHostname}:${masterPort}/user/${Master.MASTER_NAME}")
//val workerID:String,val cpu:Int,val memeory:Int
workerID = UUID.randomUUID().toString
masterRef ! RegisterWorker(workerID,cpu,memory)
}
override def receive: Receive = {
case RegisteredWorker(masterURL) =>{
/**
* 这个地方稍微说一下:
* 理论上来讲,我们worker注册,应该会有两个结果:
* 1) 注册成功
* 2)注册失败
*
* 接下来我们需要定时的去发送 心跳信息
* 每隔十秒就发送一次心跳
*/
/**
* initialDelay: FiniteDuration, 你的这个事多久以后开始干!! 0
interval: FiniteDuration, 你的这个事每隔多长时间干一次 10
receiver: ActorRef, 你的这个事是发送给谁的? master
message: Any 你到底干的是什么事? 心跳
*/
import context.dispatcher
context.system.scheduler.schedule(0 millis ,10000 millis,self,SendHeartBeat)
}
case SendHeartBeat =>{
/**
*
* 好处就是这个里面可以做好多在发送心跳之前需要做的准备工作
*、、、、、、、、、、、、、、
* 、、、、、、、、、、、、、、
*/
sender()
//可以给Master发送心跳信息
masterRef ! Heartbeat(workerID)
}
}
}
object Worker{
val WORKER_ACTORSYSTEM="WorkerActorSystem"
val WORKER_NAME="worker"
def main(args: Array[String]): Unit = {
//实际上下面的这些东西应该是通过解析配置文件得到的
val hostname=args(0)
val masterHostname=args(1)
val masterPort=args(2).toInt
val cpu=args(3).toInt
val memory=args(4).toInt
val port=args(5).toInt
val str=
s"""
|akka.actor.provider = "akka.remote.RemoteActorRefProvider"
|akka.remote.netty.tcp.hostname = ${hostname}
|akka.remote.netty.tcp.port=${port}
""".stripMargin
val conf = ConfigFactory.parseString(str)
val actorSystem = ActorSystem(WORKER_ACTORSYSTEM,conf)
actorSystem.actorOf(Props(new Worker(masterHostname,masterPort,cpu,memory)),WORKER_NAME)
}
}
//这是发送信息所用的样例类
package scala
/**
* Created by Administrator on 2017/10/19.
*/
//要发送消息的类型:
//worker -> master worker向Master注册消息
case class RegisterWorker(val workerID:String,val cpu:Int,val memeory:Int) extends Serializable
//master -> worker worker注册完成消息
case class RegisteredWorker(val masterURL:String) extends Serializable
//worker -> master 发送心跳信息
case class Heartbeat(val workerID:String) extends Serializable
case object SendHeartBeat
case object CheckTimeOut
//用于封装worker
package scala
/**
* Created by Administrator on 2017/10/19.
*/
/**
* 用于封装worker的信息
*/
class WorkerInfo(var workerId:String,var cpu:Int,var memory:Int){
var lastHeartBeatTime:Long=_
}