Akka自定义简单rpc

1. 消息的传递,从一个Actor到另一个Actor或者从自己到自己。

//网络通信需要序列化反序列化
trait RemoteMessage extends Serializable
//Woker-->Master
case class RegisterWoker(wokerId:String , momery:Int, cores:Int) extends  RemoteMessage
//Master-->Woker
case class RegisteredWoker(masterURL:String) extends  RemoteMessage
//Woker-->Woker
case object SendHeartbeat
//Woker-->Master
case class Heartbeat(wokerId:String) extends  RemoteMessage
//Master-->Master
case object CheckTimeOutWoker

2. WokeInfo

class WokerInfo(val wokerId:String,val memory:Int, val cores:Int){
  //上次一心跳的时间
  var lastHeartbeatTime:Long = _
}

3.Woker类

import java.util.UUID

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

class Woker(val host:String, val port:Int, val momery:Int, val cores:Int) extends  Actor{
    val wokerId:String = UUID.randomUUID().toString
    var master:ActorSelection = _
    var Time = 10000


  override def preStart(): Unit = {
    import context.dispatcher
    master = context.actorSelection(s"akka.tcp://MasterSystem@$host:$port/user/Master")
    master ! RegisterWoker(wokerId,momery,cores)
  }

  override def receive: Receive = {
    case RegisteredWoker(masterURL) =>{
      println("注册成功! 地址"+masterURL)
      import context.dispatcher
      context.system.scheduler.schedule(0 millis,Time millis,self,SendHeartbeat)
    }
    case SendHeartbeat => {
      //发送心跳
      println("发送心跳")
      master ! Heartbeat(wokerId)
    }
  }
}

object Woker {
  def main(args: Array[String]): Unit = {
    val host: String = args( 0 )
    val port: Int = args( 1 ).toInt
    val configString: String =
      s"""
         |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
         |akka.remote.netty.tcp.hostname = "$host"
         |akka.remote.netty.tcp.port = "$port"
    """.stripMargin
    val config = ConfigFactory.parseString( configString )
    val actorSystem = ActorSystem( "WokerSystem", config )
    actorSystem.actorOf( Props( new Woker( args( 2 ), args( 3 ).toInt, args( 4 ).toInt, args( 5 ).toInt ) ), "Woker" )
    actorSystem.awaitTermination()
  }
}

4. Master类

import java.util.UUID

import akka.actor

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

import scala.collection.mutable

class Master(val host:String, val port:Int) extends  Actor{
   val idToWoker = new mutable.HashMap[String,WokerInfo]()
   val wokers = new mutable.HashSet[WokerInfo]()
   val Time = 15000

  override def preStart(): Unit = {
    import context.dispatcher
    context.system.scheduler.schedule(0 millis,Time millis,self,CheckTimeOutWoker)
  }

  override def receive: Receive = {
    case RegisterWoker(wokerId,momery,cores) =>{
      if(!idToWoker.contains(wokerId)){
        val wokerInfo = new WokerInfo(wokerId,momery,cores)
        idToWoker(wokerId) = wokerInfo
        wokers+=wokerInfo
      }
      println("一个Woker注册了")
      sender ! RegisteredWoker(s"akka.tcp://MasterSystem@$host:$port/user/Master")
    }
    case Heartbeat(wokerId) =>{
      val currentTime = System.currentTimeMillis()
      if(idToWoker.contains(wokerId)){
        val wokerInfo = idToWoker(wokerId)
        wokerInfo.lastHeartbeatTime = currentTime
      }

    }
    case CheckTimeOutWoker =>{

      val currentTime = System.currentTimeMillis()
      val remote = wokers.filter(t=>currentTime-t.lastHeartbeatTime>=15000)
      for(r<-remote){
        wokers-=r
        idToWoker-=r.wokerId
        println("一个Woker断开了")
      }
      println("现有Woker:"+wokers.size)
    }
   }
}
object Master{
  def main(args: Array[String]): Unit = {
    val host:String = args(0)
    val port:Int = args(1).toInt
    val configString:String =  s"""
                                  |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
                                  |akka.remote.netty.tcp.hostname = "$host"
                                  |akka.remote.netty.tcp.port = "$port"
    """.stripMargin
    val config = ConfigFactory.parseString(configString)
    val actorSystem = ActorSystem("MasterSystem",config)
    actorSystem.actorOf(Props(new Master(host,port)),"Master")
    actorSystem.awaitTermination()
  }
}
//s"akka.tcp://MasterSystem@$host:$port/user/Master"

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值