大数据学习——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的环境以及相关使用 ...
随机推荐
- 兼容IE9以下的获取兄弟节点
function fileCheck(ele){ function getNextElement(node){ //兼容IE9以下的 获取兄弟节点 var NextElementNode = node ...
- PADS 9.5封装向导 多一个管脚
使用PADS 9.5封装向导(Decal Wizard)建立封装(Decals) 时遇到封装的中间多了一个管脚,如图红圈位置,通过一番搜寻,才知道这是热焊盘,不需要就在右边的红圈处去掉勾选热焊盘即可.
- Nginx 基本配置介绍
一.什么是Nginx Nginx 是一个免费的,开源的,高性能的HTTP服务器和反向代理,以及IMAP / POP3代理服务器. Nginx 以其高性能,稳定性,丰富的功能,简单的配置和低资源消耗而闻 ...
- Sequence II
6990: Sequence II 时间限制: 3 Sec 内存限制: 128 MB提交: 206 解决: 23[提交][状态][讨论版][命题人:admin] 题目描述 We define an ...
- linux文本编辑器-VIM基本使用方法
vim [OPTION]... FILE... +/PATTERN:打开文件后,直接让光标处于第一个被PATTERN匹配到的行的行首vim + file 直接打开file,光标在最后一行 三种主要模式 ...
- python @staticmethod和@classmethod
Python其实有3个方法,即 静态方法 (staticmethod), 类方法 (classmethod)和 实例方法. 如下: def foo(x): print "executing ...
- 转 Keras 保存与加载网络模型
https://blog.csdn.net/qq_28413479/article/details/77367665
- 【线性基】bzoj2844: albus就是要第一个出场
线性基求可重rank 题目描述 给定 n 个数 $\{ a_i \}$ ,以及数 $x$. 将 $\{ a_i \}$ 的所有子集(包括空集)的异或值从小到大排序,得到 $\{ b_i \} $. ...
- matplotlib绘图(四)
控制文字属性的方法: 所有的方法都会返回一个matplotlib.text.Text对象 文本注释: annnotate() xy参数设置箭头指示的位置,xytext参数设置注释文字的位置 arro ...
- Struts2和SpringMVC简单配置以及区别总结
Struts2: struts 2 是一个基于MVC(mode-view-con)设计模式的Web应用框架,是由Struts1和WebWork两个经典框架发展而来的. 工作流程: 1客户端浏览器发出H ...