访问量大,服务器吃不消,怎么办?!急

BillDeng 2003-08-18 05:37:40
我在维护一套系统,apache+tomcat+jdbc+sqlserver+jsp,由于访问量较大,且都是对数据库的访问,导致系统很慢,客户端经常出现internal error的页面。不知采取什么样的措施能够较为显著地解决上述问题。请给位高手指教!谢谢
...全文
237 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
stonewang 2003-09-01
  • 打赏
  • 举报
回复
原来是连接池,哈
xqi8 2003-08-23
  • 打赏
  • 举报
回复
配置连接池
BillDeng 2003-08-23
  • 打赏
  • 举报
回复
icecloud 2003-08-23
  • 打赏
  • 举报
回复
用shtml.
K1933 2003-08-23
  • 打赏
  • 举报
回复
其实主页用静态的也是不错,但如何有相应的热点随时更新的话那就很难做到了!
seaman0916 2003-08-19
  • 打赏
  • 举报
回复
唉,太长了,终于发完了!

你研究研究看!
seaman0916 2003-08-19
  • 打赏
  • 举报
回复
/**
获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数
限制,则创建并返回新连接
*
* @param name 在属性文件中定义的连接池名字
* @return Connection 可用连接或null
*/
public Connection getConnection(String name)
{
DBConnectionPool pool = (DBConnectionPool)pools.get(name);
if(pool != null)
{
return pool.getConnection();
}
return null;
}

/**
获得一个可用连接.若没有可用连接,且已有连接数小于最大连接数限制,
则创建并返回新连接.否则,在指定的时间内等待其它线程释放连接.
*
* @param name 连接池名字
* @param time 以毫秒计的等待时间
* @return Connection 可用连接或null
*/
public Connection getConnection(String name, long time)
{
DBConnectionPool pool = (DBConnectionPool)pools.get(name);
if(pool != null)
{
return pool.getConnection(time);
}
return null;
}


/** Added by leo on 2001-5-23
将连接对象返回给默认的连接池
*
* @param con 连接对象
*/
public void freeConnection(Connection con)
{
String name = DEFAULTCONNECTIONPOOL;
freeConnection(name,con);
}

/**
将连接对象返回给由名字指定的连接池
*
* @param name 在属性文件中定义的连接池名字
* @param con 连接对象
*/
public void freeConnection(String name, Connection con)
{
DBConnectionPool pool = (DBConnectionPool)pools.get(name);
if(pool != null)
{
pool.freeConnection(con);
}
}

/**
关闭所有连接,撤销驱动程序的注册
*/
public synchronized void release()
{ // 等待直到最后一个客户程序调用
if(--clients != 0)
{
return;
}
Enumeration allPools = pools.elements();
while(allPools.hasMoreElements())
{
DBConnectionPool pool = (DBConnectionPool)allPools.nextElement();
pool.release();
}
Enumeration allDrivers = drivers.elements();
while(allDrivers.hasMoreElements())
{
Driver driver = (Driver)allDrivers.nextElement();
try
{
DriverManager.deregisterDriver(driver);
log("撤消JDBC驱动程序" + driver.getClass().getName() + "的注册");
}
catch(SQLException e)
{
log(e, "无法撤消下列JDBC驱动程序的注册" + driver.getClass().getName());
}
}
}

/**
根据指定属性创建连接池实例.
*
* @param props 连接池属性
*/
private void createPools(Properties props)
{
Enumeration propNames = props.propertyNames();
while(propNames.hasMoreElements())
{
String name = (String)propNames.nextElement();
if(name.endsWith(".url"))
{
String poolName = name.substring(0, name.lastIndexOf("."));
String url = props.getProperty(poolName + ".url");
if(url == null)
{
log("没有为连接池" + poolName + "指定URL");
continue;
}
String user = props.getProperty(poolName + ".user");
String password = props.getProperty(poolName + ".password");
String maxconn = props.getProperty(poolName + ".maxconn", "0");

int max;
try
{
max = Integer.valueOf(maxconn).intValue();
}
catch(NumberFormatException e)
{
log("错误的最大连接数限制:" + maxconn + ".连接池:" + poolName);
log("自动改变设置为0--即无限制");
max = 0;
}
DBConnectionPool pool = new DBConnectionPool(poolName, url, user, password, max);
pools.put(poolName, pool);
log("成功创建连接池" + poolName);
}
}
}

/**
读取属性完成初始化
*/
private void init()
{

InputStream is = getClass().getResourceAsStream("/db.properties");
Properties dbProps = new Properties();
try
{
dbProps.load(is);
}
catch(Exception e)
{
System.err.println("不能读取属性文件." + "请确保db.properties在CLASSPATH指定的路径中");
return;
}

String logFile = dbProps.getProperty("Managerlogfile", "DBConnectionManager.log");
try
{
logPrint = new PrintWriter(new FileWriter(logFile, true), true);
}
catch(IOException e)
{
System.err.println("无法打开日志文件:" + logFile);
logPrint = new PrintWriter(System.err);
}
loadDrivers(dbProps);
createPools(dbProps);
}

/**
装载和注册所有JDBC驱动程序
*
* @param props 属性
*/
private void loadDrivers(Properties props)
{
String driverClasses = props.getProperty("drivers");
StringTokenizer st = new StringTokenizer(driverClasses);
while(st.hasMoreElements())
{
String driverClassName = st.nextToken().trim();
try
{
Driver driver = (Driver)Class.forName(driverClassName).newInstance();
DriverManager.registerDriver(driver);
drivers.addElement(driver);
log("成功JDBC注册驱动程序" + driverClassName);
}
catch(Exception e)
{
log("无法注册JDBC驱动程序;" + driverClassName + ",错误:" + e);
}
}
}

/**
将文本信息写入日志文件
缺省为packaged
*/
void log(String msg)
{
logPrint.println(new java.util.Date() + ": " + msg);
}

/**
将文本信息与异常写入日志文件
*/
void log(Throwable e, String msg)
{
logPrint.println(new java.util.Date() + ": " + msg);
e.printStackTrace(logPrint);
}

}
dext 2003-08-18
  • 打赏
  • 举报
回复
动静结合!
一般来说,首页访问量最大!
假设你的首页里只有100条新闻,来自于5个表!
当你在添加新闻时,首页的新闻也会改变。
这时,你何不做一个程序专门生成一个首页的静态页面,这样可以省去不少查询
首页都是静态的。
seaman0916 2003-08-18
  • 打赏
  • 举报
回复
/**
从连接池获取可用连接,可以指定客户程序能够等待的最长时间
*@param timeout 以毫秒计的等待时间限制
*/
public synchronized Connection getConnection(long timeout)
{
long startTime = new Date().getTime();
Connection con;
while((con = getConnection()) == null)
{
try
{
wait(timeout);
}
catch(InterruptedException e){}
if((new Date().getTime() - startTime) >= timeout)
{
return null;
}
}
return con;
}

/**
关闭所有连接
*/
public synchronized void release()
{
Enumeration allConnections = freeConnections.elements();
while(allConnections.hasMoreElements())
{
Connection con = (Connection)allConnections.nextElement();
try
{
con.close();
log("关闭连接池" + name + "中的一个连接");
}
catch(SQLException e)
{
log(e, "无法关闭连接池" + name + "中的连接");
}
}
freeConnections.removeAllElements();
}

/**
创建新的连接
*/
private Connection newConnection()
{
Connection con = null;
try
{
if(user == null)
{
con = DriverManager.getConnection(URL);
}
else
{
con = DriverManager.getConnection(URL, user, password);
}
log("连接池" + name + "创建一个新的连接");
}
catch(SQLException e)
{
log(e, "无法创建下列URL的连接" + URL);
return null;
}
return con;
}

/**
将文本信息写入日志文件
缺省为packaged
*/
void log(String msg)
{
logPrint.println(new Date() + ": " + msg);
}

/**
将文本信息与异常写入日志文件
*/
void log(Throwable e, String msg)
{
logPrint.println(new Date() + ": " + msg);
e.printStackTrace(logPrint);
}
}



package homepage;
/*此类用于管理多个连接池对象,它支持对一个或多个由属性文件定义的数据库连接池的访问,客户程序可以调用getInstance()方法访问本类的唯一实例。它提供以下功能:
1.装载和注册JDBC驱动程序
2.根据在属性文件中定义的属性创建连接池对象
3.实现连接池名字与其实例之间的映射
4.跟踪客户程序对连接池的引用,保证在最后一个客户程序结束时安全地关闭所有连接池
*/


import java.io.*;
import java.sql.*;
import java.util.*;
//import com.supersoftintl.intranet.common.DBConnectionPool;

//import java.util.Date;

/**
* 管理类DBConnectionManager支持对一个或多个由属性文件定义的数据库连接
* 池的访问.客户程序可以调用getInstance()方法访问本类的唯一实例.
*/
public class DBConnectionManager
{
static private DBConnectionManager instance;/*唯一实例*/
static private int clients; /*该计数代表引用DBConnectionManager唯一实例的客户程序总数,
它将被用于控制连接池的关闭操作 */
//Added by leo on 2001-5-23
static private String DEFAULTCONNECTIONPOOL = "homepage";

private Vector drivers = new Vector();
private PrintWriter logPrint;
private Hashtable pools = new Hashtable();

/**
返回唯一实例。如果是第一次调用此方法,则创建实例
*/
static synchronized public DBConnectionManager getInstance()
{
if(instance == null)
{
instance = new DBConnectionManager();
}
clients++;
return instance;
}

/**
建构函数私有以防止其它对象创建本类实例
*/
public DBConnectionManager()
{
init();
}

/** Added by leo on 2001-5-23
使用默认的连接池名,创建并返回新连接
*
* @return Connection 可用连接或null
*/
public Connection getConnection()
{
return getConnection(DEFAULTCONNECTIONPOOL);
}

seaman0916 2003-08-18
  • 打赏
  • 举报
回复
一个不错的连接池程序
2002-9-18


package homepage;
/**
此内部类定义了一个连接池。它能够根据要求创建新连接,直到预定的最大连接数为止。在返回连接给客户程序之前,它能够
验证连接的有效性。此类提供以下功能:
1.从连接池获取(或创建)可用连接
2.把连接返回给连接池
3.在系统关闭时释放所有资源,关闭所有连接
4.处理无效连接(原来登记为可用的连接,由于某种原因不再可用,如超时,通讯问题)
5.限制连接池中的连接总数不超过某个预定值
*/
import java.io.*;
import java.sql.*;
import java.util.*;
import java.util.Date;



class DBConnectionPool
{
private int checkedOut;
private PrintWriter logPrint;
private Vector freeConnections = new Vector();
private int maxConn;
private String name;
private String password;
private String URL;
private String user;

/**
创建新的连接池
*@param name 连接池名字
*@param URL 数据库的JDBC URL
*@param user 数据库帐号,或null
*@param password 密码,或null
*@param maxConn 此连接池允许建立的最大连接数
*/
public DBConnectionPool(String name, String URL, String user, String password, int maxConn)
{
this.name = name;
this.URL = URL;
this.user = user;
this.password = password;
this.maxConn = maxConn;

InputStream is = getClass().getResourceAsStream("/db.properties");
Properties dbProps = new Properties();
try
{
dbProps.load(is);
}
catch(Exception e)
{
System.err.println("不能读取属性文件." + "请确保db.properties在CLASSPATH指定的路径中");
return;
}
String logFile = dbProps.getProperty("Poollogfile", "DBConnectionPool.log");
try
{
logPrint = new PrintWriter(new FileWriter(logFile, true), true);
}
catch(IOException e)
{
System.err.println("无法打开日志文件:" + logFile);
logPrint = new PrintWriter(System.err);
}
}

/**
将不再使用的连接返回给连接池
*@param con 客户程序释放的连接
*/
public synchronized void freeConnection(Connection con)
{
freeConnections.addElement(con);
checkedOut--;
notifyAll();
}

/**
从连接池获得一个可用连接,如没有空闲的连接且当前连接数小于最大连接数,则创建新连接,
如原来登记为可用的连接不再有效,则从向量删除之,然后递归调用自己以尝试新的可用连接
*/
public synchronized Connection getConnection()
{
Connection con = null;
if(freeConnections.size() > 0)
{// 获取向量中第一个可用连接
con = (Connection)freeConnections.firstElement();
freeConnections.removeElementAt(0);
try
{
if(con.isClosed())
{
log("从连接池" + name + "删除一个无效连接");
con = getConnection();
}
}
catch(SQLException e)
{
log("从连接池" + name + "删除一个无效连接");
con = getConnection();
}
}
else if(maxConn == 0 || checkedOut < maxConn)
{
con = newConnection();
}
if(con != null)
{
checkedOut++;
}
return con;
}

seaman0916 2003-08-18
  • 打赏
  • 举报
回复
目前的软件解决方法就是: 配置连接池!

CSDN的文档库里有些这样的例子,你查找一下,研究研究.
davisye 2003-08-18
  • 打赏
  • 举报
回复
学习 ..
stonewang 2003-08-18
  • 打赏
  • 举报
回复
1、建议apache+tomcat放在一台服务器,sqlserver放在另外一台服务器
2、加大内存,增加cpu(升级机器)
3、重新设计系统:将应用层给服务层分开做(可能性不大,哈)
wllmmm 2003-08-18
  • 打赏
  • 举报
回复
哎,先找找原因阿,到底是数据库吃不消还是web吃不消阿?如果都不是,那我看你只能换服务器了
Wkenny 2003-08-18
  • 打赏
  • 举报
回复
是不是用的数据库连接池啊?
laoer 2003-08-18
  • 打赏
  • 举报
回复
先是程序问题,然后是服务器的问题!

81,091

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧