2008-11-06 14 views
11

Mam kilka procesów serwera, które raz na jakiś czas odpowiadają na wiadomości od klientów i wykonują transakcje tylko do odczytu.Dlaczego Hibernate/JDBC/MySQL zrzuca połączenia po upływie dnia?

Po około kilku dniach, gdy serwery działają, przestają działać poprawnie i kiedy sprawdzę, okazuje się, że istnieje cała masa wiadomości o zamknięciu połączenia.

Kiedy to sprawdziłem, okazało się, że domyślnie hibernacja działa w pewnym trybie programowania, w którym połączenia są usuwane po kilku godzinach, a ja zacząłem używać c3po do łączenia połączeń.

Jednak nawet w przypadku c3po pojawia się ten problem około 24 godziny po uruchomieniu serwerów.

Czy ktoś napotkał ten problem i wie, jak go rozwiązać? Nie jestem wystarczająco zaznajomiony z zawiłościami konfiguracji hibernacji.

Odpowiedz

13

Sterownik JDBC MySQL wygasa po 8 godzinach braku aktywności i zrzuca połączenie.

Możesz ustawić autoReconnect=true w adresie URL JDBC, a to spowoduje, że sterownik ponownie się połączy, jeśli spróbujesz wysłać zapytanie po rozłączeniu. Ale to ma skutki uboczne; na przykład stan sesji i transakcje nie mogą być utrzymywane przez nowe połączenie.

Jeśli używasz autoReconnect, połączenie JDBC zostanie ponownie ustanowione, ale nie spowoduje automatycznego ponownego wykonania zapytania, które otrzymało wyjątek. Musisz więc złapać SQLException w swojej aplikacji i ponowić kwerendy.

Przeczytaj http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-configuration-properties.html, aby uzyskać więcej informacji.

+0

Dzięki Bill. Nie martwię się stanem sesji, ponieważ moje sesje są otwierane tylko w razie potrzeby, a następnie zamknięte; trzymanie jednego otwartego przez 8 godzin to i tak chyba zły pomysł. Czy powinienem to skonfigurować w adresie URL JDBL, czy mogę skonfigurować go za pomocą właściwości hibernacji? – Uri

+0

Chciałbym skonfigurować go w adresie URL JDBC. –

+0

Nie zaleca się używania właściwości 'autoReconnect', ponieważ ma ona niepożądane skutki uboczne. Zamiast tego powinieneś rozważyć zwiększenie 'wait_timeout' na serwerze do wysokiej wartości z domyślnej wartości 8 godzin. Odsyłacz: https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-configuration-properties.html – nuaavee

1

Sugerowałbym, że w prawie każdym ustawieniu klient/serwer, nie jest dobrym pomysłem pozostawienie otwartych połączeń, gdy nie są potrzebne.

Mam na myśli w szczególności połączenia DB2/z, ale dotyczy to również wszystkich serwerów (bazy danych i innych). Połączenia te zużywają zasoby na serwerze, które najlepiej można wykorzystać gdzie indziej.

Jeśli miałbyś utrzymywać połączenia otwarte w środowisku korporacyjnym, gdzie dziesiątki tysięcy klientów łączy się z bazą danych, prawdopodobnie przyniosłeśaby nawet komputerowi klatkę na komputer.

Jestem za ideą łączenia połączeń, ale nie za pomysł, aby otworzyć sesje indywidualne na zawsze.

Moja rada będzie w następujący sposób:

1/posiadają trzy rodzaje połączeń w puli połączeń:

  • zamknięte (więc nie faktycznie w basenu).
  • gotowy, czyli otwarty, ale nieużywany przez klienta.
  • aktywne, czyli używane przez klienta.

2/Twoje pulowanie połączeń utrzymuje niewielką liczbę gotowych połączeń, minimalnie N i maksimum M. N może być dostosowywany w zależności od maksymalnej prędkości, z jaką klienci żądają połączeń. Jeśli liczba gotowych połączeń spadnie do zera, potrzebujesz większego N.

3/Gdy klient chce połączenia, daj mu jeden z gotowych (uczynienie go aktywnym), a następnie natychmiast otwórz nowy, jeśli jest teraz mniej niż N gotowy (ale nie każ klientowi czekać na to do ukończenia, lub stracisz przewagę łączenia). Gwarantuje to, że zawsze będzie co najmniej N gotowych połączeń. Jeśli żaden nie jest gotowy, gdy klient go potrzebuje, będą musieli poczekać, aż utworzysz nowy.

4/Gdy klient zakończy połączenie aktywne, należy go przywrócić do stanu gotowości, jeśli jest mniej niż M gotowych połączeń. W przeciwnym razie zamknij. Zapobiega to posiadaniu więcej niż M gotowych połączeń.

5/Okresowe odzyskiwanie gotowych połączeń, aby zapobiec nieaktualnym połączeniom. Jeśli masz więcej niż N gotowych połączeń, po prostu zamknij najstarsze połączenie. W przeciwnym razie zamknij i otwórz ponownie.

Ma to tę zaletę, że wystarczy mieć gotowe gotowe połączenia i w puli połączeń bez przeciążania serwera.

+0

zgadzam się, ale mam również pulę zmniejszać do zera. Jeśli nikt go nie używa, dlaczego ma połączenie? –

+1

Cały punkt pozostawiając otwarte, jeśli chcesz zmniejszyć opóźnienie dla klienta puli połączeń. Nie chcą czekać, dopóki nie ustanowisz nowego. Chociaż można uzyskać pożądany efekt poprzez ustawienie N na zero, tak myślę. – paxdiablo

+0

Mój problem polega na tym, że używam hibernacji. AFAIK Nie kontroluję bezpośrednio połączeń. Czy c3po czy pulpit połączeń czy hibernacja nie powinny być zamykane, gdy są bezczynne? – Uri

7

MySql w zasadzie domyślnie przekroczenia limitu czasu w 8 godzin.

Mam ten sam wyjątek & rozwiązałem problem po 3 gorączkowych dniach. Sprawdź, czy używasz hibernacji3. W tej wersji wymagane jest wyraźne wskazanie nazwy klasy połączenia. Sprawdź również, czy słoik znajduje się w ścieżce klasowej. Sprawdź kroki & komentarze w poniższym linku

http://hibernatedb.blogspot.com/2009/05/automatic-reconnect-from-hibernate-to.html

Usuń autoReconnect=true

1

zmieniłem plik konfiguracyjny hibernacji dodając thoses linii i działa teraz:

<property name="connection.autoReconnect">true</property> 
    <property name="connection.autoReconnectForPools">true</property> 
    <property name="connection.is-connection-validation-required">true</property> 

myślę, że za pomocą C3P0 Basen jest lepszy i polecany, ale to rozwiązanie działa teraz i nie przedstawia problemu z mrówkami.
Pozwoliłem Tomcatowi na 24 godziny i połączenie nie zostało utracone.
Proszę, wypróbuj.

Powiązane problemy