Mysql連接超時解決方案2: 配置Proxool連接池

MySQL數據庫默認的連接超時時間爲8h(即wait_timeout=28800s),如果一個連接閒置時間超過8h,MySQL會主動斷開這個連接。用proxool連接池可以解決Mysql自動斷開重連的問題,它具有移植性好,快速、成熟、健壯等特性,同時還提供了可視化的連接池實時監控工具。proxool連接池配置如下:

1、下載相關JAR包;

從Maven Repository倉庫中下載proxool相關jar包,並將proxool-0.9.1.jar和proxool-cglib.jar拷貝至項目中。

2、在WEB-INF目錄下新建一個proxool.xml文件,配置如下:

<?xml version="1.0" encoding="UTF-8"?>   
<something-else-entirely>  
    <proxool>  
        <alias>dbname</alias> <!--數據源的別名-->  
        <driver-url> jdbc:mysql://localhost:3306/testdb</driver-url><!--url連接串-->  
        <driver-class>com.mysql.jdbc.Driver </driver-class> <!--驅動類-->  
        <driver-properties>  
            <property name="user" value="root" /> <!--用戶名-->  
            <property name="password" value="root" /><!--密碼-->  
        </driver-properties>   
        <!--最大連接數(默認5個),超過了這個連接數,再有請求時,就排在隊列中等候,最大的等待請求數由maximum-new-connections決定 -->  
        <maximum-connection-count>100</maximum-connection-count>   
        <!--最小連接數(默認2個)-->  
        <minimum-connection-count>10</minimum-connection-count>   
        <!--proxool自動偵察各個連接狀態的時間間隔(毫秒),偵察到空閒的連接就馬上回收,超時的銷燬 默認30秒-->  
        <house-keeping-sleep-time>90000</house-keeping-sleep-time>  
        <!--沒有空閒連接可以分配而在隊列中等候的最大請求數,超過這個請求數的用戶連接就不會被接受-->  
        <maximum-new-connections>10</maximum-new-connections>
<!--如果housekeeper檢測到某個線程的活動時間大於這個數值.它將會殺掉這個線程.所以確認一下你的服務器的帶寬.然後定一個合適的值.默認是5分鐘.-->		
<maximum-active-time>300000</maximum-active-time> 
        <!--最少保持的空閒連接數(默認2個)-->  
        <prototype-count>5</prototype-count>   
        <!--在使用之前測試-->  
        <test-before-use>true</test-before-use>  
        <!--用於保持連接的測試語句 -->  
        <house-keeping-test-sql>select sysdate from dual</house-keeping-test-sql>  
</proxool>  
<proxool>   
        <alias> dbname2</alias>   
        <driver-url>jdbc:oracle:thin:@localhost:1521:testdb2</driver-url>  
        <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>   
        <driver-properties>   
            <property name="user" value="dba" />   
            <property name="password" value="dba" />   
        </driver-properties>   
        <maximum-connection-count>100</maximum-connection-count>   
        <minimum-connection-count>10</minimum-connection-count>   
<house-keeping-sleep-time>90000</house-keeping-sleep-time>   
        <maximum-new-connections>10</maximum-new-connections>   
        <maximum-active-time>300000</maximum-active-time>
<prototype-count>5</prototype-count>   
        <test-before-use>true</test-before-use>
        <house-keeping-test-sql>select sysdate from dual</house-keeping-test-sql>
    </proxool>
</something-else-entirely>

這裏面你可以根據需要配置多個不同數據庫的數據源。

3、配置web.xml文件;

<?xml version="1.0" encoding="UTF-8"?>  
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  
<servlet>  
  <servlet-name>ServletConfigurator</servlet-name>  
  <servlet-class>org.logicalcobwebs.proxool.configuration.ServletConfigurator</servlet-class>  
  <init-param>  
    <param-name>xmlFile</param-name>  
    <param-value>WEB-INF/proxool.xml</param-value>  
  </init-param>  
  <load-on-startup>1</load-on-startup>  
</servlet> 

<!-- 1、配置proxool連接池監控 -->
<servlet>  
  <servlet-name>Admin</servlet-name>  
  <servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>  
</servlet>  
<servlet-mapping>  
  <servlet-name>Admin</servlet-name>  
  <url-pattern>/admin</url-pattern>  
</servlet-mapping>

<!-- 2、配置受保護域,只有Tomcat管理員才能察看連接池的信息 -->  
<security-constraint>  
  <web-resource-collection>  
      <web-resource-name>proxool</web-resource-name>   
      <url-pattern>/admin</url-pattern>  
  </web-resource-collection>  
  <auth-constraint>  
     <role-name>manager</role-name> 
  </auth-constraint>  
</security-constraint>   
<security-role>  
    <description>The role that is required to log in to the Manager Application</description>   
    <role-name>manager</role-name>   
</security-role>  
<error-page>  
    <error-code>401</error-code>  
    <location>/401.jsp</location>  
</error-page>

在應用啓動後訪問:http://localhost:8080/<web-name>/admin這個url即可監控。

注意:

1、配置proxool連接池監控,僅需<!-- 1、配置proxool連接池監控 -->配置;

2、配置tomcat manager查看連接池信息時,需要在401.jsp頁面中添加如下配置:

<%response.setHeader("WWW-Authenticate", "Basic realm=\"Tomcat Manager Application\"");%>這句話,

否則在訪問/admin察看連接池信息時,會直接跳轉到401.jsp頁面。

4、通過Java API配置連接池,獲取連接池信息;

import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Statement;
import org.logicalcobwebs.proxool.ProxoolException; 
import org.logicalcobwebs.proxool.ProxoolFacade; 
import org.logicalcobwebs.proxool.admin.SnapshotIF; 

public class PoolManager {
    private static int activeCount = 0; 
    public PoolManager(){   } 
    /** 
     * 獲取連接 
     * getConnection 
     * @param name 
     * @return
     */
    public Connection getConnection() { 
        Connection conn = null;
        try{ 
            //proxool驅動類 
            Class.forName("org.logicalcobwebs.proxool.ProxoolDriver"); 
            //此處的dbname是在proxool.xml中配置的連接池別名,當然根據需要可以用dbname2
            conn = DriverManager.getConnection("proxool.dbname"); 
            showSnapshotInfo(); 
        }catch(Exception ex){
            ex.printStackTrace(); 
        } 
        return conn;
    }
           
    /**        
     * 此方法可以得到連接池的信息 
     * showSnapshotInfo 
     */ 
    private void showSnapshotInfo(){           
        try{           
            SnapshotIF snapshot = ProxoolFacade.getSnapshot("dbname", true); 
	    //獲得活動連接數
            int curActiveCount=snapshot.getActiveConnectionCount(); 
            //獲得可得到的連接數
            int availableCount=snapshot.getAvailableConnectionCount(); 
            //獲得總連接數
            int maxCount=snapshot.getMaximumConnectionCount() ; 
            //當活動連接數變化時輸出的信息
            if(curActiveCount!=activeCount) {           
                System.out.println("活動連接數:"+curActiveCount+",(active)可得到的連接數:"+availableCount+",(available)總連接數:"+maxCount+"(max)"); 
                activeCount=curActiveCount; 
            } 
        }catch(ProxoolException e){ 
            e.printStackTrace(); 
        } 
    }
    
    /** 
     * 獲取連接 
     * getConnection 
     * @param name 
     * @return 
     */ 
    public Connection getConnection(String name){ 
        return getConnection(); 
    }

    /** 
     * 釋放連接 
     * freeConnection
     * @param conn 
     */ 
    public void freeConnection(Connection conn){
        if(conn!=null){ 
            try { 
                conn.close(); 
            } catch (SQLException e) { 
                e.printStackTrace(); 
            } 
        } 
    }
   
    /** 
     * 釋放連接 
     * freeConnection 
     * @param name 
     * @param con 
     */          
    public void freeConnection (String name,Connection con){ 
        freeConnection(con); 
    } 
    
    public void getQuery() { 
        try { 
            Connection conn = getConnection(); 
            if(conn != null){ 
                Statement statement = conn.createStatement(); 
                ResultSet rs = statement.executeQuery("select * from Users"); 
                int c = rs.getMetaData().getColumnCount(); 
                while(rs.next()){ 
                    System.out.println(); 
                    for(int i=1;i<=c;i++){ 
                        System.out.print(rs.getObject(i)); 
                    } 
                } 
                rs.close(); 
            } 
            freeConnection(conn); 
        } catch (SQLException e) { 
            e.printStackTrace(); 
        } 
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章