2013-03-28 130 views
6

目前,如果我們的春天應用程序託管在Tomcat的數據庫是不可用的,上下文初始化失敗,所有的請求返回404處理Spring/Tomcat的初始化失敗

什麼是解決這個問題的好辦法?除非應用程序在下一個Tomcat之前不可用,否則我希望它在不可用時向用戶顯示錯誤消息,並在數據庫可用時自動恢復(例如,如果Tomcat已在運行時發生數據庫故障)。

我可以將所有bean設置爲lazy-init,但我不確定這是最佳解決方案嗎? Tomcat無法每隔x秒/請求重試初始化並同時顯示一個體面的錯誤頁面?對此有何想法?

在啓動時拋出的DB不可用錯誤的例子:

Caused by: java.sql.SQLException: Connections could not be acquired from the underlying database! 
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:106) 
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:529) 
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128) 
at org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy$LazyConnectionInvocationHandler.getTargetConnection(LazyConnectionDataSourceProxy.java:401) 
at org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy$LazyConnectionInvocationHandler.invoke(LazyConnectionDataSourceProxy.java:376) 
at com.sun.proxy.$Proxy43.getMetaData(Unknown Source) 
at com.googlecode.flyway.core.dbsupport.DbSupportFactory.getDatabaseProductName(DbSupportFactory.java:103) 
... 67 more 
Caused by: com.mchange.v2.resourcepool.CannotAcquireResourceException: A ResourcePool could not acquire a resource from its primary factory or source. 
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1319) 
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557) 
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477) 
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525) 
... 72 more 
Mar 28, 2013 11:19:47 AM org.apache.catalina.core.StandardContext startInternal 
SEVERE: Error listenerStart 
Mar 28, 2013 11:19:47 AM org.apache.catalina.core.StandardContext startInternal 
SEVERE: Context [] startup failed due to previous errors 
+0

也許這是明智的重點確保您的數據庫是可用/可靠的第一...但一個自定義的404很簡單:http://stackoverflow.com/questions/1196569/custom-404-using-spring -dispatcherservlet – NimChimpsky 2013-03-28 12:34:38

+0

我不能指望我的客戶按照正確的順序執行Windows更新,而不是在具有數百臺服務器的服務器環境中執行其更新,所以有時候應用程序服務器啓動時DB服務器可能會關閉。自定義404是不可能的,因爲你給的鏈接(因爲web應用程序沒有加載),我可以在Tomcat中設置一個自定義的404,但這並不能解決問題。我想要的是Spring/Tomcat重試並盡力讓應用程序升級,而不是在嘗試一次後失敗。 – MikeN 2013-03-28 15:49:16

+0

您是否在使用數據源的連接池? – 2013-04-01 06:17:03

回答

1

從異常堆棧跟蹤我看到你正在使用c3p0連接。查看http://www.mchange.com/projects/c3p0/#configuring_recovery,您可以在其中配置池以重試連接。

但是,這將保持http線程活躍,並想象如果你有高負載,你的系統會下降。

最好向用戶顯示錯誤頁面。在這種情況下,我會顯示503錯誤。您可以通過將Apache Web服務器放在您承載503頁面的tomcat前面來完成此操作。還有其他方法可以實現這一點。

由於您的web應用程序本身不會啓動,您不能從web應用程序提供錯誤頁面,除非您將其配置爲延遲初始化。

您也可以嘗試每隔X秒爲URL用戶試圖訪問的錯誤頁面上的自動刷新。

+0

謝謝,但這當然不是我正在尋找的解決方案,因爲Web應用程序永遠不會以這種方式啓動。 – MikeN 2013-04-03 09:10:53