MySql 8小時解決方案:proxool連線池
最近做的專案用的mysql資料庫,前天掛在伺服器上,昨天早晨上班一來,同事就說API資料介面訪問不了了,我馬上mstsc登陸伺服器看,報錯了。馬上重啟tomcat,結果還能正常執行,當時沒管,今天過來又出現相同的問題,錯誤程式碼網上一查,原來是MySql8小時的問題。
MySql8小時問題:
MySQL 的預設設定下,當一個連線的空閒時間超過8小時後,MySQL 就會斷開該連線,而 c3p0 連線池則以為該被斷開的連線依然有效。在這種情況下,如果客戶端程式碼向 c3p0 連線池請求連線的話,連線池就會把已經失效的連線返回給客戶端,客戶端在使用該失效連線的時候即丟擲異常。
解決方案一:
增加 MySQL 的 wait_timeout 屬性的值。
這兩個引數的預設值是8小時(60*60*8=28800)。我測試過將這兩個引數改為0,結果出人意料,系統自動將這個值設定為。換句話說,不能將該值設定為永久。
將這2個引數設定為24小時(60*60*24=604800)即可。 set interactive_timeout=604800; set wait_timeout=604800;總結:可以短時間內解決該問題,但是時間還有有限制,不是完美的解決方案。
解決方案二:
Proxool是一種Java資料庫連線池技術。是sourceforge下的一個開源專案,這個專案提供一個健壯、易用的連線池,最為關鍵的是這個連線池提供監控的功能,方便易用,便於發現連線洩漏的情況。
步驟1:將proxool支援的jar拷貝到專案的WEB-INF/lib目錄中
步驟2:src下建立proxool.xml(跟hibernate相同路徑)
<?xml version="1.0" encoding="UTF-8"?> <something-else-entirely> <proxool> <alias>mysql</alias> <driver-url>jdbc:mysql://localhost:3306/資料庫名</driver-url> <driver-class>com.mysql.jdbc.Driver</driver-class> <driver-properties> <property name="user" value="root" /> <property name="password" value="admin" /> </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> <!--最少保持的空閒連線數(預設2個)--> <prototype-count>5</prototype-count> <!--在使用之前測試--> <test-before-use>true</test-before-use> <!--用於保持連線的測試語句 --> <house-keeping-test-sql>select now()</house-keeping-test-sql> </proxool> </something-else-entirely>
步驟3:Hibernate配置檔案新增proxool連線池
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.provider_class">org.hibernate.connection.ProxoolConnectionProvider</property>
<!-- proxool.xml中對應<alias>mysql</alias>的名稱 -->
<property name="hibernate.proxool.pool_alias">
mysql
</property>
<!-- proxool.xml的路徑,因為在同一目錄下,所以直接填寫proxool.xml(相對路徑) -->
<property name="hibernate.proxool.xml">
proxool.xml
</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="show_sql">true</property>
<mapping resource="com/donen/pojo/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
這樣就可以在hiernate中使用proxool連線池了。不需要更改mysql配置解決8小時問題。
附:proxool連線池使用情況檢視
在web.xml中新增如下內容<servlet>
<servlet-name>dbpoolAdmin</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dbpoolAdmin</servlet-name>
<url-pattern>/dbpool</url-pattern>
</servlet-mapping>
之後訪問http://localhost:埠號/專案名稱/dbpool 即可檢視連線池當前資訊(訪問此頁前至少要訪問一個有對資料庫進行操作的頁面)
附:proxool屬性說明
屬性列表說明:
fatal-sql-exception: 它是一個逗號分割的資訊片段.當一個SQL異常發生時,他的異常資訊將與這個資訊片段進行比較.如果在片段中存在,那麼這個異常將被認為是個致命錯誤(Fatal SQL Exception ).這種情況下,資料庫連線將要被放棄.無論發生什麼,這個異常將會被重擲以提供給消費者.使用者最好自己配置一個不同的異常來丟擲.
fatal-sql-exception-wrapper-class:正如上面所說,你最好配置一個不同的異常來重擲.利用這個屬性,使用者可以包裝SQLException,使他變成另外一個異常.這個異常或者繼承SQLException或者繼承字RuntimeException.proxool自帶了2個實現:'org.logicalcobwebs.proxool.FatalSQLException' 和'org.logicalcobwebs.proxool.FatalRuntimeException' .後者更合適.
house-keeping-sleep-time: house keeper 保留執行緒處於睡眠狀態的最長時間,house keeper 的職責就是檢查各個連線的狀態,並判斷是否需要銷燬或者建立.
house-keeping-test-sql: 如果發現了空閒的資料庫連線.house keeper 將會用這個語句來測試.這個語句最好非常快的被執行.如果沒有定義,測試過程將會被忽略。
injectable-connection-interface: 允許proxool實現被代理的connection物件的方法.
injectable-statement-interface: 允許proxool實現被代理的Statement 物件方法.
injectable-prepared-statement-interface: 允許proxool實現被代理的PreparedStatement 物件方法.
injectable-callable-statement-interface: 允許proxool實現被代理的CallableStatement 物件方法.
jmx: 略
jmx-agent-id: 略
jndi-name: 資料來源的名稱
maximum-active-time: 如果housekeeper 檢測到某個執行緒的活動時間大於這個數值.它將會殺掉這個執行緒.所以確認一下你的伺服器的頻寬.然後定一個合適的值.預設是5分鐘.
maximum-connection-count: 最大的資料庫連線數.
maximum-connection-lifetime: 一個執行緒的最大壽命.
minimum-connection-count: 最小的資料庫連線數
overload-without-refusal-lifetime: 略
prototype-count: 連線池中可用的連線數量.如果當前的連線池中的連線少於這個數值.新的連線將被建立(假設沒有超過最大可用數).例如.我們有3個活動連線2個可用連線,而我們的prototype-count是4,那麼資料庫連線池將試圖建立另外2個連線.這和 minimum-connection-count不同. minimum-connection-count把活動的連線也計算在內.prototype-count 是spare connections 的數量.
recently-started-threshold: 略
simultaneous-build-throttle: 略
statistics: 連線池使用狀況統計。 引數“10s,1m,1d”
statistics-log-level: 日誌統計跟蹤型別。 引數“ERROR”或 “INFO”
test-before-use: 略
test-after-use: 略
trace: 如果為true,那麼每個被執行的SQL語句將會在執行期被log記錄(DEBUG LEVEL).你也可以註冊一個ConnectionListener (參看ProxoolFacade)得到這些資訊.
verbose: 詳細資訊設定。 引數 bool 值