Jednym z głównych celów tej wersji alfa jest przetestowanie całego stosu technologicznego pod presją i na coraz większą skalę z prawdziwymi graczami, ponieważ żadna ilość automatycznych testów i symulacji nie jest w stanie ujawnić różnych krytycznych zdarzeń, które mogą wystąpić w różnych sekcjach stosu i jaki mogą mieć wpływ na całą usługę.

Z punktu widzenia Liveops cały test alfa przypomina wystrzelenie w przestrzeń kosmiczną ogromnej rakiety wypełnionej paliwem z nadzieją, że dotrze ona na orbitę i najlepiej powróci na Ziemię mniej więcej nietknięta, gotowa do kolejnego lotu. Całość jest wyposażona w całą dostępną telemetrię, dzięki czemu można uzyskać wgląd w to, co dzieje się w czasie rzeczywistym i móc rozwiązać problemy, najlepiej zanim doprowadzą one do katastrofalnych awarii.

Stos jest dość złożony i składa się z różnych serwerów obsługujących wiele usług w wielu regionach geograficznych. Na potrzeby tego testu wykorzystano z około 150 serwerów wirtualnych rozmieszczonych w UE i USA. Około dwie trzecie z nich to serwery Unreal obsługujące określone strefy w określonych światach i uruchamiane automatycznie, gdy gracze wejdą do tych stref. Pozostała część to serwery zaplecza działające jako punkty końcowe API dla różnych usług gier. Należą do nich ekwipunek, awatar, grupy, budynek i uwierzytelnianie. Za tym wszystkim kryje się kilka dużych baz danych, które obsługują całą trwałość, zarówno klientów, ich postaci, jak i powiązanego stanu trwałego. Wszystkie te serwery i systemy, a także wybrane próbki klientów, generują dane telemetryczne gromadzone na platformie obserwowalności o nazwie Datadog, a także w stosie analitycznym, który pozwala wizualizować w czasie rzeczywistym stan wszystkich komponentów, a także generować automatycznie ostrzeżenia, gdy zostaną zaobserwowane pewne krytyczne warunki.

Podczas wydarzeń inauguracyjnych, takich jak teraz, tworzona jest ekipa LiveOps, która monitoruje Datadog, a także kanały mediów społecznościowych, pracując na zmiany przez całą dobę. Załoga ta składa się z najbardziej doświadczonych inżynierów niezawodności witryn, inżynierów oprogramowania i menedżerów społeczności. Skład tego zespołu jest taki, że powinien on być w stanie rozwiązać problemy krytyczne w rzeczywistym środowisku, znaleźć akceptowalne rozwiązanie, przetestować i wdrożyć wspomniane rozwiązanie, a następnie monitorować, czy rzeczywiście rozwiązał problem, a wszystko to przy zachowaniu społeczności aktualizowane tak często, jak to możliwe i upewniające się, że wszystko, co zostanie zrobione, wpłynie na jak najmniejszą liczbę osób. Cała załoga zbiera się w tak zwanym pokoju wojennym, będącym kanałem wideokonferencji, w którym omawiane i wspólnie rozwiązywane są problemy. Pomyśl o tym jak o kontroli lotu Apollo (a przynajmniej do tego lubią się porównywać).

Oto kilka historii z Pokoju Wojennego.

W ten piękny wtorkowy poranek uruchomiliśmy nasze silniki o godzinie 11 UTC i zaobserwowaliśmy natychmiastowy napływ graczy ze wszystkich światów i stref. Wszystkie systemy zachowywały się normalnie. Podczas takich wzrostów systemami, na które warto zwrócić uwagę, są serwery uwierzytelniające, a następnie różne strefy uruchamiane na żądanie, gdy gracze łączą się z różnymi częściami światów. Mimo że rozwój ten może być dość szybki, nadal jest stosunkowo organiczny, ponieważ gracze dołączają w sposób losowy.

Gdy około 12:30 UTC osiągnęliśmy populację około 5 tys. graczy, zaczęliśmy otrzymywać pierwsze ostrzeżenia. Serwer Redis zaczynał niebezpiecznie zbliżać się do 100% wykorzystania procesora. Serwery Redis służą do buforowania i szybkiego utrzymywania stanu niestabilnego z serwerów Unreal na wielu światach w tym samym regionie AWS. Są superwydajne i zwykle nie uginają się łatwo pod obciążeniem, ale nadal musisz mieć pewne wstępne przypuszczenie, jakiej mocy procesora będą potrzebować. Zwykle jesteśmy w stanie formułować uzasadnione domysły, symulując ruch na różnych punktach końcowych, ale w przypadku serwera Redis nie podlegał tego typu testom, ale zamiast tego polegał na ograniczonych testach warunków skrajnych, które przeprowadziliśmy przy użyciu wewnętrznych odtwarzaczy, a także specjalnych botów testujących. Testy te nigdy nie były nawet bliskie symulowaniu bieżącego obciążenia i było jasne, że należy je przełączyć na bardziej wydajny węzeł. Zwykle jest to coś, co można wykonać na żywo i w sposób przejrzysty, ale w tym przypadku usługa nie została skonfigurowana do działania z łatwo dostępną repliką (tzw. tryb Multi-AZ). Oznaczało to, że należało ją zdjąć i następnie uruchomiony ponownie. W tym miejscu wkroczyliśmy na nieznane terytorium, ponieważ nie było jasne, czy wszystkie systemy poradzą sobie z takimi zakłóceniami i ponownie połączą się w przejrzysty sposób z nową instancją Redis bez uporządkowanego zamykania i ponownego uruchamiania. Ponieważ nie mieliśmy dużego wyboru, ponieważ serwer w końcu przestał działać, pociągnęliśmy za spust podczas aktualizacji instancji Redis do bardziej wydajnych węzłów. Szybko stało się jasne, że nie doszło do prawidłowego ponownego połączenia i zaczęliśmy otrzymywać błędy i nietypowe zachowanie z różnych części stosu, które opierały się na serwerze Redis.

Równolegle monitorowaliśmy zużycie pamięci kilku serwerów strefy Unreal, które osiągało tendencję powyżej normy, co skutkowało słabą wydajnością i opóźnieniami dla graczy podłączonych do tych węzłów. Niektóre dochodzenia polegające na faktycznym podłączeniu się do tych podejrzanych węzłów ujawniły winowajcę. Króliki. Króliki wszędzie. Zawsze są to króliki, prawda? Zasada dystrybucji zasobów stosowana do kontrolowania populacji królików działała niewłaściwie w niektórych biomach, co skutkowało proliferacją królików. Teraz, mimo że królik wydaje się niewinnym stworzeniem, w rzeczywistości liczy się jako pełnoprawne stworzenie w naszej liczbie NPC. Gdy serwer jest w pełni obciążony, należy kontrolować NPC-ów, którzy rywalizują o te same zasoby procesora serwera, na przykład w celu wykrywania kolizji i znajdowania ścieżki. Aktualizacja dystrybucji zasobów w celu zabicia tych królików była dość łatwa, ale w tym przypadku wymagałaby ponownego uruchomienia dotkniętych stref. Ponieważ nie mieliśmy jasnego obrazu tego, który węzeł może zostać dotknięty inwazją królików, i biorąc pod uwagę, że walczyliśmy już z kolejnym zakłóceniem spowodowanym ponownym uruchomieniem Redis, a także musieliśmy zastosować te same zmiany w różnych regionach świata, zdecydowano o przełączeniu całej gry w tryb konserwacji, abyśmy mogli wszystko poprawnie zrestartować.

Tryb konserwacji zasadniczo odcina dostęp wszystkim graczom, więc natychmiastowo wyłączył usługę, co pozwoliło nam zrestartować świat i sfinalizować niektóre zmiany, które chcieliśmy zastosować. Chcemy tego uniknąć w jak największym stopniu, ponieważ w 100% zakłóca to doświadczenie gracza. Jednak wiąże się z tym jeszcze jedno wyzwanie: wyjście z trybu konserwacji.

Problem polega na tym, że przejście do trybu konserwacji, gdy wiele tysięcy graczy jest już podłączonych, oznacza, że gdy chcesz ponownie otworzyć usługę wkrótce potem, tłum tysięcy graczy ponownie łączy się niemal w tym samym momencie. Różni się to bardzo od organicznego wzorca wzrostu połączeń w ciągu typowego dnia, ale bardziej przypomina tsunami równoczesnych połączeń w ciągu kilku minut. Większość naszego stosu ma wbudowaną ochronę w zakresie automatycznego skalowania i równoważenia obciążenia, ale nadal istnieją pewne wąskie gardła, które w takich scenariuszach szybko mogą stać się problematyczne. Te wąskie gardła mogą następnie wywołać efekt domina na innych systemach oczekujących na połączenia i ostatecznie mogą przekroczyć limit czasu, tworząc idealną burzę. Zwykle wszystko w końcu się układa, choć doświadczenia gracza w tej fazie mogą być mniej niż optymalne. Naszym celem na przyszłość jest ulepszenie naszego trybu konserwacji, aby uwzględnić jakąś formę ograniczania połączeń przychodzących, co pozwoli nam na uporządkowane zwiększanie liczby połączeń, ale na razie pouczające jest dla nas sprawdzenie, które usługi stają się wąskimi gardłami i pomaga określić, gdzie możemy chcieć mieć różne konfiguracje, aby lepiej radzić sobie z tymi przepięciami.

Po około 20 minutach przestoju wróciliśmy do gry, liczba graczy stale wzrastała, a oprócz UE zaczęli dołączać do gry klienci z USA. Około godziny 17:30 czasu UTC osiągnęliśmy oczekiwaną przez nas liczbę graczy z największą liczbą połączeń w tym dniu.

W tym momencie zaczęliśmy obserwować pewne turbulencje w sile i w tym przypadku wydawało się, że są one związane z przeciążeniem bazy danych. Wydawało się, że dotyczy to głównie jednego regionu, ale ponieważ niektóre z naszych zapytań do bazy danych obejmują wiele baz danych w wielu regionach, efekt można było odczuć wszędzie. Nasze bazy danych wydawały się być prawidłowo zaopatrzone i nie powinny zbliżać się do 100% procesora nawet przy tak dużym obciążeniu, ale coś powodowało, że baza danych się zatrzymywała. W końcu zawęziliśmy sprawę do jednego fałszywego połączenia z bazą danych, które zawieszało się i blokowało krytyczną tabelę, powodując blokowanie wszelkich zapytań korzystających z tej tabeli. To ponownie wywołało efekt domina, ponieważ żądania kierowane do backendu, które inicjowały te zapytania, w końcu przekroczyły limit czasu, co doprowadziło do ponownych prób lub niepowodzeń określonych działań gracza. Był to dobry przykład pojedynczej luźnej śruby wywołującej efekt promieniujący na cały stos i obszary. Gdy zwolniliśmy blokadę stołu, większość usług zaczęła działać prawidłowo i szybko powróciliśmy do poprzednich poziomów graczy.

Przez resztę nocy mieliśmy kilka alertów, którymi musieliśmy się zająć, ale na szczęście były to wszystkie problemy, które mogliśmy naprawić na żywo, bez zakłócania całej usługi i bez konieczności budzenia większej liczby osób.

Wyciągnięte wnioski są takie, że zazwyczaj, gdy uda się znaleźć pierwotną przyczynę problemu, lekarstwo jest stosunkowo oczywiste i możesz być również nieco zawstydzony, że nie zauważyłeś tego konkretnego problemu przed publikacją. Prawda jest jednak taka, że rodzaj pojawiających się problemów i połączenie wielu różnych systemów wykazujących odmienne zachowanie w warunkach rzeczywistego ruchu graczy jest trudne do całkowitego przewidzenia, a często ustalenie prawdziwej przyczyny może być trudne ze względu na współzależności. Jednocześnie polowanie wiąże się z pewnym dreszczem emocji i dużą satysfakcją po osiągnięciu rozwiązania.

Właśnie dlatego przeprowadzamy test taki jak Alfai jesteśmy bardzo wdzięczni społeczności uczestniczącej w takim wydarzeniu, która pomaga odkryć te trudne do znalezienia problemy i stworzyć solidniejsze systemy, które poradzą sobie z nimi w przyszłości. Jeszcze raz pragniemy serdecznie podziękować całej naszej społeczności za wsparcie i pasję związaną z Pax Dei.

Zespół Mainframe