最近学习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通信的更多相关文章

  1. 大数据学习day17------第三阶段-----scala05------1.Akka RPC通信案例改造和部署在多台机器上 2. 柯里化方法 3. 隐式转换 4 scala的泛型

    1.Akka RPC通信案例改造和部署在多台机器上  1.1 Akka RPC通信案例的改造(主要是把一些参数不写是) Master package com._51doit.akka.rpc impo ...

  2. RPC通信原理(未完,先睡觉)

    一 背景 OpenStack 各组件之间是通过 REST 接口进行相互通信,比如Nova.Cinder.Neutron.Glance直间的通信都是通过keystone获取目标的endpoint,即ap ...

  3. 【Java】分布式RPC通信框架Apache Thrift 使用总结

    简介 Apache Thrift是Facebook开源的跨语言的RPC通信框架,目前已经捐献给Apache基金会管理,由于其跨语言特性和出色的性能,在很多互联网公司得到应用,有能力的公司甚至会基于th ...

  4. SpringBoot2+Netty打造通俗简版RPC通信框架

    2019-07-19:完成基本RPC通信! 2019-07-22:优化此框架,实现单一长连接! 2019-07-24:继续优化此框架:1.增加服务提供注解(带版本号),然后利用Spring框架的在启动 ...

  5. Spring Cloud 系列之 Dubbo RPC 通信

    Dubbo 介绍 官网:http://dubbo.apache.org/zh-cn/ Github:https://github.com/apache/dubbo 2018 年 2 月 15 日,阿里 ...

  6. RPC通信框架——RCF介绍

    现有的软件中用了大量的COM接口,导致无法跨平台,当然由于与Windows结合的太紧密,还有很多无法跨平台的地方.那么为了实现跨平台,支持Linux系统,以及后续的分布式,首要任务是去除COM接口. ...

  7. Scala学习资源

    Scala学习资源: Scala官方网站:http://www.scala-lang.org/ Scala github:https://github.com/scala/scala Twitter ...

  8. 【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

    下了这本<大数据Spark企业级实战版>, 另外还有一本<Spark大数据处理:技术.应用与性能优化(全)> 先看前一篇. 根据书里的前言里面,对于阅读顺序的建议.先看最后的S ...

  9. RPC通信框架——RCF介绍(替换COM)

    阅读目录 RPC通信框架 为什么选择RCF 简单的性能测试 参考资料 总结 现有的软件中用了大量的COM接口,导致无法跨平台,当然由于与Windows结合的太紧密,还有很多无法跨平台的地方.那么为了实 ...

随机推荐

  1. H5 动画:轨迹移动 | H5游戏 推金币

    https://aotu.io/notes/2017/11/06/path-animation/ https://aotu.io/notes/2017/11/06/coindozer/

  2. C语言基础温故

    一.C语言中数组动态增长有哪些方法? 1.在原数组单元后面是没法再扩长的,因为后面的单元没法保证一定有.所以,数组原址动态增长肯定是不行的: 2.要么定义长一点的数组,要么自已把N个数组用链表串起来, ...

  3. linux性能分析命令1:top命令

    转载:http://www.cnblogs.com/peida/archive/2012/12/24/2831353.html top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的 ...

  4. wamp5.5.12安装re dis扩展

    转载地址:http://hanqunfeng.iteye.com/blog/1984387 phpredis是个人觉得最好的一个php-redis客户端,因为其提供的function与redis的命令 ...

  5. jenkins邮箱配置以及结合ansible进行批量构建

    tomcat8.5以上版本,jenkins2.7以上版本 首先填写你的系统管理员邮件地址,否则会使用jenkins系统本身的邮箱 填写的163邮箱,通过smtp认证填写正确的账号和密码(注意这里的密码 ...

  6. awk循环语句-【AWK学习之旅】

      AWK中两种循环语句:if-else 和 while   控制流语句: 1.if-else 求总数,平均值: [root@monitor awkdir]# awk '$3>6 {n = n ...

  7. wget指定目录下载以及其它的使用方式

    转自 http://java-er.com/blog/wget-useage-x/ 有时候我们需要wget一个文件下载到指定的目录下,或者重命名成指定的名字 wget -r -p -np -k -P ...

  8. java程序结构

    if....else.... 1.  if都需要接判断表达式 2.  else不需要表达式 3. 有if没else可以,但else必须要有一个if,if数>=else数 if (A条件)     ...

  9. 解题报告:hdu1248寒冰王座 - 完全背包模板

    2017-09-03 16:16:38 writer:pprp 完全背包问题:从左向右进行扫描,用一维阵列进行分析 代码如下: /* @theme:hdu1248 寒冰王座 @writer:pprp ...

  10. mysql_fetch_assoc查询多行数据

    每次从查询结果中返回一行数据,作为关联数组,类似于一个游标,第一次是返回第一行,第二次迭代就是第二行,以此类推 如果返回多行,使用如下方法就可以了 while($row = $db->fetch ...