7 technik debugowania przyspieszających rozwiązywanie problemów w produkcji
Opublikowany: 2022-03-11Zapewnienie wsparcia produkcyjnego aplikacji jest jednym z najtrudniejszych aspektów tworzenia oprogramowania. Deweloperzy są przypisani do zespołu utrzymania ruchu i pracują nad poprawkami błędów w aplikacji. Są jednak również dostępne na wezwanie w przypadku przestoju w produkcji, w którym to przypadku pracują, aby jak najszybciej przywrócić działanie aplikacji.
Ten artykuł ma na celu dostarczenie zestawu wyselekcjonowanych rekomendacji, aby można było zapobiegać błędom w środowisku produkcyjnym i znacznie szybciej znajdować problemy. Obsługa tych aplikacji w środowisku produkcyjnym jest skomplikowanym zadaniem: często nie ma dostępnej dokumentacji, aplikacja została napisana w starszym stosie technologicznym lub jedno i drugie. Istnieje bardzo niewiele sesji szkoleniowych i często jest się wezwanym, aby zapewnić wsparcie dla aplikacji, o której niewiele wiesz.
Wielu programistów nie ma doświadczenia w obsłudze aplikacji w środowisku produkcyjnym. Istnieje szereg problemów występujących w środowiskach produkcyjnych, które powodują błędy i przestoje, na ogół powodując utratę tysięcy, a czasem milionów dolarów w firmie. Co więcej, ponieważ większość programistów nie ma kontaktu ze środowiskiem, popełniają błędy, które z kolei spowodują te problemy. Ta lista wskazówek powinna sprawić, że Twoja praca będzie mniej bolesna dzięki nauczaniu z doświadczenia produkcyjnego.
Wskazówka 1: Usuń lub zautomatyzuj całą konfigurację potrzebną do uruchomienia aplikacji.
Jaka konfiguracja jest wymagana do zainstalowania oprogramowania na nowym serwerze? W przeszłości za każdym razem, gdy w zespole pojawiał się nowy programista, ukończenie tego mogło czasami zająć trzy dni. Instalacja aplikacji wymagałaby wielu kroków, które należy wykonać ręcznie. Z biegiem czasu oprogramowanie ewoluuje do nowych wersji, które stają się niezgodne z tymi instrukcjami i oczywiście instrukcje zwykle nie są aktualizowane. Nagle tracisz o wiele więcej czasu niż to konieczne, aby po prostu uruchomić aplikację.
Wraz z pojawieniem się konteneryzacji znacznie łatwiej stało się zapewnienie sposobu na błyskawiczne uruchomienie aplikacji, przy zerowej konfiguracji i z dodatkową korzyścią polegającą na tym, że ponieważ obraz Dockera jest samowystarczalny, można uruchomić znacznie niższy ryzyko napotkania problemów z różnymi wersjami systemu operacyjnego, używanymi językami i frameworkami.
Podobnie uprość konfigurację programisty, dzięki czemu uruchomienie i uruchomienie nie zajmie dużo czasu, w tym konfiguracja IDE. Deweloper powinien być w stanie przejść od zera do bohatera w mniej niż 30 minut.
Kiedy pojawia się problem z produkcją, czasami Twoi najlepsi eksperci mogą być niedostępni (np. urlop lub choroba) i chcesz, aby osoba, którą rzucisz na problem, mogła go rozwiązać i szybko.
Porada 2: Nie wpadnij w pułapkę zupy stosu technologii.
Im mniej używanych technologii, tym lepiej. Oczywiście czasami trzeba użyć odpowiedniego narzędzia do pracy. Uważaj jednak, aby nie przeciążać „właściwych narzędzi”. Nawet picie wody może spowodować poważne problemy zdrowotne, jeśli robisz to za dużo. Każdy nowy język i framework dodany do stosu technologicznego musi przejść przez jasno określony proces decyzyjny z uważnym rozważeniem skutków.
- Nie dodawaj nowej zależności frameworka tylko dlatego, że potrzebujesz klasy
StringUtils
. - Nie dodawaj zupełnie nowego języka tylko dlatego, że musisz napisać szybki skrypt do przenoszenia plików.
Duży stos zależności może uprzykrzyć ci życie, gdy biblioteki staną się niekompatybilne lub gdy zostaną znalezione zagrożenia bezpieczeństwa, albo w samych frameworkach, albo w ich przechodnich zależnościach.
Co więcej, pamiętaj, że dodatkowa złożoność stosu utrudnia znalezienie i wyszkolenie nowych programistów dla zespołu. Ludzie przechodzą na nowe stanowiska w innych firmach, a ty musisz znaleźć nowe. Obroty w zespołach inżynierskich są bardzo wysokie, nawet w firmach, które cieszą się uznaniem ze świetnych przywilejów i przysmaków zapewniających równowagę między życiem zawodowym a prywatnym. Chcesz jak najszybciej znaleźć nowego członka zespołu. Każda nowa technologia dodana do stosu technologii wydłuża czas na znalezienie nowego kandydata i może sprawić, że nowe osoby będą coraz droższe.
Porada 3: Rejestrowanie musi pomóc w znalezieniu problemu, a nie zagłuszać bezużytecznymi szczegółami.
Logowanie jest bardzo podobne do komentarzy. Konieczne jest udokumentowanie wszystkich podejmowanych krytycznych decyzji oraz wszystkich informacji do wykorzystania w technikach debugowania. Nie jest to proste, ale przy odrobinie doświadczenia można nakreślić kilka możliwych scenariuszy przerw w produkcji, a następnie wprowadzić niezbędne logowanie, aby przynajmniej rozwiązać ten problem. Oczywiście rejestrowanie ewoluuje wraz z bazą kodu w zależności od rodzaju pojawiających się problemów. Ogólnie rzecz biorąc, 80% logowań powinieneś poświęcić na najważniejsze 20% kodu — część, która będzie używana najczęściej. Ważnymi informacjami są na przykład wartości argumentów przekazanych do metody, typy środowiska wykonawczego z klas dzieci i ważne decyzje podjęte przez oprogramowanie — czyli czas, w którym znajdowało się na rozdrożu i wybrało lewą lub prawą stronę.

Porada 4: Radź sobie z nieoczekiwanymi sytuacjami.
Przedstaw bardzo jasno, jakie są założenia kodu. Jeśli dana zmienna powinna zawsze zawierać wartości 2, 5 lub 7, upewnij się, że jest typu enum, a nie int. Źródłem numer jeden dużych przestojów w produkcji jest zawodność pewnego założenia. Każdy szuka problemu w niewłaściwym miejscu, ponieważ kilka rzeczy uważa za pewnik.
Założenia powinny być wyraźnie udokumentowane, a wszelkie niepowodzenia w tych założeniach powinny wzbudzić wystarczającą liczbę alarmów, aby zespół wsparcia produkcji mógł szybko naprawić sytuację. Powinien również istnieć kod zapobiegający przejściu danych w nieprawidłowy stan, a przynajmniej tworzący jakiś rodzaj alertu w takim przypadku. Jeśli pewne informacje mają być przechowywane w jednym rekordzie, a nagle są dwa rekordy, należy wystrzelić ostrzeżenie.
Porada 5: Odtworzenie problemu, który ma miejsce u klienta, powinno być proste.
Jednym z najtrudniejszych kroków jest zawsze odtworzenie problemu, z którym zmaga się klient. Wiele razy spędzisz 95% czasu próbując zreplikować problem, a gdy tylko będziesz mógł go zreplikować, poprawka, test i wdrożenie to kwestia minut. W związku z tym architekt aplikacji powinien upewnić się, że replikowanie problemów jest niezwykle proste i szybkie. Dzieje się tak dlatego, że aby dostać się do tej samej sytuacji, w której znajduje się klient, programista musi wykonać znaczną ilość konfiguracji aplikacji. Istnieje wiele przechowywanych zapisów, które razem pogarszają sytuację, w której znajduje się klient – problem polega na tym, że jako programista musisz dokładnie odgadnąć, co zrobił klient. A czasami wykonywali sekwencję kroków, z których pamiętają tylko ostatni.
Ponadto klient wyjaśni sprawę w kategoriach biznesowych, które deweloper musi następnie przełożyć na terminy techniczne. A jeśli programista ma mniejsze doświadczenie z aplikacją, nie będzie wiedział, aby poprosić o brakujące szczegóły, ponieważ nawet nie zna jeszcze brakujących szczegółów. Kopiowanie całej produkcyjnej bazy danych na maszynę jest niewykonalne. Powinno więc istnieć narzędzie do szybkiego importu z produkcyjnej bazy danych tylko kilku rekordów niezbędnych do symulacji sytuacji.
Załóżmy, że klient ma problem z ekranem Zamówienia. Być może będziesz musiał zaimportować kilka ich zamówień, rekord klienta, niektóre rekordy szczegółów zamówienia, rekordy konfiguracji zamówienia itp. Następnie możesz wyeksportować to do bazy danych w instancji Docker, uruchomić tę instancję i po prostu widząc to samo, co widzi klient. Wszystko to oczywiście powinno być wykonane z należytą starannością, aby żaden programista nie miał dostępu do poufnych danych.
Porada #6: Powinno być oczywiste, gdzie w aplikacji umieścić punkty przerwania.
Jeśli masz ekran Customer, powinien znajdować się obiekt Customer, w którym możesz umieścić punkty przerwania w celu debugowania problemu na tym ekranie. Czasami programiści wpadają w gorączkę abstrakcji i wymyślają niewiarygodnie inteligentne koncepcje, jak radzić sobie ze zdarzeniami interfejsu użytkownika. Zamiast tego powinniśmy zawsze polegać na zasadzie KISS (Keep it Simple, St— er, Silly) i mieć jedną łatwo zlokalizowaną metodę na zdarzenie interfejsu użytkownika. Podobnie w przypadku zadań przetwarzania wsadowego i zaplanowanych zadań — powinien istnieć łatwy sposób na wykrycie miejsc, w których znajdują się punkty przerwania, aby ocenić, czy dany kod działa, czy nie.
Porada 7: Upewnij się, że wszystkie zależności zewnętrzne są jawnie udokumentowane.
Najlepiej zrobić to w pliku README w systemie kontroli źródła, aby nie zgubić dokumentacji. Udokumentuj wszelkie zewnętrzne systemy, bazy danych lub zasoby, które muszą być dostępne, aby aplikacja działała poprawnie. Zwróć też uwagę, które z nich są opcjonalne i dodaj instrukcje, jak postępować, gdy są opcjonalne i niedostępne.
Poza technikami debugowania
Gdy te zalecenia będą przestrzegane podczas tworzenia nowych funkcji lub utrzymania systemu, wsparcie produkcji stanie się znacznie łatwiejsze, a Twoja firma będzie spędzać znacznie mniej czasu (i pieniędzy). Jak już wiesz, czas jest najważniejszy podczas rozwiązywania problemów z błędami i awariami produkcyjnymi — każda minuta, którą można zaoszczędzić, ma duże znaczenie w ostatecznym rozrachunku. Udanego kodowania!