最近做项目,数据库用的百度的RDS MYSQL,非常坑爹,十次连接至少三次是连不上的,而且,连不上一点提示都没有,就那么卡着,等十几分钟都没有回应。一直找不到比较合适的解决方法。百度上搜索到的内容都与这个问题无关,都是已经建好的连接超时,但是没有提到怎么才能处理建立连接的时候超时等上几个小时没回应这种坑爹问题。这次就做了一个连接拨号器,是在普通的数据库连接器的基础上改进的,原理也很简单。上代码。
代码的主体思路就是用三个内部类线程同时进行拨号,拨号成功就把连接对象放进arraylist。getconnection()方法执行的时候就检测arraylist是不是空的,如果是空的,就启动进行连接的线程,如果List里面有料就把连接对象提出来用。另外,数据库连接的时候,connection timeout的时间有时候非常长,而且完全就没有回应,这里直接让它只能等1000ms,超过没有连上直接暴力把连接线程更新掉重连。
import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.util.ArrayList;import com.mysql.jdbc.Statement;public class DatabaseConnection { private static final String DBDRIVER = "com.mysql.jdbc.Driver"; private static final String DBURL = ""; private static final String DBUSER = ""; private static final String DBPASSWORD = ""; ArrayList<Connection> arrayList = new ArrayList<Connection>(); public DatabaseConnection() throws Exception { try { Class.forName(DBDRIVER); //this.conn = DriverManager.getConnection(DBURL, DBUSER, DBPASSWORD); ThreadConnectionTimeout threadConnectionTimeout1 = new ThreadConnectionTimeout(arrayList); ThreadConnectionTimeout threadConnectionTimeout2 = new ThreadConnectionTimeout(arrayList); ThreadConnectionTimeout threadConnectionTimeout3 = new ThreadConnectionTimeout(arrayList); threadConnectionTimeout1.start(); threadConnectionTimeout2.start(); threadConnectionTimeout3.start(); } catch (Exception e) { throw e; } } public Connection getConnection() throws SQLException, InterruptedException { while(true){ for(int i = 0;i>-5;i++){//这个负责进行死循环 if(arrayList.isEmpty()==false){ return arrayList.get(0);//有连接在队列就OK } Thread.sleep(1); if(i==1000){//1000ms如果队列还没有,说明几个线程都没连上,直接更新掉线程对象,重新启动重连!相当暴力 ThreadConnectionTimeout threadConnectionTimeout1 = new ThreadConnectionTimeout(arrayList); ThreadConnectionTimeout threadConnectionTimeout2 = new ThreadConnectionTimeout(arrayList); ThreadConnectionTimeout threadConnectionTimeout3 = new ThreadConnectionTimeout(arrayList); threadConnectionTimeout1.start(); threadConnectionTimeout2.start(); threadConnectionTimeout3.start(); } } } } public void close() throws Exception { //if (this.conn != null) try { //this.conn.close(); for(int i=0;i<arrayList.size();i++){ arrayList.get(i).close(); } } catch (Exception e) { throw e; } } class ThreadConnectionTimeout extends Thread{ public ThreadConnectionTimeout(ArrayList<Connection> arrayList){ } public void run(){ try {Connection conn = null;conn = DriverManager.getConnection(DBURL, DBUSER, DBPASSWORD);arrayList.add(conn);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();} }} }
目前发现的这个代码的副作用就是,,,每次拨号的时候内存和CPU占用提高了不少,毕竟每次都是三个线程并发拨号的。
当然了,这个方法我就自己用着娱乐娱乐,有框架当然更好用啦,只是我习惯用裸的。