Jak podejść do rozwiązania problemu z powtarzalnym / losowym błędem?

11

Mamy wielojęzyczną stronę internetową, na której kilka dni temu wykryto błąd. Wyświetlał dane w innym języku w innym języku, a także wybrano mieszankę danych takich jak język angielski, ale wyświetlał również inne dane w języku na stronie i odwrotnie. Robi to rzadko, ale jest obecny na stronie internetowej. Przejrzenie kodu również nie pomaga, ponieważ nie zawsze tak się dzieje.

Wszelkie sugestie dotyczące znalezienia problemu w odpowiednim czasie? Proszę o strategie tutaj.

maz3tt
źródło
4
zacznij sprawdzać kod w sytuacjach, które pozwolą na wystąpienie tego błędu (zamiast robić to na odwrót)
Imran Omar Bukhsh

Odpowiedzi:

20

Pierwszym krokiem jest próba scharakteryzowania tego, co może powodować tego rodzaju problem. Ponieważ wiąże się to z wyborem poprawnego języka dla sekcji kodu, zacznij od rozważenia następujących kwestii:

  • Jak wykrywa się język? Czy jest oparty na informacjach z żądania HTTP? Czy jest oparty na informacjach o sesji? Czy może jest oparty na polach bazy danych? Zasadniczo, czy może to być problem związany ze sposobem, w jaki aplikacja wybiera język dla każdej sekcji?
  • Jak wyświetlany jest język? Czy pobierasz z pliku właściwości lub bazy danych? Czy to możliwe, że zgubiono odniesienie do właściwego języka? Czy mieszany język, który widzisz, jest zawsze domyślny dla witryny?
  • Czy istnieje korelacja ze środowiskiem klienta? Jest to związane z pierwszym pociskiem, ale idzie jeszcze dalej. Miałem dziwne problemy z renderowaniem z powodu serwerów proxy buforujących. Zazwyczaj tego rodzaju problemy to cała strona, która jest nieaktualna lub wyświetla stronę jednej osoby innym użytkownikom (to było zawstydzające).
  • Czy używasz wartości wątku lokalnego? Jeśli żądanie zostanie obsłużone w więcej niż jednym wątku, wartość lokalna wątku będzie zawierała różne informacje w zależności od wątku, który działa w danym momencie. W środowisku serwera WWW nie można zakładać, że wątek, na którym rozpoczęto przetwarzanie, będzie tym samym wątkiem, na którym zakończono przetwarzanie - chyba że jest to część specyfikacji platformy. Autorzy serwerów odkryli, że jeśli ponownie wykorzystają małą pulę wątków i pracują w multipleksie w porcjach, mogą obsłużyć więcej żądań jednocześnie. Nawet jeśli masz jeden wątek od początku do końca żądania, serwer może multipleksować inne żądania do tego wątku w tym samym czasie. Zamiast miejscowych wątków, rozważ powiązanie tej wartości z atrybutami żądania lub sesji.

Teraz, gdy scharakteryzujesz możliwości tego, co może pójść nie tak, nadszedł czas, aby upewnić się, że masz dane, których potrzebujesz, aby dowiedzieć się, co poszło nie tak.

  • Korzystaj z obfitego logowania w obszarach problemowych. Jest to miejsce, w którym narzędzie takie jak Log4J lub Log4Net może naprawdę zabłysnąć. Ta struktura rejestrowania i inne podobne pozwalają na zwiększenie rejestrowania dla niektórych kategorii przy jednoczesnym ograniczeniu hałasu dla wszystkich innych - wszystko przez zmianę pliku konfiguracyjnego. Chcesz wprowadzić nowe instrukcje rejestrowania, aby dowiedzieć się, czy to, co podejrzewasz, może być problemem. Upewnij się również, że dzienniki dostępu HTTP zawierają wszystkie potrzebne informacje o każdym żądaniu (pliki cookie, parametry nagłówka http itp.)
  • Spróbuj zasymulować problem. Ponieważ zdarza się to sporadycznie, jakie jest obciążenie serwera w momencie jego wystąpienia? Czy trafia Cię wiele jednoczesnych żądań z wielu języków? Jeśli tak, spróbuj przeprowadzić symulację tego rodzaju obciążenia w środowisku testowym. Potrzebne może być narzędzie podobne do JMeter. Będziesz także mieć możliwość fałszowania adresów IP swoich fałszywych klientów. Pamiętaj, że adresy IP są podzielone, dzięki czemu możesz dowiedzieć się, w jakim kraju / regionie adres IP jest oparty na pierwszych dwóch segmentach adresu.
  • Problemem będzie tylko jako sporadyczne w środowisku testowym, ale jak w zawężeniu do swojej prawdziwej przyczyny można wypaczyć wyniki, żeby tak było bardziej często niż ma to miejsce w naturalnym środowisku. Ponadto możesz łatwiej przeglądać pliki dziennika i próbować się z nich uczyć.
  • To proces iteracyjny, więc bądź cierpliwy. Musisz wskazać rodzaj obciążenia, które Twoim zdaniem spowoduje odtworzenie błędu, sprawdź dzienniki i udoskonal swoje testy na podstawie tego, co znajdziesz. Ważne jest, aby zidentyfikować problem , więc oprzyj się pokusie wprowadzenia prostych poprawek, które mogą sprawić, że prawdziwy problem będzie się pojawiał rzadziej.

Wreszcie, po zawężeniu problemu do miejsca, w którym wiesz, jak go odtworzyć, i co go powoduje, napisz najmniejszy automatyczny test, który możesz wymusić w kodzie. Jeśli zawęziłeś problem do jednej klasy lub pary klas nie współpracujących ze sobą poprawnie, odtwórz go na tym poziomie. Nie powinieneś odradzać 100 wątków, aby to zrobić, po prostu wykonaj najmniejszy test, który może spowodować, że problem wystąpi w 100% przypadków.

Teraz możesz to naprawić i mieć całkowitą pewność, że nie wróci, by cię ugryźć.

Berin Loritsch
źródło
10

Błąd nie jest nie do naprawienia. Po prostu jeszcze nie wiesz, jak to odtworzyć.

Żaden błąd nie jest przypadkowy, chyba że zgłaszasz wyjątek na podstawie wartości zwracanej przez jakąś instrukcję Random ().

Wiem, że to może wydawać się semantyką, ale psychicznie uspokajające jest mówienie tego sobie.

Bardzo trudno i frustrujące jest dowiedzieć się, jak naprawić błąd, który zdarza się tylko z powodu złożonych warunków wyścigowych lub podobnych.

Jeśli chodzi o to, jak to znaleźć, chciałbym włączyć / dodać trochę logowania do aplikacji w miejscach, które mogłyby dać ci więcej informacji.

Następnie powiedz ludziom, którzy widzą błąd (niezależnie od tego, czy są to Devs, QA, użytkownicy końcowi), aby zgłosili się, jak tylko zobaczą, z czasem, kiedy to się stało, a następnie przejrzą twoje dzienniki. Zapytaj ich o inne informacje, a błąd może się zdarzyć tylko z powodu interakcji kilku różnych systemów lub warunków wyścigu

Mam nadzieję, że będziesz w stanie znaleźć trop.

Gilles
źródło
nawet wywołania Random () nie są tak naprawdę losowe, chyba że pochodzą od sprzętowego generatora białego szumu. Są losowo psuedo, co oznacza, że ​​liczby są matematycznie rozmieszczone w losowej kolejności, jak to możliwe. Ale jeśli zaczniesz od tej samej wartości „seed”, za każdym razem otrzymasz tę samą odpowiedź.
Berin Loritsch,
1
@Berin: Wiem.
Gilles
+1 za „po prostu jeszcze nie wiesz, jak to odtworzyć”. Wszystkie błędy mają podstawową przyczynę, inaczej by się nie wydarzyły.
Mike S
1
Nie musi to być funkcja Random (), rzeczy zależne od czasu, szczególnie te, które wymagają niewłaściwego dostępu do udostępnionego zasobu, mogą być bardzo trudne do odtworzenia.
Loren Pechtel
2
@Gilles: Z wyjątkiem tego, że mogą nie determinować niczego, co można rozsądnie zmierzyć. (Powiedz dokładnie, kiedy jakieś inne zadanie zostało zwolnione, to
odcinek
5

Możesz spróbować znaleźć miejsca w kodzie, w których można rozpoznać wystąpienie problemu (na przykład niespójne parametry w metodzie), dodać kontrole do kodu i pozwolić im na dodanie dodatkowych informacji do dziennika debugowania (np. Ślad stosu, obiekty dodane do sesji itp.)

Robiąc to, przy odrobinie szczęścia możesz uchwycić informacje o zdarzeniach i wydedukować drogę do problemu.

rsp
źródło
2

Automatyzacja powinna pomóc, jeśli te same kroki do odtworzenia, które czasami zawodzą, zautomatyzuj to i umieść w pętli. Uruchom 50 000 razy i jest bardzo prawdopodobne, że wystąpi.

Kieren Johnstone
źródło
Wydarzenie nie jest losowe, po prostu wydaje się losowe. Może to spowodować, że się pojawi, ale da ci bardzo mało informacji o tym, dlaczego się pojawiło.
Josh K
1
@Josh - Jeśli nie jest w stanie go odtworzyć, może to być dobry sposób, aby to zrobić i uzyskać na przykład ślad stosu z symbolami debugowania. Myślę, że to świetny pierwszy krok - zobaczenie go z pierwszej ręki
Kieren Johnstone
Zakładasz, że istnieje stos i że można go uzyskać. Nie podał nam żadnych informacji technicznych na temat aplikacji ani jej dostępności do debugowania przy tego rodzaju obciążeniu. To nie jest strategia debugowania , to uderzenie młotkiem, który próbuje uchwycić dokładnie ten moment, w którym się psuje.
Josh K
@Josh - moje rzeczywiste doświadczenia mówią mi, że najcenniejszą rzeczą w badaniu / naprawianiu błędu jest zobaczenie go z pierwszej ręki. Niezależnie od tego, czy jest to coś, co można zobaczyć w czasie, ślad stosu, coś w logach lub cokolwiek innego. Tam, gdzie to możliwe, pozornie przypadkowe problemy przetestowane w pętli naprawdę szybko mnie tam doprowadziły. Jeśli masz inny pomysł, opublikuj go jako odpowiedź na miłość boską - jest to ważna metoda i prawidłowa odpowiedź.
Kieren Johnstone
Nie zgadzam się i uważam, że odpowiedź Berina jest właściwą drogą do rozwiązania tego problemu.
Josh K
1

spróbuj znaleźć wzorce określające warunki, które powodują pojawienie się tego problemu. Powinno to skierować Cię do części kodu, które zawiodły (lub zachowują się niekonsekwentnie).

jwenting
źródło
Bez gówna ..............
theringostarrs
0

Można wykryć, gdy problem jest występujących? Jeśli tak, czy możesz rzetelnie zrzucić informacje o stanie systemu w tym momencie?

Jeśli odpowiedź na oba powyższe pytania brzmi „tak”, przygotuj kod, aby zapisać jak najwięcej informacji w momencie wystąpienia błędu, a następnie poczekaj.

Nie zastępuje to tego, co sugerują inni (nadal będziesz musiał przemyśleć, w jaki sposób kod może przejść do stanu, w którym widzisz), ale dopóki nie możesz odtworzyć błędu do woli, dobrze jest nie marnować okazji, w których się pojawia.

jimwise
źródło