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结合的太紧密,还有很多无法跨平台的地方.那么为了实 ...
随机推荐
- H5 动画:轨迹移动 | H5游戏 推金币
https://aotu.io/notes/2017/11/06/path-animation/ https://aotu.io/notes/2017/11/06/coindozer/
- C语言基础温故
一.C语言中数组动态增长有哪些方法? 1.在原数组单元后面是没法再扩长的,因为后面的单元没法保证一定有.所以,数组原址动态增长肯定是不行的: 2.要么定义长一点的数组,要么自已把N个数组用链表串起来, ...
- linux性能分析命令1:top命令
转载:http://www.cnblogs.com/peida/archive/2012/12/24/2831353.html top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的 ...
- wamp5.5.12安装re dis扩展
转载地址:http://hanqunfeng.iteye.com/blog/1984387 phpredis是个人觉得最好的一个php-redis客户端,因为其提供的function与redis的命令 ...
- jenkins邮箱配置以及结合ansible进行批量构建
tomcat8.5以上版本,jenkins2.7以上版本 首先填写你的系统管理员邮件地址,否则会使用jenkins系统本身的邮箱 填写的163邮箱,通过smtp认证填写正确的账号和密码(注意这里的密码 ...
- awk循环语句-【AWK学习之旅】
AWK中两种循环语句:if-else 和 while 控制流语句: 1.if-else 求总数,平均值: [root@monitor awkdir]# awk '$3>6 {n = n ...
- wget指定目录下载以及其它的使用方式
转自 http://java-er.com/blog/wget-useage-x/ 有时候我们需要wget一个文件下载到指定的目录下,或者重命名成指定的名字 wget -r -p -np -k -P ...
- java程序结构
if....else.... 1. if都需要接判断表达式 2. else不需要表达式 3. 有if没else可以,但else必须要有一个if,if数>=else数 if (A条件) ...
- 解题报告:hdu1248寒冰王座 - 完全背包模板
2017-09-03 16:16:38 writer:pprp 完全背包问题:从左向右进行扫描,用一维阵列进行分析 代码如下: /* @theme:hdu1248 寒冰王座 @writer:pprp ...
- mysql_fetch_assoc查询多行数据
每次从查询结果中返回一行数据,作为关联数组,类似于一个游标,第一次是返回第一行,第二次迭代就是第二行,以此类推 如果返回多行,使用如下方法就可以了 while($row = $db->fetch ...