2013-03-28 133 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