Java Web 下彻底解决MySQL 8 小时问题
来源:互联网 发布:怎样注册淘宝号 编辑:程序博客网 时间:2024/06/13 10:50
一、问题的提出
在MySQL数据库中,当一个客户端的连接超过8小时没有向服务器发起任何请求时,连接将被服务端关闭。
而在Java Web中,很多是信息管理性质的系统,工作人员下班后服务器基本上不再向数据库发起请求,因此经常出现8小时后服务器会莫名其妙“死”一阵子的问题
二、解决思路
思路很简单,就是让 Java Web 服务器定向服务器发起一些请求,让这些连接不至于连续8小时都没事干。简而言之,就是给这些数据库连接找些事干。
通常我是让它执行 Select Now() 语句,不用访问数据库磁盘
思路虽然简单,但是实现起来却不是那么简单
1、你得保证连接池中的连接在一定时间范围内被激活一次,当然如果这个连接正在执行访问数据库的操作,则可以不激活
2、为了达到1的目的,就必须使用一个锁机制,确保连接池中所有的连接都被激活一次之后,再把这些连接放回到连接池。否则你连续取到的连接,可能是同一个。
如,你的连接池中有10个连接,如果执行10次循环,每次循环到连接池中取一次连接执行 select now() 查询,然后释放连接,那么你这10次循环可能拿到的都是同一个连接
3、如果为了避免2中的情况发生,把所有的10次连接全部占用完成之后再释放,则有可能出现死锁。
三、程序原理
创建与连接池数量相同的线程,每过一段时间(如1小时)激活这10个线程,每个线程执行一次数据库操作,然后等待2秒,最后进行统一释放连接
这样做,当系统的连接都很空闲时,可保证每个连接都被执行一次;当系统比较忙时,由于每个线程只保持2秒连接,也不会影响系统性能
使用时,在 servlet 中添加一个 ServletContextListener,启动时执行:
public void contextDestroyed(ServletContextEvent sce) {dbHolder.stopHold();}public void contextInitialized(ServletContextEvent sce) {dbHolder = new DBHolder(new DBHolderAction(){private Connection conn = null;@Overridepublic void doAction() throws SQLException {conn = ....// 执行 sql 语句}@Overridepublic void closeDBSession() throws SQLException {try{conn.close();}catch(Exception ex){}finally{conn = null;}}}, 10, // 最大连接数,请从配置文件中读取,这里取固定值60 * 60 // 运行周期);dbHolder.startHold();}
定义的程序代码:
import java.util.*;import org.apache.log4j.Logger;public class DBHolder {private static final Logger logger = Logger.getLogger(DBHolder.class);private boolean holding = false;private Object holdLock = new Object();private int executePeriod;private int maxActive;private DBHolderAction action = null;private Queue<ExecuteThread> threads = new LinkedList<ExecuteThread>();class ExecuteThread extends Thread {private Object locker = new Object();public void run(){if(action == null)return;synchronized(locker){try{long time1 = System.currentTimeMillis();action.doAction();long time2 = System.currentTimeMillis();logger.debug("DBHolder:线程 " + this.getName() + " 访问数据库,共用时" + (time2 - time1) + "毫秒");}catch(Exception e){logger.debug(e.getMessage(), e);}finally{synchronized(threads){threads.add(this);threads.notifyAll();}try{// 一个连接最多保持2秒locker.wait(2 * 1000);}catch(Exception e){}try{logger.debug("DBHolder:线程,开始关闭线程 " + this.getName() + " 的数据库资源");action.closeDBSession();logger.debug("DBHolder:线程,线程 " + this.getName() + " 的数据库资源已经关闭");}catch(Exception e){}}}}public void close(){synchronized(locker){try{locker.notifyAll();}catch(Exception ex){}}}public ExecuteThread(String name){super(name);}}public void startHold(){if(holding == true)return;holding = true;new Thread(){@Overridepublic void run(){while(holding){logger.debug("DBHolder:调度,清理线程");synchronized(threads){while(threads.size() > 0){threads.poll().close();}}logger.debug("DBHolder:调度,清理线程完成,现在创建新的线程,线程数:" + maxActive);for(int i=0; i<maxActive; i++){new ExecuteThread("DBHolder Thread " + (i + 1)).start();}logger.debug("DBHolder:调度,线程启动完成,等待所有线程全部完成数据库访问");synchronized(threads){while(threads.size() < maxActive){try {logger.debug("DBHodler:调度,等待所有线程全部完成数据库访问");threads.wait(1000);} catch (InterruptedException e) {}}}logger.debug("DBHolder:调度,全部线程完成数据库访问,开始释放全部线程的数据库资源");while(threads.size() > 0){threads.poll().close();}logger.debug("DBHolder:调度,全部线程的数据库资源释放完毕");synchronized(holdLock){try{holdLock.wait(executePeriod * 1000L);}catch(Exception ex){}}}}}.start();}public void stopHold(){try{this.holding = false;this.holdLock.notifyAll();}catch(Exception ex){}}/** * 类构造器 * @param action 用于执行数据库访问的接口 * @param maxActive 数据库最大连接数 * @param executePeriod 数据库保持连接操作的运行周期,以秒为单 */public DBHolder(DBHolderAction action, int maxActive, int executePeriod){this.executePeriod = executePeriod;this.maxActive = maxActive;this.action = action;}}
public interface DBHolderAction {public void doAction() throws java.sql.SQLException;public void closeDBSession() throws java.sql.SQLException;}
- Java Web 下彻底解决MySQL 8 小时问题
- Mysql 8小时问题
- mysql 8小时问题
- mysql 8小时问题
- MySql java 中文乱码问题彻底解决 MAC
- mysql wait_timeout 8小时问题
- 解决MYSQL 8小时问题
- 解决 MYSQL 8 小时问题
- MySQL数据库8小时问题
- mysql 8小时timeout问题
- Mysql连接 8小时问题
- Mysql 经典8小时问题
- 彻底解决java WEB项目的文件路径问题(war包)
- 经典问题:MYSQL 8小时问题
- mysql中文乱码问题彻底解决
- 彻底解决mysql数据乱码问题
- 彻底解决MySQL中文乱码问题
- MYSQL 8小时 断开链接问题
- UVALive 4127
- nginx配置ssl
- 专题一 · 1005
- 待完善知识点
- 有关小波变换的介绍
- Java Web 下彻底解决MySQL 8 小时问题
- 数据库中的VARCHAR(M)及其他变长类型
- SVM支持向量机原理(一)
- Activity与Fragment的生命周期详解
- python yield协程
- DIP、Ioc、DI、Ioc容器概念
- 3D dungeon
- Spring3第二天
- Android 开发过程遇到的错误和总结