2005年9月25日
sourceforge http://www.sourceforge.net
java.net http://www.java.net
www.eclipse.org
www.opensource.org
Lomboz http://www.objectlearn.com/index.jsp (J2EE plugin for Eclipse)
htmlArea http://sourceforge.net/projects/itools-htmlarea/ (所见即所得的在线HTML编辑器)
XmlBuddy http://www.xmlbuddy.com/ (XML Editor plugin for Eclipse)
JFreeChart http://www.jfree.org/ (用于生成图表的项目)
EclipseME http://eclipseme.sourceforge.net/ (J2ME Developmnt Plugin for Eclipse)
mvnForum http://sourceforge.net/projects/mvnforum/ (论坛)
jChatBox http://www.javazoom.net/index.shtml (用servlet实现的WEB聊天引擎)
POI http://jakarta.apache.org/poi/index.html (用于处理Excel,WORD等文档的项目)
FileUpload http://jakarta.apache.org/commons/fileupload/ (用于处理HTTP文件上传得项目)
PDFBox http://sourceforge.net/projects/pdfbox/ (处理PDF文档的项目)
Lucene http://jakarta.apache.org/lucene/index.html (搜索引擎)
Digester http://jakarta.apache.org/commons/digester/ (处理XML信息的项目)
DBCP http://jakarta.apache.org/commons/dbcp/ (数据库连接池)
AXIS http://ws.apache.org/axis/ (WebService 的实现框架)
Jetspeed http://portals.apache.org/jetspeed-1/ (Portal)
HSQLDB http://sourceforge.net/projects/hsqldb/ (Im memory Database Engine)
CEWOLF http://sourceforge.net/projects/cewolf/ (一套标签库实现Web报表,使用的是jFreeChart引擎)
Struts Menu http://sourceforge.net/projects/struts-menu/ (基于Struts的Web菜单项目)
htmlparser http://sourceforge.net/projects/htmlparser/ (用于解析HTML信息的项目)
Mondrian http://sourceforge.net/projects/mondrian/(Open Source OLAP Database)
ProGuard http://sourceforge.net/projects/proguard/(Java的混淆器)
InfoGlue http://sourceforge.net/projects/infoglue/ (J2EE 内容管理系统)
JPivot http://sourceforge.net/projects/jpivot/ (基于WEB的OLAP 展现)
http://java-source.net/
HttpClient
http://jakarta.apache.org/commons/httpclient/ 处理http客户端的接口
原文地址 http://blog.csdn.net/Xviewee/archive/2007/12/17/1944374.aspx
posted @
2011-05-05 15:31 ceaboat 阅读(1118) |
评论 (0) |
编辑 收藏
1. 概述
高效率开发、易用、功能稳定、执行效率高、维护成本低、需求变更是软件开发遵循的守则,然而现实中我们面临各种各样的问题:
1. 程序员A,程序员B开发同样的功能,理解不同、开发用时、及开发质量良莠不齐,延迟交付时间普遍。相反监督者需要花费更多精力与时间可以弥补,加大投入成本。
2. 后期维护成本高,如由于测试跟不上BUG检测不到、需求变更等。
3. 同行竞争的压力,如A公司开发模块实际时间10工作日、B公司开发模块实际时间15工作日,竞标会处于劣势。
4. 随着公司业务扩展,项目繁多,招揽人员越多、管理难度越大等因素日渐凸显,造成企业发展的瓶颈。
5. 人员的培养需要大量成本,与人员的不稳定性因素对企业造成损失较大,如人员请假、离职等。
6. 开发—测试—QA—用户测试—试运营—运营,是软件开发中耗费成本巨大的一个循环过程链,制约企业发展。
上述是据个人经验总结,Db2view是针对上述问题的一个解决方案。
2. Db2view架构
Db2view是以高效、稳定、易用、低成本维护为目的所研制的一套轻量级非入侵式、自动化开发平台。兼容多种架构,如SSH、struts—spring—ibatis等容易集成到系统,根据多年的行业经验,高效的针对各行业业务特点,最大化减少建设与维护成本。目前已在多个项目实施,不断完善。
2.1 Db2view总体架构图
2.2 平台说明
2.2.1 db2view核心层
Db2view:根据编写的SQL,在所有元素据中,勾选需要显示的元素据列,即可生成自定义显示列表。
如select school_id,school_name,school_code, school_manager from school
然后在配置界面勾选school_name, school_manager字段,则显示的列表为:
school_name |
school_manager |
广东广雅中学 |
黄光裕 |
广州先烈东小学 |
王兴东 |
查询:在SQL里涉及并且勾选的元素据字段中,可以选择是否作为查询的字段,勾选后该列成为查询项,如果是时间字段还可以进行时间区间查询的选择。
排序:列表中的每个字段都可以进行升序与降序的排列功能。
自定义字段名:对每个列名称进行界面配置,如勾选school_name、school_manager字段,可以对school_name定义显示列名为:学校名称、school_manager显示列名为:学校管理员,修改后列表显示如下:
学校名称 |
学校管理员 |
广东广雅中学 |
黄光裕 |
广州先烈东小学 |
王兴东 |
转义词:数据库中记录男女使用0,1表示,而界面需要显示为男女文字的信息,使用转义词可以达到效果。
删除:界面化配置是否需要删除功能,删除指定字段的表记录。
2.2.2 扩展层
操作:所有列表均可以添加外部操作(如增加、批量删除)与行内操作(编辑、删除),由此构成一个完整的业务功能。(示例见演示视频)
数据导出:界面化配置是否需要excel数据导出功能,根据查询的条件显示的数据,可选择导出当前所见数据与所有满足条件的数据两个选择。
模板定制:界面化配置模板,方便为不同的客户需求定制不同的显示模板。
换肤:界面化配置皮肤,每个模板依据规范可以有不同的皮肤更换功能。
数据安全:加入访问权限控制规则,保障功能数据安全性。(待实现)
3. 平台优缺点
3.1 优点
(1)高效率开发:db2view平台开发工具采用全界面配置,编写业务SQL,简单配置,即可完成。列表功能开发以分钟计时,15分钟可以完成一个高质量列表的功能开发。
(2)易用性:界面编写SQL,然后配置即可得到一个界面友好,高质量的功能列表。将传统程序员需要熟悉各种复杂的技术框架解放出来,专注于业务逻辑,大大降低企业由于人员离职或其他情况所带来的损失。
(3)功能稳定:所有功能使用统一内核,经过多个项目的迭代验证其稳定性、可靠性。
(4)低成本维护: 所有的功能需要维护的只有业务SQL与配置文件,最大化的减少维护的成本。
比较现今流行的SSH架构开发流程:
维护成本是流程涉及的内容,成本花费高。
Db2view开发流程:
维护成本只有业务SQL与配置文件,易于维护。
(5)快速响应需求变更:如业务更改字段名、添加或删除显示字段、
添加查询字段、功能删除等维护工作都能够在极短的时间内响应。
(6)无需重启服务器:功能的生成与修改实时生效,无需重启服务器。
3.2 缺点
(1) 平台仍需完善,暂不能够满足所有业务需求界面化
(2) 平台操作友好性仍待提高,如转义词的添加、新添加配置等
4. 平台支撑环境
数据库:ORACLE 10G以上版本
语言:JAVA
JDK版本:1.4以上
服务器:Tomcat,JBoss,Resin,WebSphere,WebLogic等主流服务器。
5. 部署
根据开发模式分为两种部署方式。
面向服务式模式:
作为分布式服务器对外提供服务,生成功能链接嵌入应用系统。该模式的优点:
1. 对应用系统完全无入侵,100%轻量级开发。
2. 产品升级调试简单。
缺点:
1. 需要开放应用的数据库访问权限。
2. 涉及操作并有关联动作:如删除功能在A系统开发,B系统是Db2view,关联页面需要设置同域方能进行交互。
3. 安全性相对另一种模式低。
组件模式:
作为组件集成到开发项目中,容易管理,安全性也高。
优点:
安全性高,可根据开发系统的权限要求做安全性控制
缺点:
升级调试相对复杂。
5分钟生成功能例子,对此工具有兴趣者请加群:12990321.
posted @
2010-04-01 17:47 ceaboat 阅读(1412) |
评论 (0) |
编辑 收藏
#1
世界上最经典的25句话
1.记住该记住的,忘记该忘记的。改变能改变的,接受不能改变的。
2.能冲刷一切的除了眼泪,就是时间,以时间来推移感情,时间越长,冲突越 淡,仿佛不断稀释的茶。
3.怨言是上天得至人类最大的供物,也是人类祷告中最真诚的部分。
4.智慧的代价是矛盾。这是人生对人生观开的玩笑。
5.世上的姑娘总以为自己是骄傲的公主(除了少数极丑和少数极聪明的姑娘例外)。
6.如果敌人让你生气,那说明你还没有胜他的把握。
7.如果朋友让你生气,那说明你仍然在意他的友情。
8.令狐冲说“有些事情本身我们无法控制,只好控制自己。”
9.我不知道我现在做的哪些是对的,那些是错的,而当我终于老死的时候我才知道这些。所以我现在所能做的就是尽力做好待着老死。
10.也许有些人很可恶,有些人很卑鄙。而当我设身为他想象的时候,我才知道:他比我还可怜。所以请原谅所有你见过的人,好人或者坏人。
11.鱼对水说你看不到我的眼泪,因为我在水里.水说我能感觉到你的眼泪,因为你在我心里。
12.快乐要有悲伤作陪,雨过应该就有天晴。如果雨后还是雨,如果忧伤之后还是忧伤.请让我们从容面对这离别之后的离别。微笑地去寻找一个不可能出现的你!
13.死亡教会人一切,如同考试之后公布的结果——虽然恍然大悟,但为时晚矣~!
14.你出生的时候,你哭着,周围的人笑着;你逝去的时候,你笑着,而周围的人在哭!一切都是轮回!!!! 我们都在轮回中!!!!
15.男人在结婚前觉得适合自己的女人很少,结婚后觉得适合自己的女人很多。
16.于千万人之中,遇见你所遇见的人;于千万年之中,时间的无涯荒野里,没有早一步,也没有晚一步,刚巧赶上了 。
17.每个人都有潜在的能量,只是很容易:被习惯所掩盖,被时间所迷离,被惰性所消磨。
18.人生短短几十年,不要给自己留下了什么遗憾,想笑就笑,想哭就哭,该爱的时候就去爱,无谓压抑自己。
19.《和平年代》里的话:当幻想和现实面对时,总是很痛苦的。要么你被痛苦击倒,要么你把痛苦踩在脚下。
20.真正的爱情是不讲究热闹不讲究排场不讲究繁华更不讲究嚎头的。
21.生命中,不断地有人离开或进入。于是,看见的,看不见的;记住的,遗忘了。生命中,不断地有得到和失落。于是,看不见的,看见了;遗忘的,记住了。然而,看不见的,是不是就等于不存在?记住的,是不是永远不会消失?
22.我们确实活得艰难,一要承受种种外部的压力,更要面对自己内心的困惑。在苦苦挣扎中,如果有人向你投以理解的目光,你会感到一种生命的暖意,或许仅有短暂的一瞥,就足以使我感奋不已。
23.我不去想是否能够成功,既然选择了远方,便只顾风雨兼程;我不去想,身后会不会袭来寒风冷雨,既然目标是地平线,留给世界的只能是背影。
24.后悔是一种耗费精神的情绪.后悔是比损失更大的损失,比错误更大的错误.所以不要后悔 。
25.日出东海落西山,愁也一天,喜也一天;遇事不钻牛角尖,人也舒坦,心也舒坦。
posted @
2006-12-05 11:31 ceaboat 阅读(234) |
评论 (0) |
编辑 收藏
现象一:
错误信息:
java.lang.SecurityException: sealing violation: can't seal package oracle.jdbc.driver: already loaded
原因:
was启动的lib里存在多个ORACLE DRIVER。
解决:
保留最新的一个驱动包解决。
遗留问题:
开发环境使用TOMCAT发布无此问题,JBUILDER2006开发中包是有优先顺序的,即使存在多个
相同的类,优先选择第一个找到的类。WAS在这方面显然存在不足,排异容错性不够强大。
现象二:
错误信息:
Error 500: LinkageError while defining class: com.gzedu.eecn.structure.login.action.UserLoginAction Could not be defined due to: com/gzedu/eecn/structure/login/action/UserLoginAction (Illegal constant pool type) This is often caused by having a class defined at multiple locations within the classloader hierarchy. Other potential causes include compiling against an older or newer version of the class that has an incompatible method signature. Dumping the current context classloader
原因:
上传的文件已经损坏。重复试过很多次,发现本机器通过SSH上传过程中文件已经损坏。
属于本机问题。
解决:
通过同事的机器上传文件解决
总结:
类似此问题出现的几率很小,可以认为是相同的环境,使用相同的方式做一件事情也有可能出现
不同的效果。再次出现类似问题可以更快的定位错误点。
现象三:
错误信息:
com.ibm.ws.jsp.translator.JspTranslationException: JSPG0227E: 转换 /login.jsp:
/login.jsp(1,1) --> JSPG0145E: 未知 JSP 元素:jsp:directive.pagelanguage
原因:
windows环境、tomcat作为服务器开发,部署到sit、unix环境,会出现页面不同的开发环境会
有中文问题,或是说重复定义encoding的问题页面编码问题。
解决:
按照如下进行修改和配置;
1. 对于不是被include的页面必须使用;
<%@ page contentType="text/html;charset=GBK" pageEncoding="GBK" language="java" %>
。 大写GBK
2. 对于被Include的页面必须使用如下;
。<%@ page pageEncoding="GBK" language="java" %>
注:在TOMCAT4.1.30-->was5.0,6.0出现此问题
posted @
2006-01-25 15:09 ceaboat 阅读(2049) |
评论 (0) |
编辑 收藏
sun.jdbc.rowset.CachedRowSet是sun提供的缓存数据集的一个类(数据集持久化),对BLOG,CLOG不能支持,LOG的容量是4G,结果集里存在LOG字段缓存时会报java.lang.NumberFormatException: For input string: "4294967295"
据说sun对LOG的支持原来是2G,不晓得是否有支持4G的类。
对于原来使用的com.sun.rowset.CachedRowSetImpl深感疑惑此类在缓存number字段的时候如果SCALE没声明会报不能小于0的异常
posted @
2005-12-09 09:57 ceaboat 阅读(849) |
评论 (0) |
编辑 收藏
1.GB2312支持拼音排序,GBK、GB18030不支持。2005年11月23日15:31:42
2.websphere5与6的区别:5对路径不需要/,而6必须要/,否则因为少了/找不到相应的配置文件
posted @
2005-11-23 15:31 ceaboat 阅读(339) |
评论 (0) |
编辑 收藏
参与一个项目要做到:
1.项目中有你参与整个项目进展会顺利的多。体现你的重要性。
2.一个人的能力再强,精力是有限的。切记不可体现个人主义,充分发挥团队能力,协调、配合往往比
技术重要性排前一个位置。
3.主动承担一些责任,对团队可提高士气融合的气氛、对个人当成一个磨练的机会。
4.注意项目中遇到的一些细小的问题。最不起眼的就是最能考验个人细心的程度,自己负责的事情要做到
最好。
5.同一件事情不同的人处理效果不同。
posted @
2005-11-10 00:21 ceaboat 阅读(431) |
评论 (0) |
编辑 收藏
通过URL来访问网站,action里request.getMothod()得到的GET.
而通过FORM来提交的则可以设置POST,可以通过这两种方
式的差异来做一些第一次访问与之后访问的一些个性化设置。
posted @
2005-11-09 20:17 ceaboat 阅读(359) |
评论 (0) |
编辑 收藏
增加翻页接口,满足各种分页不同的界面化显示。
代码已经开发完,工具需要做小量修改,进期主要任务是编写使用手册。
2005年10月16日21:43:36
posted @
2005-10-16 21:43 ceaboat 阅读(348) |
评论 (0) |
编辑 收藏
10.1到珠海过关的时候检查边防证,偶可是没那小本本,边警上来搜查,抓了4个人下去补办。(很多人都是没办的)看来穿着整齐是有点效果,人品好麻烦自然少
posted @
2005-10-03 21:50 ceaboat 阅读(415) |
评论 (0) |
编辑 收藏
打算到上海浙江一带去放松,解决工作上的压力。现在是去不成了,国庆4天假,广州不是放松的好地方。白云山还算可以一去,只好改去珠海玩两天,吃点海鲜补偿补偿了
posted @
2005-10-01 12:59 ceaboat 阅读(413) |
评论 (0) |
编辑 收藏
WASD支持热启动,修改代码保存服务器进行实时更新,CachedRowSet crs = new CachedRowSetImpl();缓存数据集出异常。服务器热启动与缓存机制之间有冲突。
posted @
2005-10-01 12:54 ceaboat 阅读(434) |
评论 (0) |
编辑 收藏
测试源代码
CapabilityForConnection 主运行程序,读取配置文件init.properties、reference.properties初始化参数。调用POOLTEST(一次完整的测试用例),计算其平均时间与使用连接数
package com.cea.repository.test;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
import java.util.Properties;
import java.io.FileInputStream;
import java.io.InputStream;
public class CapabilityForConnection {
private static Log log = LogFactory.getLog(CapabilityForConnection.class);
/**
* 计算一次测试所消耗的时间
*/
public static long times = 0;
/**
* 连接数
*/
public static long psize = 0;
public static void main(String[] args) throws Exception {
/**
* 运行的次数
*/
int size = 1;
/**
* 见POOLTEST说明
*/
int execsum = 0;
/**
* 见POOLTEST说明
*/
int opencon = 0;
/**
* execsum对应properties的命名
*/
String execs = null;
/**
* opencon对应properties的命名
*/
String openc = null;
long sumtime = 0;
Properties prop = initProperty("reference.properties");
Properties init = initProperty("init.properties");
if (init.size() > 0) {
Object o = init.get("init");
size = Integer.parseInt(o.toString());
execs = init.get("name0").toString();
openc = init.get("name1").toString();
}
for (int i = 0; i < prop.size() / 2; i++) {
execsum = Integer.parseInt(prop.getProperty(execs + i).toString());
opencon = Integer.parseInt(prop.getProperty(openc + i).toString());
sumtime = 0;
psize = 0;
log.info("第" + (i + 1) + "组数据:");
log.info("并发应用数:" + execsum + " 模拟连接数:" + opencon);
String[] reference = {"" + execsum, "" + opencon};
for (int j = 0; j < size; j++) {
times = 0;
PoolTest.main(reference);
sumtime += times;
}
log.info("第" + (i + 1) + "组数据共执行" + size + "次;平均耗时为:" +
sumtime / (size * execsum) + "毫秒");
log.info("平均使用" + psize / size + "个连接");
}
}
private static Properties initProperty(String filename) throws Exception {
InputStream is = new FileInputStream(filename);
Properties prop = new Properties();
prop.load(is);
return prop;
}
}
POOLTEST计算一次完整过程耗时,统计消耗的连接
package com.cea.repository.test;
import com.cea.repository.test.testdata.MainExecute;
import java.util.HashMap;
import java.util.Map;
import com.cea.repository.connection.PoolSupper;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
/**
*
*
Title: 连接池性能测试
*
*
Description: 测试不合理的利用连接对WEB应用所造成影响.
*
*
Copyright: Copyright (c) 2005
*
*
Company:
*
* @author 小舟
* @version 1.0
*/
public class PoolTest extends Thread {
private static Log log = LogFactory.getLog(PoolTest.class);
/**
* 并发执行MainExecute的数量
*/
private static int EXECUTESUM = 35;
/**
* 一次MainExecute执行所请求的连接数
*/
public static int CONNECTIONS = 3;
/**
* 记录所使用的连接
*/
public static Map poolTestMap = new HashMap();
/**
* 第sum次执行MainExecute所需要的时间
*/
public int sum = 0;
public void run() {
try {
long s = System.currentTimeMillis();
com.cea.repository.test.testdata.MainExecute.main(null);
long t = System.currentTimeMillis() - s;
CapabilityForConnection.times +=t;
// if(CapabilityForConnection.times < t){
// CapabilityForConnection.times = t;
// }
// log.info("time" + (++sum) + ":" +
// (System.currentTimeMillis() - s));
} catch (Exception ex) {
}
}
public static void main(String[] args) throws Exception {
if(args!= null && args.length>1){
EXECUTESUM = Integer.parseInt(args[0]);
CONNECTIONS = Integer.parseInt(args[1]);
}
PoolSupper.initPool();
startExec(EXECUTESUM);
//设定足够长的时间等待所有程序执行完,得到准确的并发执行所消耗的时间
try {
Thread.sleep(6000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
log.info("运行平均耗时:" + CapabilityForConnection.times/EXECUTESUM);
//如果条件成立,证明连接没有被回收,只要存在一个相同的,就证明连接被重复利用了
CapabilityForConnection.psize +=poolTestMap.size();
if (poolTestMap.size() == EXECUTESUM) {
log.info("不存在重复使用的连接,共创建" + poolTestMap.size()+ "个连接" );
} else {
log.info("共使用" + poolTestMap.size()+ "个连接" );
}
clear();
}
private static void startExec(int EXECUTESUM) {
int i = 0;
while (i < EXECUTESUM) {
if (i++ < EXECUTESUM) {
try {
new PoolTest().start();
} catch (Exception ex2) {
}
}
}
}
private static void clear() {
poolTestMap = new HashMap();
}
}
简单的不能再简单的测试代码:
package com.cea.repository.test.testdata;
import com.cea.repository.connection.drive.ConnectionFactory;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import com.cea.repository.test.PoolTest;
import com.cea.repository.connection.poolpository.PoolFactory;
/**
*
*
Title:
*
Description:
*
Copyright: Copyright (c) 2004
*
Company: cea
* @author 小舟
* @version 1.0
*/
public class MainExecute {
public static void main(String[] args) throws Exception {
testConnection();
}
static void testConnection() throws Exception {
for (int i = 0; i < PoolTest.CONNECTIONS; i++) {
Connection con = PoolFactory.newInstance();
//这里的改变直接影响连接的复用
Thread.sleep(50);
PoolTest.poolTestMap.put(con.toString(), "");
con.close();
}
}
}
三个配置文件的内容:
init.properties文件
#运行的次数
init=5
#并发执行MainExecute的数量所匹配的名字
name0=execsum
#一次MainExecute执行所请求的连接数所匹配的名字
name1=opencon
reference.properties文件
#过滤数据
execsum0=10
opencon0=1
#第一次测试数据
execsum1=100
opencon1=6
#第二次测试数据
execsum2=85
opencon2=9
#第三次测试数据
execsum3=140
opencon3=3
最后一个是pool-config.xml数据源配置:
xml version="1.0" encoding="GB2312"?>
<DataResources>
<ResourceParams dateIndentity="boat1">
<defaultAutoCommit>false< SPAN>defaultAutoCommit>
<initialSize>30< SPAN>initialSize>
<maxActive>40< SPAN>maxActive>
<minIdle>0< SPAN>minIdle>
<maxIdle>18< SPAN>maxIdle>
<maxWait>10000< SPAN>maxWait>
<username>forum< SPAN>username>
<password>king< SPAN>password>
<driverClassName>oracle.jdbc.driver.OracleDriver< SPAN>driverClassName>
<url>jdbc:oracle:thin:@192.168.1.3:1521:gzest< SPAN>url>
<removeAbandoned>true< SPAN>removeAbandoned>
<removeAbandonedTimeout>10< SPAN>removeAbandonedTimeout>
<logAbandoned>true< SPAN>logAbandoned>
< SPAN>ResourceParams>
< SPAN>DataResources>
posted @
2005-09-26 22:36 ceaboat 阅读(1645) |
评论 (0) |
编辑 收藏
影响性能的测试报告(数据库版)
如需转载,请与笔者联系
前提:项目组里无用到SPRING进行事务的管理。项目里以功能划分到每个人手里,
形成了BO,DAO,ACTION,VIEW都是单人负责。在DAO中每个动作都以
封闭式的形式存在。
问题:造成事务的不连贯性。功能是做出来了,性能问题迟早暴露。
测试:主要针对程序频繁请求数据库连接对WEB应用所造成影响做一个测试。
先做必要的说明,一步步引入正题,先从性能瓶颈开始:
所有的应用程序都存在性能瓶颈,为了提高应用程序的性能,就要尽可能的减少程序的瓶颈。以下是在JAVA程序中经常存在的性能瓶颈。
了解了这些瓶颈后,就可以有针对性的减少这些瓶颈,从而提高JAVA应用程序的性能
关于连接池的实现原理测试方案:
经过资料的收集与APACHE DBCP里连接池的查阅,对现有的连接池工作
原理有两种方式:
1. 数据库预先设置配置好的连接数。待得到用户请求连接,传出一个连接,而后为了保持供应数再提前创建连接,即提前预备连接数供请求。比如:
有5个通行道代表最大激活的连接数,最小2个闲置连接数。也就是说连接池里始终预备了2个可随时提供的连接,连接的创建开销是比较大的,连接池的存在就是了能够最小化的解决创建所等待的时间。
1 O
2 O
3 *
4 *
5 *
如上图,当1分配出去时由于池中连接数剩一个,为保持最小闲置,会自动创建一个新的连接以防止再次请求等待创建的时间。这样确实减少了等待的时间,但是数据库创建的开销方面并未得到解决。如果把1-5比喻成汽车,那么这种情况下每量车都是一次性使用。1被请求后下一个连接将是6来接替。那么如何能够重复利用1减少数据库开销。于是引出第二种方式。
2. 回收使用完后的连接,放回到池中进行循环利用。这么做必须能保证2点
一. 使连接能够保持有效的回收。
二. 约束使用者使用释放的动作,而不是直接把连接close.
本人使用的是APACHE DBCP里BasicDataSource的连接池基本实现,
经过代码与测试结果显示,其工作方式是基于二的。
请看测试用例
测试结果:
第2组数据:
并发应用数:100 模拟连接数:6
运行平均耗时:2956
共使用51个连接
运行平均耗时:3391
2共使用52个连接
运行平均耗时:2616
共使用47个连接
运行平均耗时:3377
共使用41个连接
运行平均耗时:3673
共使用46个连接
第2组数据共执行5次;平均耗时为:3229毫秒
平均使用47个连接
第3组数据:
并发应用数:85 模拟连接数:9
运行平均耗时:4830
共使用53个连接
运行平均耗时:3247
共使用49个连接
运行平均耗时:4116
共使用40个连接
运行平均耗时:4070
共使用43个连接
运行平均耗时:4053
共使用54个连接
第3组数据共执行5次;平均耗时为:4063毫秒
平均使用47个连接
第4组数据:
并发应用数:140 模拟连接数:3
运行平均耗时:2076
共使用47个连接
运行平均耗时:3104
共使用51个连接
运行平均耗时:2048
共使用43个连接
运行平均耗时:2421
共使用50个连接
运行平均耗时:2751
共使用50个连接
第4组数据共执行5次;平均耗时为:2480毫秒
平均使用48个连接
每次测试的结果都可能不同,但是所得到的结论是一致的。数据显示不合理的请求使用连接严重的影响应用所能承受的并发数量,响应的时间也因此受到影响。
没有把事务控制好,一般会出现以下的情况:
事务(){
流程1();
流程2();
}
可以看出流程1,2里都是单独创建连接,并在自己的流程里完成操作。
如果在流程2里出现异常,那么流程1所做的操作是不可恢复的。
如果能控制在事务范围内,如:
事务(){
Connection con;
流程1(con);
流程2(con);
con.close();
}
那么数据库少提供一个连接,事务的完成性也得到体现。在并发数量大的时候,
效率上就有非常明显的区别。
1. 尽量保持少的请求
如DAO中有update()方法,则应再扩展一个方法update(Connection conn)
在业务逻辑事务里调用update(Connection conn),一般情况下调用update()
2. 对于数据不变的情况采用缓存技术,或部分缓存技术。
可参照一些相关的开源的项目(JIVE)。
posted @
2005-09-25 17:21 ceaboat 阅读(1657) |
评论 (4) |
编辑 收藏