2012-01-23 12 views
7

Mamy do czynienia z nietypowym problemem w naszej aplikacji, w ostatnim miesiącu nasza aplikacja osiągnęła stan niemożliwy do odzyskania, Został odzyskany po restarcie aplikacji.Zrzut wątku pokazujący stan Runnable, ale długo zawieszony

Tło: Nasza aplikacja wykonuje zapytanie DB, aby pobrać pewne informacje, a ta baza danych jest hostowana w oddzielnym węźle.

Problematyczny przypadek: Po przeanalizowaniu zrzutu wątku widzimy, że wszystkie wątki są w stanie uruchomionym pobierając dane z bazy danych, ale nie zakończyły się nawet po 20 minutach.

Po uruchomieniu aplikacji uruchom ponownie zgodnie z oczekiwaniami wszystkie wątki odzyskane. A użycie procesora było również normalne.

Poniżej zrzutu NICI

puli wątków: 2: 47" = 3 prio tid = 0x0000000007334000 NID = 0x5f runnable [0xfffffd7fe9f54000] java.lang.Thread.State: uruchamialny w oracle.jdbc. driver.T2CStatement.t2cParseExecuteDescribe (Native Method) na oracle.jdbc.driver.T2CPreparedStatement.executeForDescribe (T2CPreparedStatement.java:518) na oracle.jdbc.driver.T2CPreparedStatement.executeForRows (T2CPreparedStatement.java:764) w Ora

All threads in the same state. 

Pytania:

  1. , co może być przyczyną tego stanu?
  2. jak odzyskać zgodnie z tym przypadkiem?
+0

można sprawdzić za pomocą gwintu zrzutu analizatora http://mchr3k.github.com/javathreaddumpanalyser/ – GustyWind

+0

Czy kiedykolwiek znaleźć rozwiązanie dla tego? Mam dokładnie ten sam problem, który powtarza się co kilka tygodni/miesięcy. – Kayaman

+0

Jesteś pewien, że fajka się nie gdzieś złamała? –

Odpowiedz

1

Prawdopodobnie oczekuje na dane sieciowe z serwera bazy danych. Wątki Java oczekujące (zablokowane) na I/O są opisane przez JVM jako będące w stanie RUNNABLE, mimo że z punktu widzenia programu są zablokowane.

0

Metody macierzyste pozostają zawsze w stanie RUNNABLE (ok, chyba że zmienisz stan z natywnej metody, sam, ale to się nie liczy).

Metoda może zostać zablokowana na IO, każde inne zdarzenie czekające lub po prostu długie zadanie intensywne procesora ... lub nieskończona pętla. Możesz dokonać własnego wyboru.

jak odzyskać na podstawie tej sprawy?

upuścić połączenie z oracle.

1

Jak już wspomniano, natywne metody są zawsze w fazie uruchamiania, ponieważ JVM ich nie zna/nie obchodzi.

Sterowniki Oracle po stronie klienta domyślnie nie mają limitu czasu gniazda. Oznacza to, że jeśli masz problemy z siecią, gniazdo niskiego poziomu klienta może "utknąć" tam na zawsze, co spowoduje maksymalną pulę połączeń. Można również sprawdzić ruch sieciowy w kierunku serwera Oracle, aby sprawdzić, czy przesyła on dane, czy nie.

Podczas korzystania z cienkiego klienta można ustawić oracle.jdbc.ReadTimeout, ale nie wiem, jak to zrobić dla grubego klienta (oci), którego nie znam.

Co robić? Dowiedz się, jak określić czas oczekiwania na gruby sterownik ojdbc i sprawdź wyjątki związane z przekroczeniem czasu połączenia, które wyraźnie zasygnalizują problemy z siecią. Jeśli możesz zmienić źródło, możesz owijać połączenia i ponawiać próbę sesji, gdy zaczniesz wychwytywać limity czasu związane z limitem czasu SQLEx.

Aby szybko rozwiązać problem, ręcznie zakończ połączenie na serwerze Oracle.

Warto sprawdzić rywalizację sesji, może zapytanie blokuje te sesje. Jeśli ją znajdziesz, zobaczysz, który obiekt bazy danych powoduje problem.

0

Czy zawieszenie systemu lub maszyny JVM? Jeśli jest to konfigurowalne i jeśli to możliwe, zmniejsz liczbę połączeń wątków/równoległych.

Wątek po prostu marnuje cykle procesora podczas oczekiwania na IO. Tak, twój procesor jest niestety zajęty wątkami, które oczekują na odpowiedź z DB.

0
  1. Czy Twój kod ręcznie obsługuje transakcję? Jeśli tak, być może niektóre z kodu nie commit() po zmianie danych. A może ktoś uruchomił kwerendę do modyfikacji danych bezpośrednio przez PLSQL lub coś takiego i nie popełnił, a to prowadzi do zawieszenia wszystkich operacji czytania.

  2. Kiedy doświadczyłeś "zawieszenia", a DB odzyskał status, czy sprawdziłeś dane, jeśli niektóre z nich zostały wycofane? Pytasz o to, ponieważ powiedziałeś "Został odzyskany po restarcie aplikacji.". Dzieje się tak, gdy sterownik JDBC zmienił dane, ale nie zatwierdził, i nastąpiło przekroczenie limitu czasu ... Operacja DB zostanie wycofana. (Może być różny w zależności od konfiguracji chociaż)