使用scala实现Akka底层的rpc通信

需求如下图:

Master代码:

package com.season.rpc.akka

import akka.actor.{Actor, ActorSystem, Props}
import com.typesafe.config.ConfigFactory
import scala.collection.mutable
import scala.concurrent.duration._

/**
  * Created by Administrator on 2017/5/2 0002.
  */
class Master extends Actor {

  val CHECK_INTERVAL = 15000
  val id2Worker = new mutable.HashMap[String,WorkerInfo]{}
  val workers = new mutable.HashSet[WorkerInfo]()

  override def preStart(): Unit = {
    //启动一个定时器
    import context.dispatcher
    context.system.scheduler.schedule(0 millis,CHECK_INTERVAL millis,self,CheckTimeOutWorker)

  }

  override def receive: Receive = {
    case RegisterWorker(workerId,memory,cores) => {
      println(s"a connection from worker workerId : $workerId ram: $memory cpu: $cores")
      val workerInfo = new WorkerInfo(workerId,memory,cores)
      id2Worker(workerId) = workerInfo
      workers += workerInfo
      sender ! RegisteredWorker
    }
    case HeartBeat(workerId) => {
      println(s"a heartbeat from worker workerId : $workerId")
      val workerInfo: WorkerInfo = id2Worker(workerId)
      val current = System.currentTimeMillis()
      workerInfo.lastHeartbeatTime = current
    }

    case CheckTimeOutWorker => {
      println("internal msg check")

      val current = System.currentTimeMillis()
      //过滤掉超时的workers
      val deadWorkers = workers.filter(w => current - w.lastHeartbeatTime > CHECK_INTERVAL)
//      for (workerInfo <- deadWorkers){
//        id2Worker -= workerInfo.id
//        workers -= workerInfo
//      }
      deadWorkers.foreach(workerInfo => {
        id2Worker -= workerInfo.id
        workers -= workerInfo
      })
      println(id2Worker.size)

    }
  }
}

object Master {

  val MASTER_ACTOR_SYSTEM = "MasterSystem"
  val MASTER_ACTOR_NAME = "Master"


  def main(args: Array[String]): Unit = {
    val host = args(0)
    val port = args(1).toInt
    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)
    val actorSystem = ActorSystem(MASTER_ACTOR_SYSTEM, config)
    val masterActor = actorSystem.actorOf(Props[Master], MASTER_ACTOR_NAME)
    //masterActor ! "CheckTimeout"
  }
}
Worker代码:

package com.season.rpc.akka

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/5/2 0002.
  */
class Worker(val host: String ,val port: Int ,val memory: Int ,val cores: Int) extends Actor{

  val WORKER_ID = UUID.randomUUID().toString
  val HEARTBEAT_INTERVAL = 10000

  var masterRef : ActorSelection =_

  override def preStart(): Unit = {
    masterRef = context.actorSelection(s"akka.tcp://${Master.MASTER_ACTOR_SYSTEM}@$host:$port/user/${Master.MASTER_ACTOR_NAME}")
    masterRef ! RegisterWorker(WORKER_ID,memory,cores)
  }

  override def receive: Receive = {

    case RegisteredWorker => {
      import context.dispatcher
      context.system.scheduler.schedule(0 millis,HEARTBEAT_INTERVAL millis,self,SendHearBeat)
    }

    case SendHearBeat => {
      masterRef ! HeartBeat(WORKER_ID)
    }
  }
}

object  Worker {

  val WORKER_ACTOR_SYSTEM = "WorkerSystem"
  val WORKER_ACTOR_NAME = "Worker"

  def main(args: Array[String]): Unit = {
    val workerHost = args(0)
    val workerPort = args(1).toInt
    val masterHost = args(2)
    val masterPort = args(3).toInt

    val workerMemory = args(4).toInt
    val workerCores = args(5).toInt

    val configStr =
      s"""
         |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
         |akka.remote.netty.tcp.hostname = "$workerHost"
         |akka.remote.netty.tcp.port = "$workerPort"
       """.stripMargin

    val config = ConfigFactory.parseString(configStr)

    val actorSystem = ActorSystem(WORKER_ACTOR_SYSTEM, config)

    actorSystem.actorOf(Props(new Worker(masterHost,masterPort,workerMemory,workerCores)),WORKER_ACTOR_NAME)
  }
}
workinfo.scala

package com.season.rpc.akka

/**
  * Created by Administrator on 2017/5/2 0002.
  */
class WorkerInfo(val id : String , val memory : Int , val cores : Int) {
  var lastHeartbeatTime: Long = 0

}
信息类:

package com.season.rpc.akka

/**
  * Created by Administrator on 2017/5/2 0002.
  */
case class RegisterWorker(workerId: String , memory: Int ,cores: Int) extends Serializable

case class RegisteredWorker() extends Serializable

case class HeartBeat(workerId : String) extends Serializable

case object CheckTimeOutWorker

case object SendHearBeat





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值