2012-07-31 6 views
5

Mamy api, który używa hibernacji jako narzędzia ORM i używamy c3p0 jako funkcji obsługi puli połączeń. Nie mamy problemów, gdy jesteśmy pod obciążeniem. Jednak kończymy na "nie można uzyskać połączenia" wyjątków, gdy interfejs API był nieaktywny przez dzień lub dłużej. Jeśli więc żaden organ nie użyje interfejsu API w ciągu weekendu, otrzymamy błędy połączenia w poniedziałek rano.Czas oczekiwania na połączenie po okresie nieaktywności

Caused by: java.sql.SQLException: An attempt by a client to checkout a Connection has timed out. 

Używamy mysql jako bazy danych. Podczas moich badań dowiedziałem się, że mój serwer bazy danych powoduje, że połączenia są nieaktualne po około 8 godzinach. Może się zdarzyć, że pula połączeń podaje nieaktualne połączenie z klientem, a tym samym wyjątki czasu połączenia dla klienta.

Obecnie nie mamy żadnych testów połączeń skonfigurowanych w C3Po. Powiedzmy, że jeśli użyję IdleTestPeriod do przetestowania połączenia, zanim zostaną one przekazane klientowi przez pulę. Co się stanie, jeśli wszystkie moje połączenia zakończą test w określonym momencie? Czy te nieudane połączenia zostaną usunięte z puli i nowe aktywne połączenia będą generowane ponownie?

Obecnie jest to ustawienie c3p0, którego używamy. Jakiekolwiek inne przyczyny tego problemu?

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> 
     <property name="driverClass" value="${----}"/> 
     <property name="jdbcUrl" value="${----}"/> 
     <property name="user" value="${----}"/> 
     <property name="password" value="${------}"/> 
     <property name="minPoolSize" value="5"/> 
     <property name="acquireIncrement" value="5" /> 
     <property name="maxPoolSize" value="125" /> 
     <property name="maxStatements" value="10" /> 
     <property name="maxIdleTime" value="180" /> 
     <property name="maxIdleTimeExcessConnections" value="30" /> 
     <property name="checkoutTimeout" value="3000" /> 
     <property name="preferredTestQuery" value="SELECT 1" /> 
    </bean> 

Dzięki za pomoc

Odpowiedz

1

W dziale najwyższej dostępności i klastrowania w MySQL Java Connector, spojrzeć na właściwości; w szczególności autoReconnect i autoReconnetForPools. Użyj właściwości w adresie URL połączenia JDBC. Pomogły mi one wcześniej, używając MySQL, Hibernate i C3P0. Mam nadzieję, że to pomaga.

9

Masz kasa w zestawie o wartości 3 s (3000 msek). To wyjątek, który widzisz. Klienci mogą czekać tylko trzy sekundy na pobranie połączenia z puli; jeśli trzy sekundy to za mało, widzą twój wyjątek.

Pytanie brzmi, dlaczego klienci tak długo szukają połączenia? Normalnie sprawdzenie połączenia jest dość szybką operacją. Ale jeśli wszystkie połączenia są wyrejestrowane, klienci muszą czekać na (powolne) pobieranie połączenia z bazy danych.

Masz skonfigurowaną pulę do dość agresywnego usuwania połączeń. Dowolna liczba połączeń powyżej minPoolSize = 5 zostanie zniszczona, jeśli są bezczynne przez więcej niż maxIdleTimeExcessConnections = 30 sekund. Jednak twoja pula jest skonfigurowana dla dużych serii: maxPoolSize = 125. Załóżmy, że aplikacja jest cicha przez jakiś czas, a następnie otrzymuje pakiet żądań połączenia od klientów. Pula szybko zabraknie połączeń i zacznie się pozyskiwać, w seriach nabyciaInspekcji = 5. Ale jeśli nagle jest 25 klientów, a pula ma tylko 5 połączeń, to nie jest nieprawdopodobne, aby 25 klient mógł przerwać pracę przed uzyskaniem połączenia.

Jest wiele rzeczy, które możesz zrobić. Ulepszenia te można rozdzielić, można je łączyć lub dopasowywać według własnego uznania.

1) Bezczynność "nadmiarowa" Połączenia są mniej agresywne, więc ogólnie rzecz biorąc, twoja pula ma zdolność do obsługi wybuchów żądań. Możesz całkowicie upuścić maxIdleTimeExcessConnections i pozwolić Connections powoli dokądś po maxIdleTime = 180 sekundach nieużywania. (Wadą? Większy ślad zasobów na dłużej podczas okresów bezczynności)

2) Ustaw minimalną wartość parametru MinPoolSize, tak aby było mało prawdopodobne, że w puli pojawi się seria działań, dla których ma ona zbyt mało połączeń (w dół ? Większy trwały ślad zasobów.)

3) Upuścić checkoutTimeout ze swojej konfiguracji. Domyślnym ustawieniem c3p0 jest zezwolenie klientom na bezterminowe oczekiwanie na połączenie. (Być może wolisz, aby klienci szybko zgłaszali awarię, zamiast czekać na możliwy sukces.)

Nie sądzę, że problem, który obserwujesz, ma wiele wspólnego z testowaniem połączenia lub limitami czasu MySQL jako takich, ale to nie znaczy, że nie powinieneś zajmować się tymi kwestiami. Odłożę się od porady nobeh dotyczącej problemu ponownego połączenia MySQL. (Nie jestem dużym użytkownikiem MySQL.) Powinieneś rozważyć wdrożenie Testowania połączenia. Masz preferowany testTestQuery, więc testy powinny być dość szybkie. Moim zwykłym wyborem jest użycie testConnectionOnCheckin i idleConnectionTestPeriod. Zobacz http://www.mchange.com/projects/c3p0/#configuring_connection_testing

Powodzenia!