整体思路
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)