我有一個在EC2上的GlassFish上運行的Java EE應用程序,在Amazon RDS上有一個MySQL數據庫。 我正在嘗試配置JDBC連接池以最大限度地減少數據庫故障轉移時的停機時間。配置GlassFish JDBC連接池以處理Amazon RDS多可用區故障轉移
我的當前配置在多可用區故障轉移期間無法正常工作,因爲備用數據庫實例在幾分鐘內(根據AWS控制檯)可用,而我的GlassFish實例長時間卡住(約15分鐘)才能恢復工作。
連接池配置是這樣的:
asadmin create-jdbc-connection-pool --restype javax.sql.ConnectionPoolDataSource \
--datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource \
--isconnectvalidatereq=true --validateatmostonceperiod=60 --validationmethod=auto-commit \
--property user=$DBUSER:password=$DBPASS:databaseName=$DBNAME:serverName=$DBHOST:port=$DBPORT \
MyPool
如果我使用一個單AZ db.m1.small實例和重啓從控制檯數據庫,GlassFish的將無效斷開的連接,拋出一些異常,然後在數據庫可用時立即重新連接。在此設置中,我可以獲得不到1分鐘的停機時間。
如果我使用一個多AZ db.m1.small實例,並重啓從AWS控制檯故障,我看不出有什麼異常的。服務器完全停止,所有傳入的請求都會超時。 15分鐘後,我終於得到這個:
Communication failure detected when attempting to perform read query outside of a transaction. Attempting to retry query. Error was: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 940,715 milliseconds ago. The last packet sent successfully to the server was 935,598 milliseconds ago.
,就像每個HTTP線程阻塞得到一個無效的連接上沒有得到一個異常,所以沒有機會進行連接驗證時出現。
多可用區域案例中的停機時間總是在15-16分鐘之間,所以它看起來像某種類型的超時,但我無法更改它。
事情我已經嘗試沒有成功:
- 連接泄漏超時/收回
- 語句泄漏超時/使用不同的驗證方法
- 使用
MysqlDataSource
回收 - 聲明超時
- 代替
MysqlConnectionPoolDataSource
如何設置停滯查詢的超時時間,以便重新使用,驗證和替換池中的連接? 或者我如何讓GlassFish檢測到數據庫故障轉移?
你能解決這個問題嗎? – hectorg87
@ hectorg87不是。我發現如果我設置更多的HTTP線程,服務器將創建與數據庫的新連接,並在數據庫可用時立即恢復。但是,舊連接仍會阻塞15分鐘,如果數據庫連接池耗盡,此設置將中斷。 – Andrea
該死!我有這樣的假設:它與池本身無關,並與Java的DNS緩存有關。它正在緩存舊數據庫的IP地址,並且在故障轉移完成後從不更改爲新數據庫。只要我禁用Java的DNS緩存,我就會通知你。也許我會回答你的問題:-) – hectorg87