• 大数据学习——akka自定义RPC


    实现

    package cn.itcast.akka
    
    import akka.actor.{Actor, ActorSystem, Props}
    import akka.actor.Actor.Receive
    import com.typesafe.config.ConfigFactory
    
    import scala.collection.mutable
    
    import scala.concurrent.duration._
    
    class Master(val host: String, val port: Int) extends Actor {
    
      //保存WorkerID 到 WorkerInfo的映射
      val idToWorker = new mutable.HashMap[String, WorkerInfo]()
      //保存所的WorkerInfo信息
      val workers = new mutable.HashSet[WorkerInfo]()
    
      val CHECK_INTERVAL = 15000
    
      override def preStart(): Unit = {
        //导入隐式转换
        import context.dispatcher
        context.system.scheduler.schedule(0 millis, CHECK_INTERVAL millis, self, CheckTimeOutWorker)
      }
    
      override def receive: Receive = {
        //Worker发送个Mater的注册消息
        case RegisterWorker(workerId, cores, memory) => {
          if (!idToWorker.contains(workerId)) {
            //封装worker发送的信息
            val workerInfo = new WorkerInfo(workerId, cores, memory)
            //保存workerInfo
            idToWorker(workerId) = workerInfo
            workers += workerInfo
            //Master向Worker反馈注册成功的消息
            sender ! RegisteredWorker(s"akka.tcp://${Master.MASTER_SYSTEM}@$host:$port/user/${Master.MASTER_NAME}")
          }
        }
    
        //Worker发送给Master的心跳信息
        case Heartbeat(workerId) => {
          if (idToWorker.contains(workerId)) {
            val workerInfo = idToWorker(workerId)
            val currentTime = System.currentTimeMillis()
            //更新上一次心跳时间
            workerInfo.lastHeartbeatTime = currentTime
          }
        }
    
        //检测超时的Worker
        case CheckTimeOutWorker => {
          val currentTime = System.currentTimeMillis()
          val deadWorkers: mutable.HashSet[WorkerInfo] = workers.filter(w => currentTime - w.lastHeartbeatTime > CHECK_INTERVAL)
          //      for(w <- deadWorkers) {
          //        idToWorker -= w.id
          //        workers -= w
          //      }
          deadWorkers.foreach(w => {
            idToWorker -= w.id
            workers -= w
          })
          println("alive worker size : " + workers.size)
        }
      }
    }
    
    object Master {
    
      val MASTER_SYSTEM = "MaterActorSystem"
      val MASTER_NAME = "Master"
    
      def main(args: Array[String]) {
    
        //    val host = args(0)
        //    val port = args(1).toInt
        val host = "127.0.0.1"
        val port = 8888
        val confStr =
          s"""
             |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
             |akka.remote.netty.tcp.hostname = "$host"
             |akka.remote.netty.tcp.port = "$port"
           """.stripMargin
        val conf = ConfigFactory.parseString(confStr)
        //ActorSystem是单例的,用于创建Acotor并监控actor
        val actorSystem = ActorSystem(MASTER_SYSTEM, conf)
        //通过ActorSystem创建Actor
        actorSystem.actorOf(Props(new Master(host, port)), MASTER_NAME)
        actorSystem.awaitTermination()
    
      }
    }
    package cn.itcast.akka
    
    trait Message extends Serializable
    
    //Worker -> Master
    case class RegisterWorker(id: String, cores: Int, memory: Int) extends Message
    
    //Master -> Worker
    case class RegisteredWorker(masterUrl: String) extends Message
    
    //Worker -> Master
    case class Heartbeat(id: String) extends Message
    
    //Worker internal message
    case object SendHeartbeat
    
    //Master internal message
    case object CheckTimeOutWorker
    package cn.itcast.akka
    
    import java.util.UUID
    import akka.actor.{Actor, ActorSelection, ActorSystem, Props}
    import com.typesafe.config.ConfigFactory
    
    import scala.concurrent.duration._
    
    class Worker(val cores: Int, val memory: Int, val masterHost: String, val masterPort: Int) extends Actor {
    
      //Master的引用
      var master: ActorSelection = _
      //Worker的ID
      val workerId = UUID.randomUUID().toString
      //masterUrl
      var masterUrl: String = _
    
      val HEARTBEAT_INTERVAL = 10000
    
      //preStart在构造器之后receive之前执行
      override def preStart(): Unit = {
        //首先跟Master建立连接
        master = context.actorSelection(s"akka.tcp://${Master.MASTER_SYSTEM}@$masterHost:$masterPort/user/${Master.MASTER_NAME}")
        //通过master的引用向Master发送注册消息
        master ! RegisterWorker(workerId, cores, memory)
      }
    
      override def receive: Receive = {
        //Master发送给Worker注册成功的消息
        case RegisteredWorker(masterUrl) => {
          this.masterUrl = masterUrl
          //启动定时任务,向Master发送心跳
          //导入隐式转换
          import context.dispatcher
          context.system.scheduler.schedule(0 millis, HEARTBEAT_INTERVAL millis, self, SendHeartbeat)
        }
    
        case SendHeartbeat => {
          //向Master发送心跳
          master ! Heartbeat(workerId)
        }
      }
    }
    
    object Worker {
      def main(args: Array[String]) {
    
        //Worker的地址和端口
        //    val host = args(0)
        //    val port = args(1).toInt
        //    val cores = args(2).toInt
        //    val memory = args(3).toInt
        val host = "127.0.0.1"
        val port = 9999
        val cores = 8
        val memory = 1024
    
        //Master的地址和端口
        //    val masterHost = args(4)
        //    val masterPort = args(5).toInt
        val masterHost = "127.0.0.1"
        val masterPort = 8888
    
        val confStr =
          s"""
             |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
             |akka.remote.netty.tcp.hostname = "$host"
             |akka.remote.netty.tcp.port = "$port"
           """.stripMargin
        val conf = ConfigFactory.parseString(confStr)
        //单例的ActorSystem
        val actorSystem = ActorSystem("WorkerActorSystem", conf)
        //通过actorSystem来创建Actor
        val worker = actorSystem.actorOf(Props(new Worker(cores, memory, masterHost, masterPort)), "Worker")
        actorSystem.awaitTermination()
      }
    }
    package cn.itcast.akka
    
    
    class WorkerInfo(val id: String, val cores: Int, val memory: Int) {
    
      //TODO
      var lastHeartbeatTime: Long = _
    
    }

     

  • 相关阅读:
    数学+高精度 ZOJ 2313 Chinese Girls' Amusement
    最短路(Bellman_Ford) POJ 1860 Currency Exchange
    贪心 Gym 100502E Opening Ceremony
    概率 Gym 100502D Dice Game
    判断 Gym 100502K Train Passengers
    BFS POJ 3278 Catch That Cow
    DFS POJ 2362 Square
    DFS ZOJ 1002/HDOJ 1045 Fire Net
    组合数学(全排列)+DFS CSU 1563 Lexicography
    stack UVA 442 Matrix Chain Multiplication
  • 原文地址:https://www.cnblogs.com/feifeicui/p/10996077.html
Copyright © 2020-2023  润新知