scala学习之实现RPC通信
最近学习scala,个人感觉非常灵活,实现rpc通信非常简单,函数式编程比较烧脑
1.搭建工程 创建scala maven 工程

项目pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xiaot</groupId>
<artifactId>scala-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<inceptionYear>2008</inceptionYear>
<properties>
<scala.version>2.10.6</scala.version>
</properties> <repositories>
<repository>
<id>scala-tools.org</id>
<name>Scala-Tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</repository>
</repositories> <pluginRepositories>
<pluginRepository>
<id>scala-tools.org</id>
<name>Scala-Tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</pluginRepository>
</pluginRepositories> <dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.specs</groupId>
<artifactId>specs</artifactId>
<version>1.2.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-actors</artifactId>
<version>2.10.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.typesafe.akka/akka-actor -->
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor_2.10</artifactId>
<version>2.3.14</version>
</dependency> <dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-remote_2.10</artifactId>
<version>2.3.14</version>
</dependency>
</dependencies> <build>
<sourceDirectory>src/main/scala</sourceDirectory>
<testSourceDirectory>src/test/scala</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<scalaVersion>${scala.version}</scalaVersion>
<args>
<arg>-target:jvm-1.5</arg>
</args>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
<downloadSources>true</downloadSources>
<buildcommands>
<buildcommand>ch.epfl.lamp.sdt.core.scalabuilder</buildcommand>
</buildcommands>
<additionalProjectnatures>
<projectnature>ch.epfl.lamp.sdt.core.scalanature</projectnature>
</additionalProjectnatures>
<classpathContainers>
<classpathContainer>org.eclipse.jdt.launching.JRE_CONTAINER</classpathContainer>
<classpathContainer>ch.epfl.lamp.sdt.launching.SCALA_CONTAINER</classpathContainer>
</classpathContainers>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<configuration>
<scalaVersion>${scala.version}</scalaVersion>
</configuration>
</plugin>
</plugins>
</reporting>
</project>
2. 创建Master.scala 作为主节点保持跟Worker进行通信 提供Worker注册信息存储和心跳检测
package com.xiaot.master
import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import com.typesafe.config.ConfigFactory
import com.xiaot.worker.WorkerInfo
import scala.concurrent.duration._
import scala.collection.mutable
/**
* Created by xiaot on 2018/4/2.
* scla 实现RPC
*/
class Master(val host:String,val port :Int) extends Actor{
//存储worker注册信息
val idToWork = new mutable.HashMap[String,WorkerInfo]()
//用于心跳检测动态删除添加worker节点信息
val workers = new mutable.HashSet[WorkerInfo]()
//超时时间
val CHECK_TIME_OUT = 15000
override def preStart(): Unit = {
println("master preStart ")
//定时检查worker是否存活 实时删除不存活的worker
import context.dispatcher
context.system.scheduler.schedule(0 millis,CHECK_TIME_OUT millis,self,CheckTimeOutWorker)
}
override def receive: Receive = {
case RegisterWorker(id,memory,cores) =>{
if (!idToWork.contains(id)){
val workerInfo = new WorkerInfo(id,memory,cores)
idToWork(id) = workerInfo
workers+=workerInfo
}
println("worker:"+id+" regist to master success")
sender ! RegisteredWorker(s"akka.tcp://MasterSystem@$host:$port/user/master")
}
case HeartBeat(id) =>{
if (idToWork.contains(id)){
//获取对应的worker
val workerInfo = idToWork(id)
val currentTime = System.currentTimeMillis()
//心跳检测更新时间
workerInfo.lastHeartbeatTime = currentTime
}
}
case CheckTimeOutWorker =>{
val currentTime = System.currentTimeMillis()
val preMovesWorkers = workers.filter(x => currentTime-x.lastHeartbeatTime>CHECK_TIME_OUT)
for (w<-preMovesWorkers){
idToWork -= w.id
workers -=w
}
println(workers.size)
}
}
}
object 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("MasterSystem",config)
// 创建actor
val master = actorSystem.actorOf(Props(new Master(host,port)),"master")
actorSystem.awaitTermination()
}
}
Master运行参数:

3.创建Worker.scala 作为工作节点 定期向master心跳检测和节点注册信息
package com.xiaot.worker
import java.util.UUID
import akka.actor.{Actor, ActorSelection, ActorSystem, Props}
import com.typesafe.config.ConfigFactory
import scala.concurrent.duration._
import com.xiaot.master.{HeartBeat, RegisterWorker, RegisteredWorker, SendHeartBeat}
/**
* Created by xiaot on 2018/4/3.
*/
class Worker(val masterHost:String,val port:Int,val memory:Int,val cores:Int) extends Actor{
var master :ActorSelection = _
val workerId = UUID.randomUUID().toString
val HEART_INTERAL=10000
override def preStart(): Unit = {
//与master创建连接
master = context.actorSelection(s"akka.tcp://MasterSystem@$masterHost:$port/user/master")
//向master注册
master ! RegisterWorker(workerId,memory,cores)
}
override def receive: Receive = {
case RegisteredWorker(masterUrl) =>{
println("worker:"+workerId+" 已经成功注册到"+masterUrl)
//心跳检测
import context.dispatcher
//自己调用自己通过case类进行实际心跳检测实现
context.system.scheduler.schedule(0 millis,HEART_INTERAL millis,self,SendHeartBeat)
}
case SendHeartBeat=>{
println("send heartbeat to master")
master ! HeartBeat(workerId)
}
}
}
object Worker{
def main(args: Array[String]): Unit = {
val host = args(0)
val port = args(1).toInt
val masterHost = args(2)
val masterPort = args(3).toInt
val memory = args(4).toInt
val cores = args(5).toInt
val configStr =
s"""
|akka.actor.provider = "akka.remote.RemoteActorRefProvider"
|akka.remote.netty.tcp.hostname = "$host"
|akka.remote.netty.tcp.port = "$port"
""".stripMargin
var config = ConfigFactory.parseString(configStr)
var worder = ActorSystem("WorderSystem",config)
worder.actorOf(Props(new Worker(masterHost,masterPort,memory,cores)))
worder.awaitTermination()
}
}
Worker运行参数:

WorkerInfo.scala 用于保存工作节点的信息
package com.xiaot.worker /**
* Created by xiaot on 2018/4/4.
*/
class WorkerInfo(val id:String,val memory:Int,val cores:Int){ var lastHeartbeatTime :Long = _
}
RemoteMessage.scala 用于远程信息发送,其中包括心跳检测等样例类
package com.xiaot.master /**
* Created by xiaot on 2018/4/4.
*/
trait RemoteMessage extends Serializable
//worker -->master
case class RegisterWorker(id:String,memory:Int,cores:Int) extends RemoteMessage
//master--->worker
case class RegisteredWorker(masterUrl:String) extends RemoteMessage
//worker---master
case class HeartBeat(id:String) extends RemoteMessage
//worker -->self
case object SendHeartBeat
//master -->self
case object CheckTimeOutWorker
4. 执行结果


scala学习之实现RPC通信的更多相关文章
- 大数据学习day17------第三阶段-----scala05------1.Akka RPC通信案例改造和部署在多台机器上 2. 柯里化方法 3. 隐式转换 4 scala的泛型
1.Akka RPC通信案例改造和部署在多台机器上 1.1 Akka RPC通信案例的改造(主要是把一些参数不写是) Master package com._51doit.akka.rpc impo ...
- RPC通信原理(未完,先睡觉)
一 背景 OpenStack 各组件之间是通过 REST 接口进行相互通信,比如Nova.Cinder.Neutron.Glance直间的通信都是通过keystone获取目标的endpoint,即ap ...
- 【Java】分布式RPC通信框架Apache Thrift 使用总结
简介 Apache Thrift是Facebook开源的跨语言的RPC通信框架,目前已经捐献给Apache基金会管理,由于其跨语言特性和出色的性能,在很多互联网公司得到应用,有能力的公司甚至会基于th ...
- SpringBoot2+Netty打造通俗简版RPC通信框架
2019-07-19:完成基本RPC通信! 2019-07-22:优化此框架,实现单一长连接! 2019-07-24:继续优化此框架:1.增加服务提供注解(带版本号),然后利用Spring框架的在启动 ...
- Spring Cloud 系列之 Dubbo RPC 通信
Dubbo 介绍 官网:http://dubbo.apache.org/zh-cn/ Github:https://github.com/apache/dubbo 2018 年 2 月 15 日,阿里 ...
- RPC通信框架——RCF介绍
现有的软件中用了大量的COM接口,导致无法跨平台,当然由于与Windows结合的太紧密,还有很多无法跨平台的地方.那么为了实现跨平台,支持Linux系统,以及后续的分布式,首要任务是去除COM接口. ...
- Scala学习资源
Scala学习资源: Scala官方网站:http://www.scala-lang.org/ Scala github:https://github.com/scala/scala Twitter ...
- 【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习
下了这本<大数据Spark企业级实战版>, 另外还有一本<Spark大数据处理:技术.应用与性能优化(全)> 先看前一篇. 根据书里的前言里面,对于阅读顺序的建议.先看最后的S ...
- RPC通信框架——RCF介绍(替换COM)
阅读目录 RPC通信框架 为什么选择RCF 简单的性能测试 参考资料 总结 现有的软件中用了大量的COM接口,导致无法跨平台,当然由于与Windows结合的太紧密,还有很多无法跨平台的地方.那么为了实 ...
随机推荐
- spark[源码]-TaskSchedulerlmpl类源码
TaskSchedulerImpl概述 TaskSchedulerlmpl是创建三大核心TaskSheduler的实现类,TaskScheduler是一个特征类,DAGScheduler在提交Task ...
- php中获得数组长度的方法
php中获得数组长度的方法 count统计数组里元素的个数: strlen是统计数组中元素的长度: 你如果想统计数组中所有元素的长度,那就用循环统计吧tqeb 代码: $a = array( ...
- JavaScript 引用【转】
从一个例子说起: var m ={a:’a’, b:’b’}; var n=m; n.c=’c’; 那么在这个时候 , m.c 也会变成 ’c’! 这个问题在我最开始学习 JS 语言时个人一直处于概念 ...
- RabbitMQ脑裂
在RabbitMQ3.4.x中会出现脑裂的现象,本文通过实验验证此脑裂现象,愿小伙伴们少走弯路. Preview 网上有两篇帖子(需要FQ) https://groups.google.com/for ...
- elasticsearch系列(七)java定义score
概述 ES支持groovy 和 java两种语言自定义score的计算方法,groovy甚至可以嵌套在请求的参数中,有点厉害,不过不在本篇讨论范围. 如何用自定义的java代码来定义score如何产生 ...
- XML CDATA是什么?
XML CDATA是什么? 投稿:mdxy-dxy 字体:[增加 减小] 类型:转载 这篇文章主要为大家介绍下XML CDATA是什么,学习xml的朋友可以参考下 All text in ...
- jvm垃圾回收策略
一.jvm堆内存的分代划分 在基于分代的内存回收策略中,堆空间通常都被划分为3个代,年轻代,年老代(或者tenured代),永久代.在年轻代中又被划分了三个小的区域,分别为:Eden(伊甸)区,S0区 ...
- ADO.NET 使用DELETE语句批量删除操作,提示超时,删除失败,几种优化解决思路
起因是如此简单的一句sql 提示:Timeout 时间已到.在操作完成之前超时时间已过或服务器未响应. 提供几种解决思路: 1.检查WHERE条件中字段是否已建索引 2.检查是否被其他表引用,引用表外 ...
- Dive into Spring framework -- 搭建spring 源码的开发环境
spring是一个类之间依赖的管理容器,大家都知道,但我们中很多人都仅仅停留在使用的层面,但spring本身具有极大的研究价值,所以在使用了几年spring之后,还是想深入的探究一下其根源.记录于此, ...
- awardRotate.js
(function($) { var supportedCSS,styles=document.getElementsByTagName("head")[0].style,toCh ...