Akka(二):使用Akka模拟yarn

1.样例
        使用akka来模拟yarn集群的通信。流程图如下:

完整代码如下:

MyResourceManager.scala

import akka.actor.{Actor, ActorSystem, Props}
import com.typesafe.config.ConfigFactory
 
import scala.collection.mutable
import scala.concurrent.duration._
 
class MyResourceManager extends Actor{
  //将Worker信息存到map集合中
  val map = new mutable.HashMap[String, WorkerInfo]()
 
 
  override def preStart(): Unit = {
    println("preStart")
    import context.dispatcher
    context.system.scheduler.schedule(0.millisecond,5000.millisecond,self,CheckTimeOutWorker)
  }
 
  //消息的接受  此函数为偏函数 不需要写match
  override def receive: Receive = {
    //做模式匹配
    case "hello" =>{
      println("hello")
    }
 
    case CheckTimeOutWorker =>{
      val deadWorker: Iterable[WorkerInfo] = map.values.filter(x => System.currentTimeMillis() - x.lastHeartbeatTime > 15000)
 
      deadWorker.foreach(m =>{
        map -= m.workerId
      })
      println(s"current alive worker size: ${map.size}")
    }
 
    //匹配worker发送来的注册信息
    case Conf(workerId, memory, cores) => {
      //      println(s"workerId:$workerId,memory:$memory,cores:$cores")
      //将Worker的数据存到内存中
      val workInfo = new WorkerInfo(workerId, memory, cores)
      map(workerId) = workInfo
      //给发送者返回一个注册成功的响应
      sender() ! Confed
    }
 
 
    //接受Worker的心跳 并更新心跳时间
    case HeartBeat(workerId) =>   {
      //根据workerId查找对应的Worker信息
      if (map.contains(workerId)){
        val workerInfo: WorkerInfo = map(workerId)
        //更新Worker心跳的时间 更新到当前时间
        workerInfo.lastHeartbeatTime = System.currentTimeMillis()
      }
    }
 
  }
}
object MyResourceManager{
  def main(args: Array[String]): Unit = {
 
    val host = "localhost"
    val port = 1111
 
    val configstr =
      s"""
         |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
         |akka.remote.netty.tcp.hostname = $host
         |akka.remote.netty.tcp.port = $port
         |""".stripMargin
 
    val config = ConfigFactory.parseString(configstr)
    //创建MasterActorSystem(单例)
    val masterActorSystem = ActorSystem("MasterActorSystem", config)
    //通过Master创建Actor
    val masterActor = masterActorSystem.actorOf(Props[MyResourceManager], "MasterActor")
    //自己给自己发消息
    masterActor ! "hello"
  }
}

MyNodeManager.scala

import java.util.UUID
 
import akka.actor.{Actor, ActorSelection, ActorSystem, Props}
import com.typesafe.config.ConfigFactory
 
import scala.concurrent.duration._
 
 
class MyNodeManager extends Actor {
 
  var workerId = UUID.randomUUID().toString
 
  var selection: ActorSelection = _
 
 
  //是在构造方法之后,receive方法之前一定会调用一次
  override def preStart(): Unit = {
    //与master建立连接
    selection = context.actorSelection("akka.tcp://MasterActorSystem@localhost:1111/user/MasterActor")
    //向master注册信息
    selection ! Conf(workerId, 2040, 4)
  }
 
 
  //消息的接受  此函数为偏函数 不需要写match
  override def receive: Receive = {
    //做模式匹配
    case "hello" => {
      println("hello")
    }
 
    //向Master发送一个心跳
    case SendHeartBeat => {
      selection ! HeartBeat(workerId)
    }
 
 
    //启动定时器
    case Confed => {
      //导包 隐式转换
      import context.dispatcher
      context.system.scheduler.schedule(0.millisecond, 10000.millisecond, self, SendHeartBeat)
    }
 
  }
}
 
object MyNodeManager {
  def main(args: Array[String]): Unit = {
 
    val host = "localhost"
    val port = 2222
 
    val configStr =
      s"""
         |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
         |akka.remote.netty.tcp.hostname = $host
         |akka.remote.netty.tcp.port = $port
         |""".stripMargin
 
    val config = ConfigFactory.parseString(configStr)
    //创建WorkerActorSystem
    val workerActorSystem = ActorSystem("WorkerActorSysytem", config)
    //通过WorkActorSystem创建WorkerActor
    workerActorSystem.actorOf(Props[MyNodeManager], "WorkerActor")
  }
}

Message.scala

case class Conf(workerId: String, memory: Int, cores: Int)
 
case object Confed
 
case class WorkerInfo(workerId: String, memory: Int, cores: Int) {
 
  var lastHeartbeatTime: Long = _
}
 
case object SendHeartBeat
 
case class HeartBeat(workerId: String)
 
case object CheckTimeOutWorker
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值