在这篇文章中,作者Edward Salatovka介绍了一种他称为Train的设计架构。Train允许简化组合多用户请求为一次数据库或网络查询,因此改善应用性能和减少硬件需求。这种方式的好处已经通过类似实际应用的压力测试来验证。
想像一下铁路站点以这样一种方式操作,每一个买了票的乘客立刻得到一个专属于他的列车!这种操作方式在实际生活中是可笑的,但在WEB应用服务器和数据应该访问应用却是很常见的。常规的方式意味着每一个用户请求会得到一个自己的线程和数据库连接。每一个用户请求需要一个即时的数据库或网络资源交互。显然这儿应该使有一种聪明地处理外部通讯的方式而不是增加更多的硬件。让我们寻找一种简单但还未注意到的方式来增加应用的效率。
在这篇文章中,我们采用一种新的方法即每一次与数据库或网络资源交互不是基于每一个请求而多个请求,这样高并发性的负效应如超时和死锁就会大大减少,而且大访问量下的性能衰退也可以忽略不计了。
为了使用这种方式-我们必须创建一个相应的运行应用和执行理论测试的环境。
创建一个黑盒
为了显示这种架构的优越性,我们会构建两个简单的功能上相同的servlet。两者都下发相同的包含从示例数据库获取数据的HTML页面。每一个servlet代表一种不同的实现—常规的和新式的。为了构建我们的servlet,我们需要一个WEB应用服务器,一个数据库和一个压力测试器。你可以自己选择相应的软件。这儿我使用的是Tomcat 4, JMeter和DB2。Tomcat 4和JMeter是免费的开源应用。选择DB2是为了尽可能模拟商业WEB环境。
创建数据库并添加随机内容
假设数据库名为“trdata”,我们来创建必要的方案:
//schema.sql
connect to trdata;
create table trentry (ID integer not null , NAME char(25), DESCR varchar(128), views integer with default 0, constraint p_trentry primary key (ID));
简单的JAVA应用PropSamples生成包含250000行随机数据的表trentry。
//PropSamples.java
package train;
import java.util.*;
import java.sql.*;
public class PropSamples {
public static String GetString(int size, Random rand) {
StringBuffer strBuff = new StringBuffer();
for (int i = 0; i < size; i++) {
char b = (char) (rand.nextInt(25) + 65);
strBuff.append(b);
}
return strBuff.toString();
}
public void Process() throws SQLException {
String sqlString = "insert into trentry values(?,?,?,?)";
Connection connection = Util.getDBConnection();
PreparedStatement stmt = connection.prepareStatement(sqlString);
Random rand = new Random();
for (int i = 1; i <= 250000; i++) {
stmt.clearParameters();
stmt.setInt(1, i);
stmt.setString(2, GetString(25, rand));
stmt.setString(3, GetString(128, rand));
stmt.setInt(4, 0);
stmt.execute();
if (i00 == 0) {
connection.commit();
System.out.println(i + " rows committed");
}
}
}
public static void main(String[] args) throws SQLException{
PropSamples propSamples = new PropSamples();
propSamples.Process();
}
}
这些代码是用来生成数据。Util类(可以从资源中下载的源程序中获得)包含DB2相关的属性,你可以根据自己的环境而改变。
