最近学习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. Use the SVN command-line tool

    欢迎关注我的社交账号: 博客园地址: http://www.cnblogs.com/jiangxinnju/p/4781259.html GitHub地址: https://github.com/ji ...

  2. Spring MVC 复习笔记03

    1. @RequestMapping 1). url映射 定义controller方法对应的url,进行处理器映射使用. 2). 窄化请求映射  3). 限制http请求方法 出于安全性考虑,对htt ...

  3. BigDecimal处理加减乘除

    public static void main(String[] args) { BigDecimal totalDoneAmt = new BigDecimal(2); Double d1 = ad ...

  4. 如何用纯 CSS 创作一个单元素抛盒子的 loader

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/qKwXbx 可交互视频 ...

  5. centos 最新版git 致命错误: zlib.h:没有那个文件或目录

    遇到此类问题通常是缺少对应的库文件. 由于yum install是老版本的git 还是1.8的 如果需要安装新版本的git,官方给出的url:https://git-scm.com/download/ ...

  6. ubuntu 12.04网络设置

    1.服务器版本 设置IP地址 ubuntu 12.04的网络设置文件是/etc/network/interfaces,打开文件,会看到 auto lo iface lo inet loopback 这 ...

  7. Tomcat热部署,Web工程中线程没有终止

    近期项目中,用 jenkins 热部署 web工程时,发现工程中静态持有的线程(将ScheduledExecutorService定时任务存储在静态Map中),导致不定时出现数据库访问事务关闭异常,如 ...

  8. (转)C#调用C函数(DLL)传递参数问题

    备忘: 1.C函数参数为字符串char*.如果是入参,对应C#中string或StringBuilder:如果是出参对应C#中StringBuider: 2.C函数参数为结构体指针,需在C#中对应定义 ...

  9. 快速升级openwrt的linux内核版本

    一.分析 要升级openwrt的linux内核版本,关键是要制作内核配置文件 二.内核配置文件制作方法 2.1当前openwrt对应的某个开发板有对应的内核配置文件,比如此时的openwrt的linu ...

  10. Linux 下部署Django项目

    Linux 下部署Django项目   说明:本文所使用的环境为CentOS 6+Python2.7+Django1.11 安装Django.Nginx和uWSGI 1.确定已经安装了2.7版本的Py ...