1.RPC: The simple point is that the communication between multithreading, we use Scala and Akka today
To make it simple.
Some simple contents of the RPC framework, a face including, heartbeat, Interval time,
Registration and some questions,
Pattern matching some things, although relatively simple, but belong to the small, perfectly formed
There are a total of four files in this:
Master.scala
Remotemessage.scala
Worker.scala
Workerinfo
Master.scala
Package Cn.wj.rpcimport Akka.actor. {Actor, Actorsystem}import akka.actor.Actor.Receiveimport com.typesafe.config.ConfigFactoryimport Akka.actor.Propsimport scala.concurrent.duration._import scala.collection.mutable/** * Created by WJ on 2016/12/23. */class Master (Val host:string,val port:int) extends Actor {//Workerid-workerinfo val idtoworker = new mutable. Hashmap[string,workerinfo] () Val workers = new mutable. Hashset[workerinfo] ()//interval time, timeout detection interval val check_interval = 15000//For receiving message override Def receive:receive = {case R Egisterworker (Id,memory,cores) = {//println ("a client Connected")//Sender! "Reply"//Send the message to the person to reply to a message//to determine whether it has been registered if (! Idtoworker.contains (ID)) {//The worker information is encapsulated previously, saved in memory val workerinfo = new Workerinfo (id,memory,cores) Idtowo Rker (id) = workerinfo//This should be a specific version of Scala workers + = Workerinfo Sender! Registeredworker (S "akka.tcp://[email protected] $host: $port/user/master")}} case HEartbeat (ID) =>{if (Idtoworker.contains (id)) {val Workerinfo = idtoworker (ID)//Live report//Get system Current time Between Val currenttime = System.currenttimemillis () Workerinfo.lastheartbeattime = currenttime}} CAs E Checktimeoutworker = {val currenttime = System.currenttimemillis () val toremove = workers.filter (x = Currenttime-x.lastheartbeattime > Check_interval) for (w <-toremove) {Workers-= W Idtoworker- = W.id} println (Workers.size)}} override Def Prestart (): Unit = {println ("Prestart invoked")// Import implicit conversion features import Context.dispatcher context.system.scheduler.schedule (0 millis,check_interval Millis,self,checktim Eoutworker)}}object master{def main (args:array[string]): Unit = {val host = args (0) Val port = args (1). ToInt Prepare to configure Val Configstr = S "" "|akka.actor.provider =" Akka.remote.RemoteActorRefProvider "|AKKA.R Emote.netty.tcp.hostname = "$host" |akka.remote.netty.tcp.port = "$port" "" ". Stripmargin val config = configfactory.parsestring (c ONFIGSTR)//actorsystem, assistant to create and monitor the following actor, he is a singleton val actorsystem = Actorsystem ("mastersystem", config)//create actor Val master = actorsystem.actorof (Props (new Master (Host,port)), "Master") Actorsystem.awaittermination ()}}
Worker.scala
Package Cn.wj.rpcimport Java.util.UUIDimport Akka.actor. {Actor, actorselection, Actorsystem, Props}import com.typesafe.config.ConfigFactoryimport scala.concurrent.duration . _/** * Created by WJ on 2016/12/23. */class Worker (Val masterhost:string,val masterport:int,val memory:int,val cores:int) extends Actor {var master:actors Election = _ val Workerid = Uuid.randomuuid (). toString val Heart_interval = 10000//prestart The time to execute the method: After the constructor, receive before// Connect with Master (Actor) override Def Prestart (): Unit = {//master is already a reference to another master, this is a connection to master = context.actors Election (S "akka.tcp://[email protected] $masterHost: $masterPort/user/master")//Send registration message to Master Master! Registerworker (Workerid,memory,cores)} override def receive:receive = {case Registeredworker (masterurl) = = { println (MasterUrl)//Start timer sends heartbeat import Context.dispatcher context.system.scheduler.schedule (0 millis,hear T_interval millis,self,sendheartbeat)} case sendheartbeat =&Gt {println ("Send Heartbeat to Master") master! Heartbeat (Workerid)}}}object worker{def main (args:array[string]): Unit = {val host = args (0) val port = ar GS (1). toint val masterhost = args (2) Val masterport = args (3). toint val memory = args (4). ToInt val cores = arg S (5). ToInt//Ready to configure 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)//actorsystem, assistant to create and monitor the following actor, he is a singleton val actorsystem = Actorsystem ("Workersys Tem ", config)//create actor, call the Prestart of the actor and the Receive method Actorsystem.actorof (Props (The new Worker (Masterhost,masterpor t,memory,cores)), "Worker") Actorsystem.awaittermination ()}}
Remotemessage.scala
Package cn.wj.rpc/** * Created by WJ on 2016/12/25. */trait Remotemessage extends Serializable//worker->master (this indicates that when Master accepts this Worker, the message is receive) Case class Registerworker (id:string, Memory:int, cores:int) extends Remotemessage//master Worker (this is the registration information that Master received from Workerd, Indicates that this message has been registered, sender! XXX time) Case class Registeredworker (masterurl:string) extends remotemessage//This is the process of sending itself messages to itself, so use case object, And do not need to implement Serializable//worker-a Worker case Object sendheartbeat//This is the work to send a timer to master, where the ID is the work ID, Because to explain to Master, which work to send him heartbeat//worker-Mastercase class Heartbeat (id:string) extends Remotemessage//master- > Selfcase Object Checktimeoutworker
Workerinfo.scala
Package cn.wj.rpc/** * Created by WJ on 2016/12/25. */class Workerinfo (Val id:string, Val memory:int,val cores:int) { //todo last heartbeat var lastheartbeattime:long = _}
The above four is a simple implementation of the RPC framework, in fact, a master monitoring multiple workers,
When a worker is created, he is required to register the information in master, in fact this master personally feels like
is a zookeeper, in charge of the worker's information, assigns some resources to its worker, when master receives the worker
Registration information, he adds the worker to his own registry and then sends a registration to the worker
Successful information, at this time the worker receives this registration information, and then he sends the heartbeat to master, this
The role is to tell Master that my worker is alive (reported live) when a Worke sends heartbeat interval
Too long, longer than we set the time, then we need to actively kill this worker, feel that some of the Hadoop
Distribution is similar to this principle.
Here is a schematic picture:
The receive is used to receive information because the actor is inherited,
Prestart This method is performed after the actual class instance, after the Receive method
Initially AKKA-02:RPC frame