java分布式框架-JDF
2015-07-27 17:06
561 查看
1. 前言
由于信息技术的发展,特别是互联网的出现,产生并要处理请求数可能达到百万QPS,甚至更高,面对这些海量请求,普通的集中式或者集群都很难满足这个量级的请求时,可行的一种解决办法就是使用分布式运算系统与分布式文件系统来构建服务器。
再看现云概念的兴起,而分布式为云计算的基础,因此要运用云,就得先了解及应用分布式。
2. 系统架构演化历程
It架构经过几十年的发展,大致经历了以下几个阶段:
Level-1:初始阶段架构:应用程序、数据库、文件等所有的资源都在一台服务器
Level-2:应用服务和数据服务分离
Level-3:使用数据库缓存改善性能
Level-4:使用应用服务器集群
Level-5:数据库读写分离
Level-6:反向代理和CDN加速
Level-7:分布式文件系统和分布式数据库
Level-8:使用NoSQL和搜索引擎
Level-9:业务拆分
Level-10:分布式服务
参考文章:http://blog.csdn.net/binyao02123202/article/details/32340283
3. 分布式介绍
将任务分散到多台计算上运行计算,最后将结果汇总。
分布式分为两大类:分布式计算、分布式存储。
3.1.分布式与集中式的优缺点
优点:
1.计算能力可以无限扩展
2.节点可以运行在任何可以联网的普通pc上
3.每个业务节点又可做集群
4.单点故障不会影响整体程序
5.一个流程的多个步骤可以并行执行,极大提高单次请求响应时间
6.可对单个节点进行调试(其它节点可以放服务器上,对调试的节点可启在本地)
7.结构松散,节点间不会产生代码级依赖
缺点:
1.每一个流程的日志分散到多个节点上,日志查询不方便
2.每个流程的节点可能分散在各个节点上,节点通信造成无法忽略的网络开销
3.模块节点分散到网络各处,不方便统一管理
3.2.分布式与集群
一句话:分布式是并联工作,集群是串联工作。
集群的一个业务请求只能在一台服务器上完成,分布式的一个业务请求可能在很多服务器上完成。
分布式是以缩短单个任务的执行时间来提升效率的,而集群则是通过提高单位时间内执行的任务数来提升效率。
分布式可以对每个业务节点进行集群,而集如群很难整合进分布式。
4. Java分布式框架JDF(Java distributed framework)
4.1.简介
JDF按传统的mvc分层结构,从Model层到controller层基于消息对列的一整套分布式解决方案。
JDF框架源码为intellij的maven项目,提供一个简单登录例子
JDF源码SVN地址:http://code.taobao.org/svn/jdf/
4.2.关键技术与软件简介
l ActiveMQ:Apache顶级开源项目,目前最流行的,能力强劲的开源消息总线,它是JDF基础传输层
它完全支持JMS1.1和J2EE 1.4规范点对点、发布-订阅等。
支持常见协议:STOMP、MQTT、AMQP等
l Spring mvc DeferredResult类:Spring3.2以后提供服务端对异步的处理
Servlet 3.0开始提供对异步的支持,它允许一个Servlet在返回请求之后声明保持响应为打开状态,这样请求就可以交给MQ去分布式处理。
l FastJson:阿里巴巴开源的JSON解析工具,包括对对象序列化与反序列化
它能将对象在极短的时间内将它序列化与反序列化,并且对象可以不用。implements Serializable接口
l Redis:Key-Value数据库,与memcached功能相似,现只用于缓存分布式并行处理结果。
模块间maven依赖图:
@RequestMapping(value = "loginFromDb")
public DeferredResult loginFromDb(HttpServletRequest request,HttpServletResponse response) throws Exception {
DeferredResult result=new DeferredResult();
String account = request.getParameter("account");
String pwd = request.getParameter("pwd");
ReqModel reqModel = new ReqModel();
reqModel,put("account", account);
reqModel,put("pwd",pwd);
LoginWeb web = new LoginWeb(request,result);
web,login(reqModel,WebHelper.initDataCommModel());
return result;
}
2.初始化参数后去调用adminService模块,缓存当前对象的信息到通信类中
public class LoginWeb extends BaseWeb {
public void login(ReqModel in,DataCommModel out) throws Exception {
out.getReqModel().put("account", in.getStringByKey("account"));
out.getReqModel().put("pwd", in.getStringByKey("pwd"));
/**
* 去请求adminService模块
* out:请求的最终对象,
* ADMIN_SERVICE:请求模块id,
* LoginService:调用模块的这个类,
* loginBack回调方法
*/
request(out,ModelIds.ADMIN_SERVICE,"LoginService", "loginBack");
}
...
}
3.Service模块中处理
public class LoginService extends BaseBusiness {
private String account;//用户名
private String pwd;//密码
public void login(ReqModel in,DataCommModel out) throws Exception {
account =in.getStringByKey("account");
pwd=in.getStringByKey("pwd");
out.getReqModel().put("account",account);
LogHelper.insertDbLog(out.getJmsId(). Config.MODEL_ID,"开始处理登录,account:"+account+",pwd:"+pwd);
request(out, ModelIds.ADMIN_DAO, "MemberQueryDao", "loginBack");
}
}
4.adminDao模块核心代码
public Boolean query(ReqModel in, DataCommModel out) throws Exception {
....
try {
Query query = null;
Session session = sessionFactory.openSession();
query = session.createQuery(sql);
list = query.list();
out.getReqModel().putObject("list", list);
session.close();
catch (Throwable e) {
throw new Exception("持久层异常:"+e.getMessage());
}
//dao返回查询出的数据到adminService模块
return response(out);
}
5.调用adminService的回调方法
public class LoginService extends BaseBusiness {
private String account;//用户名
private String pwd;//密码
public void login(ReqModel in,DataCommModel out) throws Exception {
...
}
public void loginBack(ReqModel in,Data
b861
CommModel out){
JSONArray array=in.getJSONArrayByKey("list");
JSONObject model=(JSONObject)array.get(0);
if(pwd.equals(model.get("pwd"))){
out.getReqModel().setInfo("用户名密码验证成功");
out.getReqModel().put("model",model);
}else{...}
//返回处理数据到adminWeb
response(out);
}
6.5,调用loginWeb的回调
public class LoginWeb extends BaseWeb {
public void login(ReqModel in, DataCommModel out) throws Exception {
...
}
//登录验证返回
public Boolean loginBack(ReqModel in, DataCommModel out) throws Exception {
JSONObject json = in.getJSONByKey("model");
out.getReqModel().put("member", json);
//将用户信息缓存
findRequest().getSession().setAttribute("info", "登录成功");
findRequest().getSession().setAttribute(CoreContant.SESSION_USER_KEY, json);
//响应浏览器
return rspHttpClient(this.getReqId(), out, "forward:/model/list/-1");
}
}
示例中提供对模块的简单管理,如图:
模块管理列表:
模块点对点:模块只接收点对点请求,模块id必需为:”queue://”开头
模块订阅发布:模块订阅一个类型的,模块id必需为:”topic://”开头
除web层外,继承分布式的所有优点
采用springmvc异步,不占用宝贵的tomcat连接池资源
天生多数据源:每个DAO模块连接一个数据库,service层可调用任何一个dao
缺点
web层由于浏览器请求的地址必须固定,因此不能使用分布式,只能使用nginx等进行集群,此层只能使用点对点模式,只需要将web层模块id设置为”queue://”开头
页面布局和修饰框架:sitemesh,tiles等还不支持异步,因此还无法使用。
第一次模块与消息总线建立连接时耗时较长。
ActiveMQ:官网上面下载下来后直接运行,若”http://127.0.0.1:8161/demo/”这个页面能打开就说明已成功启动
Mysql:安装好以后,新建数据库”jdf”
Tomcat:...
Redis:key-value数据库,功能与memcached相似,并发时缓存请求返回的参数
2.主要参数配置
Core模块中类ActivemqConfig:配置activemq的一些连接地址等
Dao模块中的配置文件appContext.xml:配置mysql连接等信息
adminWeb模块中配置文件appconfig.properties:配置web层模块名及内置的登录用户名密码
3.步骤
一、启动activeMQ,mysql,tomcat,Redis
二、将adminWeb当中发布到tomcat中(若intellij为社区版,则可修改下目录下deploy。bat中的写死的路径后运行则可一键部署与更新)
三、启动以后访问:”http://127.0.0.1:8080/jdf”若可以正常打开,则说明发布成功。
因前端用了bootstrap和一些html5标签,因此请用支持html5的浏览器访问。
四、用内置系统账户登录系统
五、到模块上传页面先上传所有的依赖jar(也可直接将jar放到”e:/usr/local/models/”这个目录),再上传可执行jar:
六、完成后查看模块列表,确定所有模块都成功启动后执行下一步骤
七、退出登录再去用数据库账户登录,登录第一次,因为adminDao模块会生成表,生成以后到数据库中新增一用户。
八、再第二次用数据库账户登录,登录成功以后可看到模块模块列表,环境搭建成功。
由于信息技术的发展,特别是互联网的出现,产生并要处理请求数可能达到百万QPS,甚至更高,面对这些海量请求,普通的集中式或者集群都很难满足这个量级的请求时,可行的一种解决办法就是使用分布式运算系统与分布式文件系统来构建服务器。
再看现云概念的兴起,而分布式为云计算的基础,因此要运用云,就得先了解及应用分布式。
2. 系统架构演化历程
It架构经过几十年的发展,大致经历了以下几个阶段:
Level-1:初始阶段架构:应用程序、数据库、文件等所有的资源都在一台服务器
Level-2:应用服务和数据服务分离
Level-3:使用数据库缓存改善性能
Level-4:使用应用服务器集群
Level-5:数据库读写分离
Level-6:反向代理和CDN加速
Level-7:分布式文件系统和分布式数据库
Level-8:使用NoSQL和搜索引擎
Level-9:业务拆分
Level-10:分布式服务
参考文章:http://blog.csdn.net/binyao02123202/article/details/32340283
3. 分布式介绍
将任务分散到多台计算上运行计算,最后将结果汇总。
分布式分为两大类:分布式计算、分布式存储。
3.1.分布式与集中式的优缺点
优点:
1.计算能力可以无限扩展
2.节点可以运行在任何可以联网的普通pc上
3.每个业务节点又可做集群
4.单点故障不会影响整体程序
5.一个流程的多个步骤可以并行执行,极大提高单次请求响应时间
6.可对单个节点进行调试(其它节点可以放服务器上,对调试的节点可启在本地)
7.结构松散,节点间不会产生代码级依赖
缺点:
1.每一个流程的日志分散到多个节点上,日志查询不方便
2.每个流程的节点可能分散在各个节点上,节点通信造成无法忽略的网络开销
3.模块节点分散到网络各处,不方便统一管理
3.2.分布式与集群
一句话:分布式是并联工作,集群是串联工作。
集群的一个业务请求只能在一台服务器上完成,分布式的一个业务请求可能在很多服务器上完成。
分布式是以缩短单个任务的执行时间来提升效率的,而集群则是通过提高单位时间内执行的任务数来提升效率。
分布式可以对每个业务节点进行集群,而集如群很难整合进分布式。
4. Java分布式框架JDF(Java distributed framework)
4.1.简介
JDF按传统的mvc分层结构,从Model层到controller层基于消息对列的一整套分布式解决方案。
JDF框架源码为intellij的maven项目,提供一个简单登录例子
JDF源码SVN地址:http://code.taobao.org/svn/jdf/
4.2.关键技术与软件简介
l ActiveMQ:Apache顶级开源项目,目前最流行的,能力强劲的开源消息总线,它是JDF基础传输层
它完全支持JMS1.1和J2EE 1.4规范点对点、发布-订阅等。
支持常见协议:STOMP、MQTT、AMQP等
l Spring mvc DeferredResult类:Spring3.2以后提供服务端对异步的处理
Servlet 3.0开始提供对异步的支持,它允许一个Servlet在返回请求之后声明保持响应为打开状态,这样请求就可以交给MQ去分布式处理。
l FastJson:阿里巴巴开源的JSON解析工具,包括对对象序列化与反序列化
它能将对象在极短的时间内将它序列化与反序列化,并且对象可以不用。implements Serializable接口
l Redis:Key-Value数据库,与memcached功能相似,现只用于缓存分布式并行处理结果。
4.3.JDF框架的层次结构
JDF在模块说明:模块间maven依赖图:
4.4.核心类介绍:
类名 | 说明 | 继承 |
BaseBusiness | 业务处理核心类,提供对业务消息请求前的处理 | 无 |
BaseWeb | Web层业务处理核心类,提供对客户端响应的处理 | BaseBusiness |
BaseMySQLDao | Dao层业务处理核心类,提供对数据库的基本操作 | BaseBusiness |
MsgHandle | 消息处理,通过消息中的指定的处理类,找到模块中的相应的Business对消息进行处理,支持多线程(DAO层必需使用多线程来保持数据库连接池) | 无 |
Listener | 消息消费者:保持activeMq连接,监听模块消息,获得消息后将它交给MsgHandle | 无 |
Publishers | 消息生产者:保持对消息接收者模块的连接,将消息投递到activemq中 | 无 |
DataCommModel | 通信对象,模块之间的消息都以此对象进行序列化发送,反序列化后处理 | 无 |
4.5.实例:登录的代码流程
1.标准的springmvc@RequestMapping(value = "loginFromDb")
public DeferredResult loginFromDb(HttpServletRequest request,HttpServletResponse response) throws Exception {
DeferredResult result=new DeferredResult();
String account = request.getParameter("account");
String pwd = request.getParameter("pwd");
ReqModel reqModel = new ReqModel();
reqModel,put("account", account);
reqModel,put("pwd",pwd);
LoginWeb web = new LoginWeb(request,result);
web,login(reqModel,WebHelper.initDataCommModel());
return result;
}
2.初始化参数后去调用adminService模块,缓存当前对象的信息到通信类中
public class LoginWeb extends BaseWeb {
public void login(ReqModel in,DataCommModel out) throws Exception {
out.getReqModel().put("account", in.getStringByKey("account"));
out.getReqModel().put("pwd", in.getStringByKey("pwd"));
/**
* 去请求adminService模块
* out:请求的最终对象,
* ADMIN_SERVICE:请求模块id,
* LoginService:调用模块的这个类,
* loginBack回调方法
*/
request(out,ModelIds.ADMIN_SERVICE,"LoginService", "loginBack");
}
...
}
3.Service模块中处理
public class LoginService extends BaseBusiness {
private String account;//用户名
private String pwd;//密码
public void login(ReqModel in,DataCommModel out) throws Exception {
account =in.getStringByKey("account");
pwd=in.getStringByKey("pwd");
out.getReqModel().put("account",account);
LogHelper.insertDbLog(out.getJmsId(). Config.MODEL_ID,"开始处理登录,account:"+account+",pwd:"+pwd);
request(out, ModelIds.ADMIN_DAO, "MemberQueryDao", "loginBack");
}
}
4.adminDao模块核心代码
public Boolean query(ReqModel in, DataCommModel out) throws Exception {
....
try {
Query query = null;
Session session = sessionFactory.openSession();
query = session.createQuery(sql);
list = query.list();
out.getReqModel().putObject("list", list);
session.close();
catch (Throwable e) {
throw new Exception("持久层异常:"+e.getMessage());
}
//dao返回查询出的数据到adminService模块
return response(out);
}
5.调用adminService的回调方法
public class LoginService extends BaseBusiness {
private String account;//用户名
private String pwd;//密码
public void login(ReqModel in,DataCommModel out) throws Exception {
...
}
public void loginBack(ReqModel in,Data
b861
CommModel out){
JSONArray array=in.getJSONArrayByKey("list");
JSONObject model=(JSONObject)array.get(0);
if(pwd.equals(model.get("pwd"))){
out.getReqModel().setInfo("用户名密码验证成功");
out.getReqModel().put("model",model);
}else{...}
//返回处理数据到adminWeb
response(out);
}
6.5,调用loginWeb的回调
public class LoginWeb extends BaseWeb {
public void login(ReqModel in, DataCommModel out) throws Exception {
...
}
//登录验证返回
public Boolean loginBack(ReqModel in, DataCommModel out) throws Exception {
JSONObject json = in.getJSONByKey("model");
out.getReqModel().put("member", json);
//将用户信息缓存
findRequest().getSession().setAttribute("info", "登录成功");
findRequest().getSession().setAttribute(CoreContant.SESSION_USER_KEY, json);
//响应浏览器
return rspHttpClient(this.getReqId(), out, "forward:/model/list/-1");
}
}
示例中提供对模块的简单管理,如图:
模块管理列表:
模块点对点:模块只接收点对点请求,模块id必需为:”queue://”开头
模块订阅发布:模块订阅一个类型的,模块id必需为:”topic://”开头
4.6.JDF优缺点
优点:除web层外,继承分布式的所有优点
采用springmvc异步,不占用宝贵的tomcat连接池资源
天生多数据源:每个DAO模块连接一个数据库,service层可调用任何一个dao
缺点
web层由于浏览器请求的地址必须固定,因此不能使用分布式,只能使用nginx等进行集群,此层只能使用点对点模式,只需要将web层模块id设置为”queue://”开头
页面布局和修饰框架:sitemesh,tiles等还不支持异步,因此还无法使用。
第一次模块与消息总线建立连接时耗时较长。
4.7.JDF实例环境搭建
1.所需软件ActiveMQ:官网上面下载下来后直接运行,若”http://127.0.0.1:8161/demo/”这个页面能打开就说明已成功启动
Mysql:安装好以后,新建数据库”jdf”
Tomcat:...
Redis:key-value数据库,功能与memcached相似,并发时缓存请求返回的参数
2.主要参数配置
Core模块中类ActivemqConfig:配置activemq的一些连接地址等
Dao模块中的配置文件appContext.xml:配置mysql连接等信息
adminWeb模块中配置文件appconfig.properties:配置web层模块名及内置的登录用户名密码
3.步骤
一、启动activeMQ,mysql,tomcat,Redis
二、将adminWeb当中发布到tomcat中(若intellij为社区版,则可修改下目录下deploy。bat中的写死的路径后运行则可一键部署与更新)
三、启动以后访问:”http://127.0.0.1:8080/jdf”若可以正常打开,则说明发布成功。
因前端用了bootstrap和一些html5标签,因此请用支持html5的浏览器访问。
四、用内置系统账户登录系统
五、到模块上传页面先上传所有的依赖jar(也可直接将jar放到”e:/usr/local/models/”这个目录),再上传可执行jar:
六、完成后查看模块列表,确定所有模块都成功启动后执行下一步骤
七、退出登录再去用数据库账户登录,登录第一次,因为adminDao模块会生成表,生成以后到数据库中新增一用户。
八、再第二次用数据库账户登录,登录成功以后可看到模块模块列表,环境搭建成功。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- [原创]java局域网聊天系统