一、设计目的

设计出一个通用的Master-Slave基础框架,然后可以基于这个框架来实现特定的业务需求,比如实现多节点并行计算、分布式处理等。

二、设计理念

基于经典的命令模式,Master和Slave之间通过相互发送命令(Command)实现交互,命令是一个抽象的概念,Command可以用来分发任务,也可以用来传输数据, 这完全由业务来决定怎么处理, 框架只定义了一个实际的命令-心跳检测命令(Heartbeat Command)。可以通过定义自己的命令,并提供响应的命令处理器,来实现任何形式的业务。框架提供的核心功能其实只有,底层的网络通信,Master/Slave关系的维系,命令的分发功能。

三、详细设计

  1. 系统类图

核心接口和类:

名称

类型

方法

说明

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处理器

    1. 时序图

Master工作时序图

Slave工作时序图

    1. 状态迁移图

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

六、总结

目前只实现了基础的功能,还有很有一些值得去思考与实现的,如:

  1. Slave的管理,包括Slave的存活,负载,等管理。

  2. 到底是Master主动将Command推送到Slave, 还是Slave主动拉,这也是值得考虑的,不过这个实现起来还是比较简单的,目前采用Slave主动拉的机制,主要考虑到这样实现更简单也更健壮。

  3. Command分配策略的考虑,是将一个Command分配给一个Slave呢,还是一个Command可以分配个多个Slave呢,这个可以考虑用策略模式来处理。

  4. CommandHandler支持异步,这个通过回调可以很好的处理。

  5. Master单点故障的问题,怎么考虑,怎么处理z

Master-Slave通用基础框架的更多相关文章

  1. MUI项目基础框架

    码云SVN仓库地址:https://gitee.com/lim2018/vx/tree/master MUI项目基础框架,底部导航栏切换 目录结构 index为入口页主体,sub1-4为要切换的子页面 ...

  2. LayIM.AspNetCore Middleware 开发日记(三)基础框架搭建

    前言 在上一篇中简单讲了一些基础知识,例如Asp.Net Core Middleware 的使用,DI的简单使用以及嵌入式资源的使用方法等.本篇就是结合基础知识来构建一个基础框架出来. 那么框架有什么 ...

  3. 一个简单的、面向对象的javascript基础框架

    如果以后公司再能让我独立做一套新的完整系统,那么我肯定会为这个系统再写一个前端框架,那么我到底该如何写这个框架呢? 在我以前的博客里我给大家展示了一个我自己写的框架,由于当时时间很紧张,做之前几乎没有 ...

  4. 60.Android通用流行框架大全

    转载:https://segmentfault.com/a/1190000005073746 Android通用流行框架大全 1. 缓存 名称 描述 DiskLruCache Java实现基于LRU的 ...

  5. 准备.Net转前端开发-WPF界面框架那些事,搭建基础框架

    题外话 最近都没怎么写博客,主要是最近在看WPF方面的书<wpf-4-unleashed.pdf>,挑了比较重要的几个章节学习了下WPF基础技术.另外,也把这本书推荐给目前正在从事WPF开 ...

  6. JeeSite 企业信息管理系统基础框架

    1. JeeSite概述 1.1. 简介 JeeSite是一个开源的企业信息管理系统基础框架.主要定位于“企业信息管理”领域,可用作企业信息管理类系统.网站后台管理类系统等.JeeSite是非常强调开 ...

  7. query通用开源框架

    Jquery通用开源框架之[ejq.js] 简介 ejq是一款非常小巧的JS工具库,未压缩才50K,在jquery的基础上对jquery缺失部分作了很好的弥补作用. 优点: 1.具有内置的模板解析引擎 ...

  8. MySQL的Master/Slave群集安装和配置

    本文介绍MySQL的Master/Slave群集安装和配置,版本号安装最新的稳定版GA 5.6.19. 为了支持有限HA.我们用Master/Slave读写简单孤立的集群.有限HA这是当Master不 ...

  9. 【Yii系列】Yii2.0基础框架

    缘起 因为一个月的短暂停留,我在给朋友搞事情,所以Yii系列的文章耽搁了很长时间,现在又重拾当时的知识,给大伙好好撸下这一系列的博客 提起Yii,虽然是国外的开发者搞的,但是它的作者是华人,这才是让我 ...

随机推荐

  1. JAVA基础学习——1.2 环境搭建 之eclipse安装及中文化

    安装好jdk,配置好环境变量以后,下面就可以进行安装eclipse了. 闲话少说,eclipse下载地址:http://www.eclipse.org/downloads/ 不大用关注checksum ...

  2. 163邮件出错:不允许使用邮箱名称。 服务器响应为: authentication is required,smtp7,C8CowEDpS0+Uke9VvSmXBg--.546S2 1441763733

    原因:用163邮箱发邮件,需开启smtp服务,开启服务时,要求使用客户端授权码. 在.net中,使用smtp发邮件,在验证中使用的密码,是上面所讲的客户端授权码,而不是注册和web登录时用的邮箱密码. ...

  3. JQ倒计时天时分秒

    <div id="times_wrap" class="time_num"> 距离现在时间: <div class="time_w& ...

  4. repo 修改邮箱地址

    需要重新运行 repo init 被带上参数: --config-name xx@a.com

  5. ABAP 特性值取数 非BAPI方式

    特性值在ausp,objnr  一般是客户号或是客户号拼接的,客户号加特征字段特征类别就可以取了

  6. Markdown 语法说明(持续更新-20160822)

    Markdown 是一种轻量级的「标记语言」.Markdown 语法的目标是:成为一种适用于网络的书写语言.Markdown 的语法简单,熟悉Markdown语法规则,事倍功半. 语法 插入图片如何定 ...

  7. lanmp之一 (动静分离)

    一.lanmp--需求篇 1. 准备两台centos 6,其中一台机器跑mysql,另外一台机器跑apache,nginx + php 2. 同时安装apache和nginx,其中nginx启动80端 ...

  8. Qt在ui中使用代码添加新的控件

    QLabel* label = new QLabel(ui->centralWidget);

  9. C++ 字符处理函数

    C/C++里有一个头文件#include <ctype.h>,里面定义了很多字符函数,在实际开发中,用起来很方面. int isalpha(int ch)  若ch是字母('A'-'Z', ...

  10. iOS内支付