2013-01-02 17 views
18

Analizuję różnice między podejściami do wykonywania zrzutów wątków. Poniżej znajduje się kilka z nich badam naWykonywanie zrzutów wątków w produkcji

  1. Definiowanie fasoli JMX, który wyzwala jstack przez Runtime.exec() na kliknięcie deklarowaną operację Bean.

  2. Wątek demona wykonujący "ManagementFactory.getThreadMXBean(). DumpAllThreads (true, true)" wielokrotnie po zdefiniowanym przedziale.

Porównując wyjścia gwint przegubowe pomiędzy dwoma widzę poniższych wad ze stanowiskiem 2

  1. zrzuty wątku rejestrowane z podejściem 2 nie może być przetwarzany przez open source analizatorów gwint zrzutu jak TDA
  2. Plik wyjściowy nie zawiera natywnego identyfikatora wątku, który może być przydatny w analizowaniu problemów wysokiego cpu (prawda?)
  3. Dosyć?

Byłbym wdzięczny, aby uzyskać sugestie/wejść na

  1. Czy są jakieś wady wykonywania jstack przez Runtime.exec() w kodzie produkcyjnym? wszelkie problemy ze zgodnością w różnych systemach operacyjnych - Windows, Linux?

  2. Jakieś inne podejście do wykonywania zrzutów wątków?

Dziękuję.

Edit -

połączonego stosowania z 1 i 2 wydaje się być droga. Możemy mieć dedykowany wątek działający w tle i drukować zrzuty wątków w pliku dziennika w formacie zrozumiałym dla analizatorów zrzutów wątków. Jeśli są jakieś dodatkowe informacje (np. Prawdopodobnie natywny identyfikator wątku), które są rejestrowane tylko przez wyjście jstack, robimy to ręcznie w razie potrzeby.

+0

Czy jest to związane z aplikacją JEE? –

+0

@WaleedMadanat Tak –

Odpowiedz

29

Można użyć

jstack {pid} > stack-trace.log 

działa jako użytkownik na polu, gdzie proces jest uruchomiony.

Jeśli uruchomisz to wiele razy, możesz użyć diff, aby zobaczyć, które wątki są aktywniejsze.


Do analizy śledzenia stosów używam następujących próbek okresowo w dedykowanym wątku.

Map<Thread, StackTraceElement[]> allStackTraces = Thread.getAllStackTraces(); 

Korzystając z tych informacji, można uzyskać identyfikator wątku, stan pracy i porównać ślady stosu.

+0

Pierwszy punkt wykonywania jstack jest taki sam jak podejście 1, o którym wspomnę powyżej? Integracja i wyzwalanie poprzez jmx pomaga użytkownikowi nie martwić się o identyfikator procesu. Również przy podejściu jmx możemy zaplanować wykonywanie jstack wielokrotnie po każdym określonym interwale. Odnośnie drugiego punktu dotyczącego wywoływania Thread.getAllStackTraces(); oznaczałoby to, że zapisałbym zrzut wątku ręcznie w taki sposób, że zostanie zinterpretowany przez analizatory zrzutu wątku. Jakie jest zalety tego podejścia w stosunku do pierwszego, o którym wspomniałeś? –

+0

Chciałbym mieć analizatory w programie i rejestrować tylko te informacje, które Cię interesują.W moim przypadku dzieje się tak tylko wtedy, gdy mam problem, który zwykle oznacza, że ​​chcę zobaczyć, jakie inne dzienniki występują w czasie, np. o której godzinie wystąpiła, jaka jest ostatnia rzecz, która została zarejestrowana przez wątek i który był później błędem. –

3

Jeśli jest to * nix, powinienem spróbować kill -3 <PID>, ale musisz znać identyfikator procesu, a może nie masz dostępu do konsoli?

+0

Tak. Dostęp do konsoli i uzyskanie identyfikatora procesu to problemy z podejściem "zabij". Podejścia, o których wspomniałem powyżej, nie mają tych wad. –

0

Proponuję wykonanie wszystkich analiz sterty w środowisku pomostowym, jeśli istnieje taki env, a następnie odzwierciedlenie wymaganego dostrojenia serwera aplikacji do produkcji, jeśli istnieje. Jeśli potrzebujesz zrzutów do analizy wykorzystania pamięci aplikacji, to być może powinieneś rozważyć profilowanie go dla lepszej analizy.

Zrzuty sterty są zwykle generowane w wyniku OutOfMemoryExceptions w wyniku wycieków pamięci i nieprawidłowego zarządzania pamięcią.

Sprawdź dokumentację serwera aplikacji, większość współczesnych serwerów ma środki do tworzenia zrzutów w czasie wykonywania, oprócz normalnej przyczyny, o której wspomniałem wcześniej, wynikowy zrzut może być jednak określony przez dostawcę.

+0

Rozumiem narzut związany z uzyskiwaniem zrzutów wątków, ale aby dokładnie zrozumieć, co dzieje się w środowisku produkcyjnym, potrzebujemy tej funkcji. Używamy serwera aplikacji Glassfish, a otrzymanie zrzutów wątku w Glassfish nie jest niczym specjalnym. Musisz wysłać sygnał zabicia do jvm, który ma dwie wady wspomniane w mojej odpowiedzi na @Peter Lljenbery. –

+0

Mam to, to polecam użyć specjalnej kompilacji z włączonym zrzutem pamięci (być może poprzez konfigurację) i ocenić rzeczy do oceny, a następnie wyłączyć po zakończeniu. W ten sposób nie będziesz musiał się martwić o konsekwencje używania jstack lub jakiegokolwiek innego takiego podejścia. Właściwie, jstack byłby OK w tym scenariuszu. Powinieneś również sprawdzić to [link] (http://docs.oracle.com/javase/6/docs/technotes/tools/share/jstack.html), może trochę pomóc (Przewiń do sekcji Opis) . –

+0

Więc sugerujesz podejście 2 z mojego opisu powyżej? Jakie są twoje przemyślenia na temat wad, o których wspomniałem powyżej? Czy są również jakieś problemy z uruchamianiem środowiska runtime.exec() w środowiskach produkcyjnych? –

5

W przypadku Javy 8 na zdjęciu preferowanym rozwiązaniem jest jcmd.

jcmd <PID> Thread.print 

Poniżej znajduje się fragment z Oracle documentation:

Uwolnienie JDK 8 wprowadzono Java Mission Control, Java Flight Recorder i jcmd narzędzia do diagnozowania problemów z aplikacjami Java i JVM. Zaleca się korzystanie z najnowszego narzędzia jcmd zamiast poprzedniego narzędzia jstack w celu udoskonalonej diagnostyki i zmniejszenia narzutu wydajności.

Jednak wysyłka tego wniosku może być implikacją licencji, której nie jestem pewien.

+0

Dobrze wiedzieć. Czy można je analizować za pomocą analizatorów zrzutów wątków open source, takich jak TDA? Czy zawierają natywny identyfikator wątku? –