2013-05-02 7 views
5

Mam sporadyczne problemy z serwerem, który napisałem. Jest w Clojure, ale nie sądzę, żeby to miało znaczenie, i możemy udawać, że jest w Javie. W każdym razie działa to dobrze przez wiele godzin, ale trafia w miejsca, gdzie zachowuje się bardzo źle: cała aktywność zatrzymuje się na około piętnaście sekund, a następnie działa normalnie przez kilka sekund, a następnie zatrzymuje się na piętnaście sekund ... i tak na około (zwykle) około dziesięciu minut, po czym wraca do normalnego zachowania.Jak mogę debugować serwer, który nie odpowiada, gdy profiler nie może zbierać próbek?

Robiłem dużo profilowania go z YourKit, a ja wykluczyć szereg prawdopodobnych podejrzanych:

  • To nie jest kwestia zbierania śmieci: biegnę go -XX:+UseConcMarkSweepGC i zweryfikowałem, że serwer działa dobrze podczas zarówno niewielkich, jak i dużych kolekcji, ze względu na współbieżny charakter tego garbage collectora. Nie tracimy czasu na wyczerpywanie się pamięci lub czegoś w tym rodzaju: obecny rozmiar sterty jest znacznie niższy niż maksymalna.

  • Nie sądzę, że to kwestia blokowania/synchronizacji, ale nie jestem w 100% pewny. Profiler YourKit pokazuje czasami oczekujące wątki, np. Konkurowanie o blokadę dla System.out w celu generowania komunikatów dziennika, ale jedyne długie oczekiwania dotyczą wątków roboczych w wątkach, gdy nie ma nic do zrobienia. I oczywiście YourKit twierdzi, że nigdy nie wykryto żadnych zakleszczeń.

  • Nie jest to spowodowane przez dołączenie profilera, ponieważ nadal ma miejsce, nawet jeśli uruchomię serwer, a następnie pozostawię go w spokoju, nigdy nie dołączając profilera.

  • To nie jest jakiś inny proces w systemie zajmujący cały czas procesora: top pokazuje użycie procesora na poziomie 100% dla mojego procesu java i zasadniczo 0% dla wszystkiego innego.

Moim największym problemem jest to, że nie mogę zobaczyć, co serwer jest robi podczas tych dziwnych Funks, ponieważ profiler zatrzymuje otrzymujących próbki. Oto wykres wykresie użytkowania CPU:

YourKit CPU-graph screenshot

Po lewej stronie wykresu jest normalna praca, podczas której możemy uzyskać próbki Profiler co drugi lub tak. Prawa strona jest "zepsuta" i jest bardzo spiczasta, ponieważ profiler pobiera próbki tylko co dziesięć sekund. W próbkach, które robi, serwer wydaje się wykonywać swoją zwykłą działalność: reagowanie na żądania i tak dalej; a logi potwierdzają, że robi normalne rzeczy, ale tylko wtedy, gdy profiler ma próbki dla: podczas pochyłych ku górze "prostych linii" na wykresie, dla których profiler nie ma próbek, serwer nic nie robi .

Czy ten wykres jest dobrze znany każdemu? Czy miałeś już ten problem i naprawiłeś go? Czy możesz wskazać mi kierunek działania narzędzia, które może dowiedzieć się, co robi mój serwer w czasie, gdy YourKit nie może? W przypadku, jest to ważne, urządzenie serwer działa Ubuntu 10.04 i

$ java -version 
java version "1.6.0_22" 
OpenJDK Runtime Environment (IcedTea6 1.10.10) (rhel-1.28.1.10.10.el5_8-x86_64) 
OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode) 
+0

Może to być gigantyczny ból w dupie, ale można jednak rejestrowanie debugowania wszystko w całym kodzie, a następnie zobaczyć, co jest wpisywane do dziennika. Inną możliwością jest to, że problem nie jest twoim programem java, ale w rzeczywistości inną pracą na serwerze, która zjada wszystkie zasoby przez 10 minut. – durron597

+0

Co jest potrzebne, aby pobrać próbkę * * (** to ** jeden ** (1)) (http://stackoverflow.com/a/378024/23771) po jej zawieszeniu, a następnie sprawdzić i zrozumieć. Tu nie chodzi o pomiar - chodzi o "dlaczego jest zawieszony?" Oczywiście, jak powiedział durron597, może to nie być twój kod błędu, więc możesz potrzebować próbki ze wszystkich wątków. –

+0

To dobrze, @durron, ale nic ciekawego nie działa na tym komputerze, a 'top' pokazuje proces java używający 100% procesora podczas" smutnych czasów ". Zmienię to na pytanie. I już mam sporo rejestrowania, jak już wspomniałem: żadna z nich nie dzieje się, gdy serwer utknął. – amalloy

Odpowiedz

2

Ok, z uwagi wydaje się dla mnie jasne, że nie będą mogli dowiedzieć się tego z informacjami Dałaś tak daleko. Najlepsze, co możemy zrobić, to podać sugestie dotyczące debugowania ...

Chciałbym spróbować użyć jstack podczas jednego z impulsów i sprawdzić, czy można go użyć, aby dowiedzieć się, gdzie wisi.

+0

Nie używałem jstack wcześniej - czy mówi ci więcej niż zwykły zrzut wątku? – Alex

+0

@Alex tak, to prawda. Przeczytaj dokumentację – durron597

+0

Cóż, pytał specjalnie o sugestie dotyczące debugowania go. – Rayne

0

Jeśli nie masz szansy na pomiar lub debugowanie w kodzie, spróbuj wyglądać z zewnątrz.

Początkowo próbowałbym odtworzyć problem. Innymi słowy, istnieje zewnętrzne wydarzenie, które wywołuje takie zachowanie. Spróbuj zmienić obciążenie serwera. Przełącz wszystko, co możliwe, aby odtworzyć problem.

Może to również dobry pomysł, aby powąchać ruch sieciowy (tcpdump), aby znaleźć coś interesującego w czasie, gdy serwer się zawiesi.

Można również uruchomić go na innym systemie operacyjnym, aby sprawdzić, czy zależy on od środowiska instalacji.

Jeśli nie możesz odtworzyć sytuacji, w której występuje problem, spróbuj znaleźć sytuacje, w których problem nie występuje. Na przykład usuń serwer z sieci. Zamknij wszystkie pozostałe usługi.

Jeśli nie możesz znaleźć tej zmiany w swoim programie, spróbuj zmniejszyć złożoność kodu i sprawdź, czy możesz znaleźć wewnętrzny moduł, który wydaje się być powiązany z problemem.

0

Masz już ten problem i go naprawiłeś? Czy możesz wskazać mi w kierunku narzędzia, które może dowiedzieć się, co mój serwer robi w czasie, gdy YourKit nie może?

Jeśli masz dostęp do powłoki na serwerze i możesz zobaczyć standardowe wyjście, spróbuj wykonać zrzut wątku, gdy serwer przestanie odpowiadać. Nie jestem pewien, czy da ci to coś innego niż to, co dałoby ci jstack (wspomniane w innej odpowiedzi).

Na Ubuntu: kill -QUIT <java-pid> (faktycznie nie zabije procesu Java).

http://www.crazysquirrel.com/computing/java/basics/java-thread-dump.jspx

Powiązane problemy