Charts and analytical data on the tablet screen with a cup of coffee and a telephone in the background

Twoja aplikacja po godzinach

Czy zastanawiałeś się kiedykolwiek co robi Twoja aplikacja, gdy na nią nie patrzysz? Czy jesteś pewien, że wytworzone przez Ciebie oprogramowanie jest stabilne?

W mojej programistycznej karierze większość czasu spędziłem projektując i wdrażając systemy portalowe. Dziedzina portali jest bardzo specyficzna. Główną cechą charakteryzującą te systemy musi być wysoka wydajność oraz dostępność. Nie można sobie pozwolić na przerwy w działaniu aplikacji. Każda minuta niedostępności serwisu to olbrzymie straty dla Klienta – przede wszystkim utrata odbiorców i czytelników.

Wolno, coraz woooooolnieeej…

Pamiętam jak dziś projekt popularnego portalu informacyjnego o tematyce filmowej. Czas developmentu był trudnym okresem, gdyż wymagania zmieniały się jak w kalejdoskopie i ciężko było zamknąć zakres projektu. Prawdziwe czarne chmury nadeszły w dniu uruchomienia produkcyjnego. Na naszych oczach już w pierwszych minutach portal zaczął „umierać”. Tysiące odsłon serwisu w tym samym momencie wysyciło wszystkie wątki kontenera aplikacji. Możesz sobie wyobrazić nastrój w zespole, napiętą sytuację z Klientem i tysiące oczu wpatrzone w spinner ładowania się strony. Serwery również miały co robić – load serwera 20, całkowicie zużyta pamięć, a praca wentylatorów przypominała suszarkę do włosów. Co robić, jak żyć? Od czego zacząć analizę? Nadszedł czas reaktywacji…

Szybka diagnoza

Gdyby to był mój pierwszy projekt – miałbym poważne kłopoty. Jednak w tym przypadku byliśmy przygotowani na tego typu atrakcje. Z pomocą przyszły nam wszelkiego rodzaju logi aplikacji, timery wykonywania się metod oraz system monitorujący zajętość zasobów (począwszy od przestrzeni dyskowej, poprzez pamięć i procesory, aż do statysyk zaalokowanej pamięci Javy oraz czasu wykonywania się Garbage Collectora). W ruch poszły narzędzia monitoringu i ulubiony zestaw komend linuxowych (less oraz grep). Cóż więc było problemem podczas tej próby wdrożenia? Odpowiedź jest banalna:

  • wolno wykonujące się zapytanie (około 1s) powodowało lawinę wysyceń wątków kontenera aplikacji,
  • źle dobrane przestrzenie Young i Old Generation dla Garbage Collectora.

Bardziej wnikliwy Czytelnik mógłby stwierdzić: Dlaczego więc nie zrobiliście testów wydajnościowych?. Otóż – zrobiliśmy. Niestety, w scenariuszach testowych nie przewidzieliśmy  jednej z pobocznych ścieżek, która była bardzo często wykonywana na produkcji.

Ucz się na cudzych błędach

Droga programistko, drogi programisto – czy masz pewność, że Twoja aplikacja jest responsywna 24/24? Zgodnie ze staropolskim powiedzeniem „Ucz się na cudzych błędach” poniżej zamieszczam kilka porad, które warto wdrożyć już podczas tworzenia oprogramowania:

  1. Logowanie czasu wykonywania się metod – można to wykonać na setki sposobów począwszy od prostych timer’ów i ręcznego wrzucenia do loga, aż do integracji z zewnętrznymi systemami monitoringu (np. Graphana i Graphite).
  2. Ciągły monitoring zasobów sprzętowych oraz samej aplikacji. Tutaj jest szerokie spectrum gotowych do użycia aplikacji, np.: Cacti, Zabbix, etc. Koniecznie należy monitorować użycie procesorów, pamięci, przepustowość łącza oraz przestrzeń dyskową. W monitoring warto włączyć dostępność wątków kontenera aplikacji, dostępność bazy danych jak również samego Reverse Proxy i mnóstwo innych rzeczy, która można spotkać w Twojej aplikacji. Narzędzie monitorujące powinno mieć możliwość przejrzenia wykresów i zebranych danych.
  3. Monitoring webserwisów, z którymi integruje się Twoja aplikacja. Doskonale nadaje się do tego końcówka /health w Spring Boot, która jest wpięta w system monitoringu.
  4. Logowanie czasu wykonywania się zapytań SQL. Nieoptymalnie napisane zapytania (szczególnie, gdy wykorzystujemy ORM) jest jedną z głównych przyczyn awarii systemów! Logowanie tego typu operacji jest wręcz obowiązkowe.
  5. Cykliczne sprawdzanie dostępności aplikacji poprzez wywołanie głównych kontekstów aplikacji i podstawowych scenariuszy testowych (np. narzędzie curl).
  6. Wdrożenie systemu powiadamiania o błędach w aplikacji i problemach sprzętowych (np. alerty w systemie Nagios).
  7. Uruchomienie narzędzia do zbierania i przeglądania logów – tu z pomocą przychodzi magiczne trio ELK (Elastic Search, Log Stash, Kibana).
  8. Włączenie logowania czasu wykonywania się Garbage Collectora.
  9. W pogotowiu powinny być skonfigurowane narzędzia/skrypty umożliwiajce wykonanie Thread Dumpa oraz Heap Dumpa. Warto pokusić się o implementację automatu, który podczas awarii wykonuje Thread Dump, a podczas niedostępności dłuższej niż np. 10 minut – Heap Dump.
  10. Opracowanie procedury działania podczas awarii systemu, najlepiej lista w postaci TODO. Awaria aplikacji jest zawsze stresująca. Spisana procedura pozwoli na sprawną diagnozę przyczyn problemu.

 

Jak dziecko we mgle

W systemach, które utrzymywane są przez naszą firmę zawsze są wpięte systemy monitoringu. Nie wyobrażam sobie pracy i analizy problemów bez statystyk, czy też wykresów. Zebrane dane pozwalają na natychmiastową diagnozę problemu i szybką naprawę niedziałającego serwisu. Gdybym nie miał takich narzędzi czułbym się jak dziecko we mgle a reakcja na problem byłaby zdecydowanie dłuższa. Strzeż się – SLA zobowiązuje 🙂

 

Źródła obrazków:

  1. http://bestwebsitedesignideas.com/500-internal-server-error-design-inspiration.html

About the author

piotr.filipowicz

View all posts