大数据学习——akka自定义RPC

实现

package cn.itcast.akka
import akka.actor.{Actor, ActorSystem, Props}
import akka.actor.Actor.Receive
import com.typesafe.config.ConfigFactory
import scala.collection.mutable
import scala.concurrent.duration._
class Master(val host: String, val port: Int) extends Actor {
//保存WorkerID 到 WorkerInfo的映射
val idToWorker = new mutable.HashMap[String, WorkerInfo]()
//保存所的WorkerInfo信息
val workers = new mutable.HashSet[WorkerInfo]()
val CHECK_INTERVAL = 15000
override def preStart(): Unit = {
//导入隐式转换
import context.dispatcher
context.system.scheduler.schedule(0 millis, CHECK_INTERVAL millis, self, CheckTimeOutWorker)
}
override def receive: Receive = {
//Worker发送个Mater的注册消息
case RegisterWorker(workerId, cores, memory) => {
if (!idToWorker.contains(workerId)) {
//封装worker发送的信息
val workerInfo = new WorkerInfo(workerId, cores, memory)
//保存workerInfo
idToWorker(workerId) = workerInfo
workers += workerInfo
//Master向Worker反馈注册成功的消息
sender ! RegisteredWorker(s"akka.tcp://${Master.MASTER_SYSTEM}@$host:$port/user/${Master.MASTER_NAME}")
}
}
//Worker发送给Master的心跳信息
case Heartbeat(workerId) => {
if (idToWorker.contains(workerId)) {
val workerInfo = idToWorker(workerId)
val currentTime = System.currentTimeMillis()
//更新上一次心跳时间
workerInfo.lastHeartbeatTime = currentTime
}
}
//检测超时的Worker
case CheckTimeOutWorker => {
val currentTime = System.currentTimeMillis()
val deadWorkers: mutable.HashSet[WorkerInfo] = workers.filter(w => currentTime - w.lastHeartbeatTime > CHECK_INTERVAL)
// for(w <- deadWorkers) {
// idToWorker -= w.id
// workers -= w
// }
deadWorkers.foreach(w => {
idToWorker -= w.id
workers -= w
})
println("alive worker size : " + workers.size)
}
}
}
object Master {
val MASTER_SYSTEM = "MaterActorSystem"
val MASTER_NAME = "Master"
def main(args: Array[String]) {
// val host = args(0)
// val port = args(1).toInt
val host = "127.0.0.1"
val port = 8888
val confStr =
s"""
|akka.actor.provider = "akka.remote.RemoteActorRefProvider"
|akka.remote.netty.tcp.hostname = "$host"
|akka.remote.netty.tcp.port = "$port"
""".stripMargin
val conf = ConfigFactory.parseString(confStr)
//ActorSystem是单例的,用于创建Acotor并监控actor
val actorSystem = ActorSystem(MASTER_SYSTEM, conf)
//通过ActorSystem创建Actor
actorSystem.actorOf(Props(new Master(host, port)), MASTER_NAME)
actorSystem.awaitTermination()
}
}
package cn.itcast.akka trait Message extends Serializable //Worker -> Master
case class RegisterWorker(id: String, cores: Int, memory: Int) extends Message //Master -> Worker
case class RegisteredWorker(masterUrl: String) extends Message //Worker -> Master
case class Heartbeat(id: String) extends Message //Worker internal message
case object SendHeartbeat //Master internal message
case object CheckTimeOutWorker
package cn.itcast.akka import java.util.UUID
import akka.actor.{Actor, ActorSelection, ActorSystem, Props}
import com.typesafe.config.ConfigFactory import scala.concurrent.duration._ class Worker(val cores: Int, val memory: Int, val masterHost: String, val masterPort: Int) extends Actor { //Master的引用
var master: ActorSelection = _
//Worker的ID
val workerId = UUID.randomUUID().toString
//masterUrl
var masterUrl: String = _ val HEARTBEAT_INTERVAL = 10000 //preStart在构造器之后receive之前执行
override def preStart(): Unit = {
//首先跟Master建立连接
master = context.actorSelection(s"akka.tcp://${Master.MASTER_SYSTEM}@$masterHost:$masterPort/user/${Master.MASTER_NAME}")
//通过master的引用向Master发送注册消息
master ! RegisterWorker(workerId, cores, memory)
} override def receive: Receive = {
//Master发送给Worker注册成功的消息
case RegisteredWorker(masterUrl) => {
this.masterUrl = masterUrl
//启动定时任务,向Master发送心跳
//导入隐式转换
import context.dispatcher
context.system.scheduler.schedule(0 millis, HEARTBEAT_INTERVAL millis, self, SendHeartbeat)
} case SendHeartbeat => {
//向Master发送心跳
master ! Heartbeat(workerId)
}
}
} object Worker {
def main(args: Array[String]) { //Worker的地址和端口
// val host = args(0)
// val port = args(1).toInt
// val cores = args(2).toInt
// val memory = args(3).toInt
val host = "127.0.0.1"
val port = 9999
val cores = 8
val memory = 1024 //Master的地址和端口
// val masterHost = args(4)
// val masterPort = args(5).toInt
val masterHost = "127.0.0.1"
val masterPort = 8888 val confStr =
s"""
|akka.actor.provider = "akka.remote.RemoteActorRefProvider"
|akka.remote.netty.tcp.hostname = "$host"
|akka.remote.netty.tcp.port = "$port"
""".stripMargin
val conf = ConfigFactory.parseString(confStr)
//单例的ActorSystem
val actorSystem = ActorSystem("WorkerActorSystem", conf)
//通过actorSystem来创建Actor
val worker = actorSystem.actorOf(Props(new Worker(cores, memory, masterHost, masterPort)), "Worker")
actorSystem.awaitTermination()
}
}
package cn.itcast.akka
class WorkerInfo(val id: String, val cores: Int, val memory: Int) {
//TODO
var lastHeartbeatTime: Long = _
}


大数据学习——akka自定义RPC的更多相关文章
- 大数据学习——akka学习
架构图 重要类介绍 ActorSystem 在Akka中,ActorSystem是一个重量级的结构,他需要分配多个线程,所以在实际应用中,ActorSystem通常是一个单例对象,我们可以使用这个Ac ...
- 大数据学习——hadoop的RPC框架
项目结构 服务端代码 test-hadoop-rpc pom.xml <?xml version="1.0" encoding="UTF-8"?> ...
- 大数据学习day29-----spark09-------1. 练习: 统计店铺按月份的销售额和累计到该月的总销售额(SQL, DSL,RDD) 2. 分组topN的实现(row_number(), rank(), dense_rank()方法的区别)3. spark自定义函数-UDF
1. 练习 数据: (1)需求1:统计有过连续3天以上销售的店铺有哪些,并且计算出连续三天以上的销售额 第一步:将每天的金额求和(同一天可能会有多个订单) SELECT sid,dt,SUM(mone ...
- 大数据学习:storm流式计算
Storm是一个分布式的.高容错的实时计算系统.Storm适用的场景: 1.Storm可以用来用来处理源源不断的消息,并将处理之后的结果保存到持久化介质中. 2.由于Storm的处理组件都是分布式的, ...
- 大数据学习笔记——Hadoop编程实战之HDFS
HDFS基本API的应用(包含IDEA的基本设置) 在上一篇博客中,本人详细地整理了如何从0搭建一个HA模式下的分布式Hadoop平台,那么,在上一篇的基础上,我们终于可以进行编程实操了,同样,在编程 ...
- 大数据学习笔记——Linux完整部署篇(实操部分)
Linux环境搭建完整操作流程(包含mysql的安装步骤) 从现在开始,就正式进入到大数据学习的前置工作了,即Linux的学习以及安装,作为运行大数据框架的基础环境,Linux操作系统的重要性自然不言 ...
- 大数据学习笔记——Java篇之集合框架(ArrayList)
Java集合框架学习笔记 1. Java集合框架中各接口或子类的继承以及实现关系图: 2. 数组和集合类的区别整理: 数组: 1. 长度是固定的 2. 既可以存放基本数据类型又可以存放引用数据类型 3 ...
- 大数据学习路线,来qun里分享干货,
一.Linux lucene: 全文检索引擎的架构 solr: 基于lucene的全文搜索服务器,实现了可配置.可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面. 推荐一个大数据学习群 ...
- 大数据学习系列之四 ----- Hadoop+Hive环境搭建图文详解(单机)
引言 在大数据学习系列之一 ----- Hadoop环境搭建(单机) 成功的搭建了Hadoop的环境,在大数据学习系列之二 ----- HBase环境搭建(单机)成功搭建了HBase的环境以及相关使用 ...
随机推荐
- 一条shell统计代码行数
Xcode统计代码,用shell命令即可,非常简单.打开终端,进入你的工程目录,执行下列代码 find . -name "*.m" -or -name "*.h" ...
- JavaScript中var a=b=c=d的发现
看了别人的博客随手记录下 先看一下以下的代码 var a=1,b=2,c=3; (function(){ var a=b=1; })(); console.log(a); console.log(b) ...
- OPEN SQL
OPEN SQL 1.SELECT .INSERT.UPDATE.DELETE.MODIFYSELECT 命令包含如下从句:SELECT: 需要查询资料库指定表的那些列,是一行还是多行INTO: 查询 ...
- 关于IT公司招聘的一个思考
作者:朱金灿 来源:http://blog.csdn.net/clever101 21世纪什么最贵?人才!相信这是很多IT公司管理者的深刻感悟.对于IT公司而言,找到合适的人才往往不能单靠人事部门,一 ...
- CSS 利用border三角形绘制方法
CSS 三角形绘制方法,这里面的transparent比较重要,有和没有影响很大: 原理:这个div是由4个三角形组成,每个三角对应一个border,隐藏其它3个border,就可以得到一个三角形. ...
- 创建XML的用法
注意:在实际开发中,注意createElement().createAttribute().createTextNode().appendchild()等方法的具体使用. // root根节点的属性数 ...
- HDU 3709 Balanced Number (数位DP)
题意: 找出区间内平衡数的个数,所谓的平衡数,就是以这个数字的某一位为支点,另外两边的数字大小乘以力矩之和相等,即为平衡数. 思路: 一开始以为需要枚举位数,枚举前缀和,枚举后缀和,一旦枚举起来就会M ...
- [中文翻译] ASP.NET 5 简介(Introducing ASP.NET 5,原作ScottGu 2015/2/23)
本文出处 [中文翻译] ASP.NET 5 简介(Introducing ASP.NET 5,原作ScottGu 2015/2/23) 这是我的文章备份 http://www.dotblogs.co ...
- Acronis.Disk.Director磁盘分区管理
Acronis.Disk.Director分为for 专业版和服务器版的,我在生产环境中调整Windows2003跳板机使用的是Acronis.Disk.Director Server 10.0.20 ...
- Python 继承、派生、组合、接口、抽象类
继承是一种是的关系,和组合对比,组合是一种有的关系,这两者都是解决代用重用问题的 继承 注意:继承不是遗传,在显示角度中,是通过对象抽象成类,再把这些类抽象成一个,就是父类.是自下而上的过程,在程序中 ...