2013-03-28 10 views
6

Obecnie, jeśli baza danych z naszej wiosennej aplikacji hostowane na Tomcat jest niedostępny, inicjalizacji kontekstu i nie wszystkie wnioski zwróci 404.Handling Wiosna/Tomcat awarie inicjalizacji

Jaki byłby dobry sposób, aby rozwiązać ten problem? Zamiast niedostępności aplikacji do następnego Tomcata, chciałbym, aby wyświetlał użytkownikowi komunikat o błędzie, gdy jest niedostępny i automatycznie odzyskuje dostęp, gdy baza danych jest dostępna (jak gdyby w przypadku awarii bazy danych, gdy Tomcat jest już uruchomiony).

Mogę ustawić wszystkie ziarna do lazy-init, ale nie jestem pewien, czy to najlepsze rozwiązanie? Czy Tomcat nie może powtórzyć inicjalizacji co x sekund/żądań i w międzyczasie wyświetlać przyzwoitą stronę błędu? Jakieś pomysły na ten temat?

Przykładem błędów rzucone na starcie, gdy DB jest niedostępny:

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

Może warto byłoby najpierw skupić się na upewnieniu się, że baza danych jest dostępna/niezawodna ... ale niestandardowe 404 jest całkiem proste: http://stackoverflow.com/questions/1196569/custom-404-using-spring -dispatcherservlet – NimChimpsky

+0

Nie mogę oczekiwać od moich klientów, aby wykonywali swoje aktualizacje Windows dokładnie w odpowiedniej kolejności, a nie w krajobrazie serwera z setkami serwerów, więc czasami serwer bazy danych może być wyłączony po pojawieniu się serwera aplikacji. Niestandardowy 404 nie jest możliwy z podanym linkiem (ponieważ aplikacja nie jest załadowana), mógłbym ustawić niestandardowy 404 w Tomcat, ale to nie rozwiązałoby problemu. To, czego chcę, to Spring/Tomcat, aby spróbować ponownie i postaraj się, aby aplikacja została uruchomiona, zamiast nieudanej próby po 1 próbie. – MikeN

+0

Czy używasz pulingu połączeń dla źródła danych? –

Odpowiedz

1

Od śladu stosu wyjątku widzę, że używasz puli połączeń C3P0. Spójrz na http://www.mchange.com/projects/c3p0/#configuring_recovery, gdzie możesz skonfigurować swoją pulę do ponowienia w celu nawiązania połączenia.

Ale to utrzymywałoby aktywny wątek http i wyobrażałem sobie, że jeśli masz duże obciążenie, twój system ulegnie awarii.

Najlepiej pokazać stronę błędu użytkownikowi. W tym przypadku pokazałbym błąd 503. Możesz to zrobić, umieszczając serwer WWW Apache przed swoim tomcat, w którym hostujesz stronę 503. Mogą istnieć inne sposoby osiągnięcia tego również.

Ponieważ twoja aplikacja nie uruchomi się, nie będzie można wyświetlić strony błędu ze swojej aplikacji internetowej, chyba że skonfigurujesz ją jako leniwą.

Możesz także spróbować automatycznego odświeżania na stronie błędu co X sekund, aby użytkownik adresu URL próbował wejść.

+0

Dzięki, ale nie jest to oczywiście rozwiązanie, którego szukam, ponieważ aplikacja internetowa nigdy nie zacznie działać w ten sposób. – MikeN