2017-02-02 18 views
5

różnych powodów połączeń w puli mogą stać się nieprawidłowy: limit czasu połączenia z serwerem, zagadnień sieciowych ...Tomcat JDBC Basen: testOnBorrow vs testWhileIdle

moim rozumieniu jest to, że gra Bilard Tomcat JDBC nie daje żadnej gwarancji na temat ważność połączeń, które zapewnia aplikacji.

Aby zapobiec (właściwie zmniejszyć ryzyko) uzyskanie nieprawidłowego połączenia z puli, rozwiązaniem wydaje się konfiguracja sprawdzania poprawności połączeń. Sprawdzanie poprawności połączenia oznacza uruchamianie bardzo podstawowego zapytania w bazie danych (na przykład SELECT 1; w MySQL).

Pula połączeń JDBC Tomcata oferuje kilka opcji testowania połączenia. Dwa, które uważam za bardziej interesujące to testOnBorrow i testWhileIdle.

Najpierw pomyślałem, że najlepsza jest opcja testOnBorrow, ponieważ zasadniczo sprawdza połączenie przed dostarczeniem go do aplikacji (z maksymalną częstotliwością zdefiniowaną przez validationInterval).

Ale po chwili zdałem sobie sprawę, że testowanie połączenia tuż przed jego użyciem może wpłynąć na szybkość reakcji aplikacji. Więc uważam, że używanie testWhileIdle może być bardziej wydajne, ponieważ testuje połączenia, gdy nie są używane.

Bez względu na to, którą opcję wybiorę, wydaje się, że zmniejsza ona tylko ryzyko uzyskania nieprawidłowego połączenia, ale ryzyko to nadal istnieje.

W efekcie pytam: czy powinienem użyć testOnBorrow lub testWhileIdle, czy też kombinacji obu?

Na marginesie, jestem zaskoczony, że validationInterval nie ma zastosowania do testOnReturn i naprawdę nie mam celu testOnConnect.

Odpowiedz

4

Nie ma 100% słusznej odpowiedzi na to pytanie. Jest to kwestia kompromisu i kontekstu.

  • Większość czasu, testOnBorrow jest co najmniej ryzykowne, ponieważ zapewnia ona (najlepiej jak to możliwe), że zanim połączenie zostanie zwrócony z puli dla swojego użytku, podstawowa kontrola poprawności został wykonany, że klient i db-serwer są na rozmowach.
  • Nadal nie zapobiega to awarii stanu wyścigu połączenia z serwerem, między czasem "sprawdzenie stanu sprawności" wykonano & czasu, w którym aplikacja korzystała z połączenia.
  • Ale biorąc pod uwagę to jako przypadku narożnego, testOnBorrow daje całkiem dobre zapewnienie.

  • Teraz kompromis polega na tym, że za każdym razem, gdy żądasz połączenia, zapytanie (bez względu na lekkość) jest wysyłane do serwera bazy danych. Może to bardzo szybko, ale koszt nadal nie jest zerowy.

A jeśli masz zajęty aplikację, z bardzo dobrej bazy połączenie niezawodności, wtedy zaczniesz widzieć z danymi, że koszt „check ważności na każdym połączeniu-żądanie z puli” przewyższają korzyści wynikające z wykrywania problemów z połączeniem.

  • Z drugiej strony, jeśli aplikacja nie jest jednolicie zajęty (jak większość aplikacji w rzeczywistym świecie), to jest bardzo korzystne mieć opcję testOnBorrow.
  • Gwarantuje to maksymalnie dobre połączenie przed użyciem. Zwłaszcza biorąc pod uwagę koszt (ponowienie + ręczna interwencja + utrata przepływu pracy itp.) "Braku możliwości łatwego odzyskania" z nieudanej operacji DB.

  • Teraz wyobraź sobie, jeśli masz opcję testOnIdle. Wymaga to, aby połączenia były bezczynne (w zależności od bezczynności limitu czasu połączenia), zanim możliwe będzie sprawdzenie poprawności.

  • To jest poprawa wydajności w stosunku do testOnBorrow, ale ma on swoje wady.
    • świecie rzeczywistym app-do-db-połączenia są nie tylko idle-timeout oparte na stłuczeniu, mogą zostać usunięte na podstawie reguł zapory, n/w zatorów, konserwacji db-server-poddawanych/łatanie itp
    • Wracamy więc do pomiaru danych dotyczących liczby błędów połączenia w danych, kiedy nie mieliśmy żadnego "sprawdzania połączenia".
  • I jedno trzeba uważać z tą opcją jest, gdy masz swój basen działa najlepiej z połączeniami Max i aplikacja wykonywania dobrze, a jeśli z jakiegoś powodu Twój db-serwer ulega restart lub podobnie. Wszystkie połączenia na żywo (z punktu widzenia klienta) będą teraz głównie powodować błędy, aż do momentu, gdy przestaną działać limity czasu bezczynności. Tak więc twój problem z db (który byłby walką ogniową) jest teraz nieco większy, aż połączenia aplikacji znów się poprawią lub zrestartujesz aplikację.

I ostatni punkt danych jest taki, że w przypadku niektórych aplikacji ścieżka krytyczna nie jest czasem "zapytania sprawdzającego" (miejmy nadzieję, że w mniejszym młynie). Aplikacje mają większe problemy do rozwiązania. I oczywiście, dla niektórych aplikacji, ten czas jest bardzo znaczący.

1

Poinformowałem Cię, że właśnie przetestowałem to i możliwe jest użycie obu właściwości: testOnBorrow i testOnIdle.

Jak wspomniano powyżej, będę jednak decydować się na testOnBorrow wyjątkowo ze względu na fakt, że moja aplikacja nie jest pod dużym natężeniem ruchu i może sobie pozwolić na sprawdzenie połączenia przed jego przejęciem.

Jak wskazano w komentarzach, testOnBorrow nie wymaga kwerendy weryfikacji. Jeśli zdecydujesz się trzymać jednego może to być prosty wybór:

jdbc.hive.testOnBorrow=true 
jdbc.hive.validationQuery=SELECT 1 

Jeśli chcesz korzystać testWhileIdle, można użyć następujący:

jdbc.testWhileIdle=true 
jdbc.minEvictableIdleTimeMillis=1800000 
jdbc.timeBetweenEvictionRunsMillis=1800000` 

Więcej informacji na temat DCHP: https://commons.apache.org/proper/commons-dbcp/configuration.html

+0

Rzeczywiście zapytanie o weryfikację nie jest obowiązkowe. Metoda isValid jest używana w połączeniu, jeśli zapytanie dotyczące sprawdzania poprawności nie zostało dostarczone. Myślę, że dobrym pomysłem jest pozostawienie sprawdzania poprawności połączenia dla sterownika JDBC. –

+0

Och, wydaje się, że masz rację. Po prostu przeczytaj dokumentację. Dokona edycji wpisu. – UltimaWeapon

Powiązane problemy