模仿NameNode和DataNode之间通信

供自己查看。。。。。。。。。。。。。。。。。。。。。。。
//这是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=_
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值