Scala总和实战

整体思路

1.启动master ,worker(node)

2.worker 向master传递注册信息,master放worker返回注册信息

3.worker,向master传递心跳机制,master定时检查心跳机制,并移除,超出时间未能传递心跳机制的机器

一.本地传本地信息代码

package Demo1

import akka.actor.{Actor, ActorSystem, Props}
import com.typesafe.config.ConfigFactory

class Master extends Actor{
  override def receive: Receive = {
    case "hello" =>{
      println("received........")
    }
  }
}

//在下面写一个伴生对象
object Master {
  def main(args: Array[String]): Unit = {

    //指定配置文件
    val confStr =
      s"""
         |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
         |akka.remote.netty.tcp.hostname = "localhost"
         |akka.remote.netty.tcp.port = 8888
         |""".stripMargin

    //解析配置文件
    val config = ConfigFactory.parseString(confStr)
    //创建ActorSystem
    val actorSystem = ActorSystem("MASTER_ACTOR_SYSTEM", config)
    //创建Actor
    val actorRef = actorSystem.actorOf(Props[Master])

    //发送消息
    actorRef.!("hello")

  }
}

多个线程之间相互传递信息

注意所有的分布式,都是小弟找老大的,什么时候找老大呢

造构造方法执行之后,receive方法执行之前,根master建立连接

先启动master线程,然后再启动worker线程

package Demo1

import akka.actor.{Actor, ActorSystem, Props}
import com.typesafe.config.ConfigFactory

class Master extends Actor{
  //receive其实就是一个偏函数,专门来做模式匹配的
  override def receive: Receive = {
    case "connect" =>{
      println("a work connected")
      
      //谁想master发送消息,就向谁返回一个消息
       sender() ! ("response")
    }
  }
}

//在下面写一个伴生对象
object Master {
  def main(args: Array[String]): Unit = {

    //指定配置文件
    val confStr =
      s"""
         |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
         |akka.remote.netty.tcp.hostname = "localhost"
         |akka.remote.netty.tcp.port = 8888
         |""".stripMargin

    //解析配置文件
    val config = ConfigFactory.parseString(confStr)
    //创建ActorSystem
    val actorSystem = ActorSystem("MASTER_ACTOR_SYSTEM", config)
    //创建Actor
    actorSystem.actorOf(Props[Master],"MASTER_ACTOR")

    //发送消息
    //不再自己跟自己发
    //actorRef.!("hello")

  }
}

 

import akka.actor.{Actor, ActorSelection, ActorSystem, Props}
import com.typesafe.config.ConfigFactory

class Worker extends Actor{
  /**
   * 在构造方法执行之前,receive方法执行之后,与master建立连接
   * 这个进程如何与master建立连接呢,这是就需要一个协议,这个协议可以用context表示
   *ctrl  +  o   显示重写的方法
   * @return
   */
  var masterRef: ActorSelection = _  //这相当于定义一个变量
  override def preStart(): Unit = {
    //masterRef是一个链接值,ActorSelection是一个该链接的类
    //这个协议里面传的是路径表示,你传到哪里去,
    //先找LocalHost的端口号8888,他有对应的ActorSystem 线程  ,并在actorSystem里面找具体哪个actor,因为一个
    //actorSystem下面可能有多个actor,一个actor可以认为是一个人,叫user ,后面根对应actor的名字
    //这样一句话,就知道Master的端口号,地址,以及actorSystem和下面哪个具体的actor,返回一个连接,也叫做代理对象
    //通过actorSelection 与master对应的actor连接起来
    masterRef = context.actorSelection("akka.tcp://MASTER_ACTOR_SYSTEM@localhost:8888/user/MASTER_ACTOR")

    //向master发送connect消息
    masterRef ! ("connect")
  }

  //receive就是一个偏函数,专门来做模式匹配的
  override def receive: Receive = {
    //接收master发送过来的消息
    case "ressponse" =>{
      println("response received from Master.......")
    
    }
  }
}
//建一个伴生对象
object Worker{
  def main(args: Array[String]): Unit = {
    //指定配置文件
    val confStr =
      s"""
         |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
         |akka.remote.netty.tcp.hostname = "localhost"
         |akka.remote.netty.tcp.port = 8889
         |""".stripMargin
    //解析配置文件
    val config = ConfigFactory.parseString(confStr)
    //创建ActorSystem
    val actorSystem = ActorSystem("Work_ACTOR_SYSTEM", config)
    //创建Actor
    actorSystem.actorOf(Props[Worker])
    //发送消息
   // actorRef.!("hi")

  }
}

 

Worker  向 Master发送注册信息,Master返回注册成功的信息

package Demo02

import akka.actor.{Actor, ActorSelection, ActorSystem, Props}
import com.typesafe.config.ConfigFactory

class Worker extends Actor {
  //worker建立与master的连接

  var masterRef: ActorSelection =_
  override def preStart(): Unit = {

    //Worker根master建立连接
    val masterRef = context.actorSelection("akka.tcp://MASTER_ACTOR_SYSTEM@localhost:8888/user/MASTER_ACTOR")
    //发送消息
    masterRef ! RegisterWorker("1001",1024,8)
  }
  override def receive: Receive ={
    case RegisterWorker=> {
      println("Register success")
    }
  }
}

//创建伴生对象
object Morker{
  def main(args: Array[String]): Unit = {
    //指定配置文件
    val confStr =
      s"""
         |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
         |akka.remote.netty.tcp.hostname = "localhost"
         |akka.remote.netty.tcp.port = 8889
         |""".stripMargin
    //解析配置文件
    val config = ConfigFactory.parseString(confStr)
    //创建ActorSystem
    val actorSystem= ActorSystem("MASTER_ACTOR_WORKER", config)
    //创建actor
    actorSystem.actorOf(Props[Worker])
  }

}

 

master部分


import akka.actor.{Actor, ActorSystem, Props}
import com.typesafe.config.ConfigFactory

import scala.collection.mutable

class Master extends Actor{
  //创建一个map 保存接收过来的内容
  val idToWorker = new mutable.HashMap[String, WorkerInfo]()
  //接收消息
  override def receive: Receive = {
    case RegisterWorker(id,memory,cores) =>{
      //println(s"worker:$id,memory;$memory,core:$cores")
      //将worker保存起来
      val workerInfo = new WorkerInfo(id, memory, cores)

      idToWorker(id) = workerInfo
    }
      sender() ! RegisterWorker

  }
}
//创建伴生对象
object Master {
  def main(args: Array[String]): Unit = {
    //指定配置文件
    val congStr =
      s"""
         |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
         |akka.remote.netty.tcp.hostname = "localhost"
         |akka.remote.netty.tcp.port = 8888
         |""".stripMargin
    //解析配置文件
    val config = ConfigFactory.parseString(congStr)
    //创建actorSystem
    val actorSystem = ActorSystem("MASTER_ACTOR_SYSTEM", config)
    //创建Actor
    actorSystem.actorOf(Props[Master],"MASTER_ACTOR")



  }
}

 

package Demo02

//注册信息用多例的进行发送,
case class RegisterWorker(WorkerId: String,memory: Int,core:Int)

//

 

package Demo02

class WorkerInfo(val id:String,var memory:Int,cores:Int)

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值