Master-Slave通用基础框架
一、设计目的
设计出一个通用的Master-Slave基础框架,然后可以基于这个框架来实现特定的业务需求,比如实现多节点并行计算、分布式处理等。
二、设计理念
基于经典的命令模式,Master和Slave之间通过相互发送命令(Command)实现交互,命令是一个抽象的概念,Command可以用来分发任务,也可以用来传输数据, 这完全由业务来决定怎么处理, 框架只定义了一个实际的命令-心跳检测命令(Heartbeat Command)。可以通过定义自己的命令,并提供响应的命令处理器,来实现任何形式的业务。框架提供的核心功能其实只有,底层的网络通信,Master/Slave关系的维系,命令的分发功能。
三、详细设计
系统类图

核心接口和类:
|
名称 |
类型 |
方法 |
说明 |
|
|
Node |
interface 扩展 Runnable接口 |
void init() |
节点初始化 |
接口Node: 代表分布式节点,Master或Slave节点,分布式节点,Master节MasterNodel和Slave节SlaveNode实现本接口 |
|
void start() |
节点启动 |
|||
|
void stop() |
节点停止 |
|||
|
void reset() |
节点重启 |
|||
|
名称 |
类型 |
方法 |
说明 |
|
MasterNode |
class |
实现Node接口 |
Master节点,负责管理Slave节点,分发命令给Slave |
|
名称 |
类型 |
方法 |
说明 |
|
SlaveNode |
class |
实现Node接口 |
Slave节点,负责接收Master节点分发的命令,并执行命令,将结果封装成命令发送到Master节点 |
|
名称 |
类型 |
方法 |
说明 |
|
SlaveNode |
class |
实现Node接口 |
Slave节点,负责接收Master节点分发的命令,并执行命令,将结果封装成命令发送到Master节点 |
|
名称 |
类型 |
方法 |
说明 |
|
| CommandProvider |
interface |
Command produce() |
产生Command |
Command提供者接口,业务代码提供实现该接口的Provider,因为采用Slave主动拉取Command的机制,CommandProvider为SlaveNode用来生产Command。 后面考虑支持Master主动推送Command到Slave. |
|
List produce(long count) |
批量产生Commnad |
|||
|
名称 |
类型 |
方法 |
说明 |
|
| NetWorkClient |
interface |
void init() |
初始化 |
Slave端负责底层网络通信的,网络服务客户端,负责和Master节点通信。采用nio实现。 |
|
void start() |
启动 |
|||
|
void stop() |
停止 |
|||
|
void reset() |
重启 |
|||
|
名称 |
类型 |
方法 |
说明 |
|
| Session |
class |
void init() |
初始化会话 |
Master和Slave之间的会话,Master通过Session来跟中,管理Slave。Session通过一个线程来接收Command,执行Command,发送Command。SessionManager负责管理, 分配,回收这个Session. SessionManager会定时转换Session的状态,如果Session的状态转换到MS_SESSION_STATE_DEAD 状态,就会在在下次被回收.但是如果Master接收到Slave的心跳命令,就会将Session的状态置为MS_SESSION_STATE_ALIVE ,以表示Slave还存活. |
|
void start() |
启动会话 |
|||
|
void destroy() |
销毁会话 |
|||
|
void alive() |
当Master接收到Slave的心跳Command时,会将调用本函数,将当前的Session置为“存活”状态 |
|||
|
void free() |
释放会话,已被以后重新利用,并不是销毁,防止频繁创建,销毁会话(线程) |
|||
|
void isDead |
会话是否已经“死掉”,这意味着Master长时间没有收到对应的Slave的心跳Command,Master会认为这个Slave已经“死掉”。 |
|||
|
void onRead() |
NetWorkServer会在会话的Socket有数据可读时,会调用Session的这个函数,让Session接收Slave发送的数据包 |
|||
|
void onWrite() |
NetWorkServer会在会话的Socket可写时,调用Session的这个函数,Session可以将自己的数据输出缓存队列的数据通过网络发送到Slave。 |
|||
|
void run |
Runnable接口的函数,循环从自己的输入缓存队列中解析出Command并通过CommandDispatcher分发Command并将结果Command写到自己的输出缓冲队列. |
|||
|
void transitState() |
根据Session当前的状态转换到下一个状态,SessionManager会有一个定时任务,负责调用本函数,来转换Session的状态. |
|||
|
名称 |
类型 |
方法 |
说明 |
|
| SessionManager |
interface |
void init() |
初始化 |
Master端负责底层网络通信的,网络服务器,负责和Slave节点通信。采用nio实现一个线程处理所有的网络操作。 |
|
void freeSession(Session session) |
释放Session,实际上是被回收,以备再分配 |
|||
|
SessionnewSession(java.nio.channels.SocketChannel channel) |
分配Session |
|||
|
void destroy() |
SessionManager的销毁,会销毁所有的Session | |||
|
名称 |
类型 |
方法 |
说明 |
|
| Command |
class |
ByteBuffer getPayLoad() |
获得Comamnd的负载,业务相关的数据 |
Master和Slave之间交换的命令,业务可以定义的自己的Command并提供对应的Command处理器,Command可以用来分发任务,也可以用来传输数据,这完全由业务来决定怎么处理 |
|
void setPayLoad(ByteBuffer payLoad) |
设置Comamnd的负载,业务相关的数据 |
|||
|
Long getType() |
获得Command的类型,业务可以定义自己的Command类型,并负责处理 |
|||
|
void setType(Long type) |
设置Command的类型,业务可以定义自己的Command类型,并负责处理 |
|||
|
Session getSession() |
Master端,获得Command对应的Session |
|||
|
void setSession(Session session) |
Master端,设置Command对应的Session |
|||
|
名称 |
类型 |
方法 |
说明 |
|
| CommandHandler |
interface |
Command handle(Command command) |
处理命令,并返回以Command封装的结果 |
负责处理Command的接口, 业务定义新的Command需要提供实现该接口的Command处理器 |
|
名称 |
类型 |
方法 |
说明 |
|
| CommandDispatcher |
interface |
void int() |
初始化 |
Master和Slave负责分发Command的接口,通过业务配置的命令路由表,分发Command到具体的Command处理器 |
|
Command dispatch(Command command) |
通过业务配置的命令路由表,分发Command到具体的Command处理器 |
|||
时序图
Master工作时序图

Slave工作时序图

状态迁移图

Session一共有5种状态,设计这么多的中间等待状态,或许没有这必要。
Session分配时默认状态为alive,存活状态,然后SessionManager的定任务会定时将Session的状态沿着alive->waiting_0->waiting_1->waiting_2->dead路线迁移,但是同时Master在收到Slave的心跳Command时会将Session的状态置为alive.SessionManager的定任务会在Session的状态被置为dead后,下一次定时任务执行是回收该Session,即认为相应的Slave已经“死掉”。
四、实现
请参考代码
五、代码
请见附件
http://files.cnblogs.com/files/HANYI7399/ms.zip
六、总结
目前只实现了基础的功能,还有很有一些值得去思考与实现的,如:
Slave的管理,包括Slave的存活,负载,等管理。
到底是Master主动将Command推送到Slave, 还是Slave主动拉,这也是值得考虑的,不过这个实现起来还是比较简单的,目前采用Slave主动拉的机制,主要考虑到这样实现更简单也更健壮。
Command分配策略的考虑,是将一个Command分配给一个Slave呢,还是一个Command可以分配个多个Slave呢,这个可以考虑用策略模式来处理。
CommandHandler支持异步,这个通过回调可以很好的处理。
Master单点故障的问题,怎么考虑,怎么处理z
Master-Slave通用基础框架的更多相关文章
- MUI项目基础框架
码云SVN仓库地址:https://gitee.com/lim2018/vx/tree/master MUI项目基础框架,底部导航栏切换 目录结构 index为入口页主体,sub1-4为要切换的子页面 ...
- LayIM.AspNetCore Middleware 开发日记(三)基础框架搭建
前言 在上一篇中简单讲了一些基础知识,例如Asp.Net Core Middleware 的使用,DI的简单使用以及嵌入式资源的使用方法等.本篇就是结合基础知识来构建一个基础框架出来. 那么框架有什么 ...
- 一个简单的、面向对象的javascript基础框架
如果以后公司再能让我独立做一套新的完整系统,那么我肯定会为这个系统再写一个前端框架,那么我到底该如何写这个框架呢? 在我以前的博客里我给大家展示了一个我自己写的框架,由于当时时间很紧张,做之前几乎没有 ...
- 60.Android通用流行框架大全
转载:https://segmentfault.com/a/1190000005073746 Android通用流行框架大全 1. 缓存 名称 描述 DiskLruCache Java实现基于LRU的 ...
- 准备.Net转前端开发-WPF界面框架那些事,搭建基础框架
题外话 最近都没怎么写博客,主要是最近在看WPF方面的书<wpf-4-unleashed.pdf>,挑了比较重要的几个章节学习了下WPF基础技术.另外,也把这本书推荐给目前正在从事WPF开 ...
- JeeSite 企业信息管理系统基础框架
1. JeeSite概述 1.1. 简介 JeeSite是一个开源的企业信息管理系统基础框架.主要定位于“企业信息管理”领域,可用作企业信息管理类系统.网站后台管理类系统等.JeeSite是非常强调开 ...
- query通用开源框架
Jquery通用开源框架之[ejq.js] 简介 ejq是一款非常小巧的JS工具库,未压缩才50K,在jquery的基础上对jquery缺失部分作了很好的弥补作用. 优点: 1.具有内置的模板解析引擎 ...
- MySQL的Master/Slave群集安装和配置
本文介绍MySQL的Master/Slave群集安装和配置,版本号安装最新的稳定版GA 5.6.19. 为了支持有限HA.我们用Master/Slave读写简单孤立的集群.有限HA这是当Master不 ...
- 【Yii系列】Yii2.0基础框架
缘起 因为一个月的短暂停留,我在给朋友搞事情,所以Yii系列的文章耽搁了很长时间,现在又重拾当时的知识,给大伙好好撸下这一系列的博客 提起Yii,虽然是国外的开发者搞的,但是它的作者是华人,这才是让我 ...
随机推荐
- linux Mint mysql 安装
sudo apt-get install mysql-server 之后按照提示,输入root的密码,再次输入密码,就好了. mysql -uroot -p**** //连接数据库 show data ...
- linux下编译时,链接math库
在gcc下用到数学函数,如sqrt.在gcc时要加上 -lm 参数,这样告诉编译器我要用到数学函数了 . 如:gcc a.c -o a -lm 当在用Eclipse编译使用数学函数的C语言程序时,如s ...
- 定时器管理:nginx的红黑树和libevent的堆
libevent 发生超时后, while循环一次从堆顶del timer——直到最新调整的最小堆顶不是超时事件为止,(实际是del event),但是会稍后把这个timeout的 event放到ac ...
- 关于so文件cp覆盖导致调用者core的研究
先说cp好mv/rm的区别: cp from to,则被覆盖文件 to的inode依旧不变(属性也不变),内容变为from的: mv from to,则to的inode变为from的,相应的,to的属 ...
- STL源码学习----lower_bound和upper_bound算法
转自:http://www.cnblogs.com/cobbliu/archive/2012/05/21/2512249.html 先贴一下自己的二分代码: #include <cstdio&g ...
- python的异常处理
在所有的程序中,都会遇到异常,有些异常是代码编写的时候产生的,在前期过程中可能会直接导致程序无法运行.这一类的异常,在编写代码的时候,程序可以直接排查修改.但有些异常,是在程序运行过程中产生的,可能是 ...
- Lintcode 175. 翻转二叉树
-------------------- 递归那么好为什么不用递归啊...我才不会被你骗...(其实是因为用惯了递归啰嗦的循环反倒不会写了...o(╯□╰)o) AC代码: /** * Definit ...
- 我的基于asp.net mvc5 +mysql+dapper+easyui 的Web开发框架(1)数据库访问(0)
一.数据库访问 概述 1. 数据库使用mysql,orm采用dapper框架.dapper框架应用简单,只是需要自己手写sql语句,但是对于像我这样写了多年sql语句的人来说,这应该不算问题,个人还是 ...
- Python学习笔记(3)
1.元组 元组的定义符号是() ,元素定义与列表完全一致.不同的是元组的内容是不可变的. 2.字典 字典里面的内容是无序的. 字典的元素组成形式是 key:value key的定义规则:key是不 ...
- .Net中Remoting通信机制简单实例
.Net中Remoting通信机制 前言: 本程序例子实现一个简单的Remoting通信案例 本程序采用语言:c# 编译工具:vs2013工程文件 编译环境:.net 4.0 程序模块: Test测试 ...