Krótka odpowiedź

Serwer dedykowany gry nadaje się do utrzymania wtedy, gdy osoby, które będą go obsługiwać, potrafią go zbudować, wdrożyć, skonfigurować, obserwować, wycofać do poprzedniej wersji i przywrócić po awarii bez programisty, który go napisał. Dopóki tak nie jest, serwer jest działającym programem, ale jeszcze nie usługą.

Taka definicja przydaje się przed premierą lub startem LiveOps, bo zamienia niejasne przeczucie („działa na stagingu, będzie dobrze”) w dowody, które da się sprawdzić. Każdy z poniższych obszarów wymaga czegoś konkretnego: pipeline’u, dokumentu, dashboardu, przećwiczonej procedury. Jeśli dowodu brakuje, obszar nie jest gotowy, niezależnie od tego, jak dobrze serwer radzi sobie w playtestach.

Artykuł omawia te obszary w kolejności, w jakiej zwykle zawodzą, a na końcu zbiera je w jedną tabelę z właścicielem i warunkiem „gotowe, gdy” dla każdego wiersza.

Dwóch właścicieli, jedna granica

Większość problemów z przekazaniem to w rzeczywistości problemy z odpowiedzialnością. Biorą w nim udział dwie role, nawet jeśli obie pełni ta sama firma:

  • Deweloper gry odpowiada za to, co działa wewnątrz procesu: build serwera headless, kontrakt uruchomieniowy, specyficzne dla gry sygnały kondycji, logi i metryki, zgodność wersji oraz zachowanie meczu, gdy coś zawiedzie.
  • Operator infrastruktury odpowiada za to, gdzie i jak proces działa: konta hostingowe, regiony, hosty lub klastry, rejestr kontenerów, sekrety, pipeline’y logów i metryk, kierowanie alertów, pojemność i budżet oraz dyżury.

Granica między nimi to kontrakt: jak serwer się uruchamia, jakiej konfiguracji oczekuje, jakie sygnały emituje, jak należy go zatrzymać i co oznacza „zdrowy”. Warto spisać go wcześnie. Większość checklisty sprawdza, czy obie strony dotrzymały swojej części.

1. Powtarzalny build

Wszystko inne zależy od tego, czy potrafisz wyprodukować dokładnie ten serwer, który zamierzasz uruchomić. W praktyce oznacza to, że:

  • Serwer headless jest budowany przez zautomatyzowany job z otagowanego commita, a nie eksportowany z czyjegoś edytora.
  • Wersja silnika, pakiety i ustawienia buildu są przypięte, więc ten sam tag za miesiąc da ten sam wynik.
  • Każdy build ma identyfikator (wersja, commit, numer buildu), który serwer wypisuje przy starcie i dołącza do logów.
  • Ścieżki kodu działające tylko na serwerze oraz pominięte assety testujesz w tym buildzie, a nie zakładasz ich działania na podstawie klienta.

Typowa awaria jest cicha: serwer, który buduje się tylko na jednej maszynie, albo hotfix, którego nie da się odtworzyć, bo nikt nie wie, jaka lokalna zmiana do niego trafiła.

2. Wdrożenie

Wdrożenie powinno być powtarzalną operacją, a nie serią ręcznych poleceń na serwerze. W przypadku serwerów w kontenerach definicja obrazu znajduje się w repozytorium, obraz jest otagowany identyfikatorem buildu, a staging i produkcja są wdrażane tym samym mechanizmem, tylko z innymi danymi wejściowymi.

Deweloper gry odpowiada za obraz, który czysto startuje z udokumentowanych danych wejściowych. Operator odpowiada za rejestr, platformę wdrożeniową i dostęp do niej. Dobry test tej granicy: czy operator potrafi wdrożyć nowy build na staging wyłącznie na podstawie dokumentacji?

3. Konfiguracja

To właśnie przy konfiguracji „działa na stagingu” najczęściej przestaje działać na produkcji. Wypisz każde ustawienie, które czyta serwer: porty, nazwy regionów lub środowisk, endpointy backendu, reguły meczu, ustawienia ticka lub symulacji, poziom logowania, dane uwierzytelniające. Dla każdego zapisz wartość domyślną, wartość dla każdego środowiska, czy jest sekretem i kto może je zmieniać.

Dwa zachowania sprawiają, że konfiguracja jest bezpieczna. Serwer waliduje konfigurację przy starcie i odmawia uruchomienia z czytelnym komunikatem w logu, gdy czegoś brakuje lub wartość jest nieprawidłowa. A sekrety pochodzą z magazynu sekretów operatora, nigdy z obrazu ani z repozytorium.

4. Regiony i założenia dotyczące pojemności

W tym obszarze zespoły najchętniej podają liczbę. Nie rób tego, dopóki liczba nie ma dowodów. Pojemność zależy od symulacji gry, modelu hostingu, sprzętu i rzeczywistego zachowania graczy, więc wynik z innej gry albo ze spokojnego playtestu mówi bardzo niewiele.

Zamiast liczby prowadź krótki rejestr założeń. Każdy wpis zawiera:

  • założenie (na przykład: liczba graczy na mecz, liczba meczów na host, pamięć i CPU na mecz, regiony docelowe, spodziewane godziny szczytu),
  • jego podstawę: zmierzone (z linkiem do testu i identyfikatorem buildu), oszacowane (z uzasadnieniem) lub nieznane,
  • datę i build, którego dotyczy,
  • właściciela oraz test, który zastąpi je pomiarem.

Koszty podlegają tej samej zasadzie: dokumentuj czynniki kosztowe (typ instancji lub hosta, regiony, niewykorzystana pojemność, ruch wychodzący, retencja logów i metryk) oraz to, od których założeń zależą, zamiast jednej miesięcznej kwoty, której nikt nie potrafi uzasadnić. Deweloper gry mierzy, ile zasobów zużywa jeden mecz; operator przekłada to na dobór hostów, limity i budżet.

5. Logi, metryki i obserwowalność awarii

Gracz zgłasza rozłączenie w sobotę o 21:40. Czy operator potrafi znaleźć ten mecz, przeczytać log serwera i zobaczyć, co robił proces? Taki scenariusz jest lepszym testem niż dowolny zrzut ekranu dashboardu.

  • Logi są ustrukturyzowane i w każdej linii zawierają identyfikator buildu, identyfikator serwera lub meczu oraz region. Retencja i dostęp są określone.
  • Metryki obejmują proces (CPU, pamięć, restarty) i grę (czas klatki lub ticka serwera, liczba połączonych graczy, stan meczu, nieudane połączenia). Deweloper gry określa, które metryki gry są istotne; operator odpowiada za zbieranie, przechowywanie i kierowanie alertów.
  • Crashe generują raport lub zrzut pamięci, a symbole debugowania każdego wydanego buildu są przechowywane, aby raport dało się odczytać później. Polityka restartów jest jawna, więc pętla crashy jest widoczna, zamiast po cichu zużywać pojemność.
  • Alerty startują z ostrożnymi, udokumentowanymi progami początkowymi, a każdy z nich prowadzi do wpisu w runbooku. Alert, na który nikt nie wie, jak zareagować, to szum.

6. Wersjonowanie

Wersje klienta, serwera, protokołu sieciowego i zawartości muszą mieć określoną regułę zgodności. Proces sesji lub matchmakingu powinien kierować klienta tylko na serwer, z którym ten potrafi się komunikować, a klient z niezgodną wersją powinien otrzymać określony komunikat zamiast timeoutu. Spisz tę regułę: które zmiany wersji wymagają skoordynowanego wydania klienta i serwera, a które mogą trafić na produkcję niezależnie.

7. Wdrażanie i rollback

Serwery dedykowane obsługują trwające mecze, więc „wdrożenie nowej wersji” nigdy nie jest zwykłym restartem. Zdecyduj i udokumentuj:

  • czy nowe mecze startują na nowej wersji, a trwające kończą się na starej (draining), i jak długo draining może trwać;
  • jak serwer reaguje na sygnał zakończenia: przestaje przyjmować graczy, czysto kończy lub zamyka mecz, zapisuje logi i kończy pracę w czasie karencji;
  • jak wykonać rollback: poprzedni obraz jest zachowany, procedura jest spisana i przećwiczona na stagingu;
  • kto decyduje o rollbacku i na podstawie jakich sygnałów.

Deweloper gry określa ograniczenia zgodności i zachowanie przy zamykaniu; operator przeprowadza wdrożenia i rollbacki.

8. Scenariusze awarii

Wypisz spodziewane awarie i pożądane zachowanie dla każdej z nich. Wystarczy krótka tabela: scenariusz, zachowanie widoczne dla gracza, sygnał wykrycia, krok w runbooku. Typowe pozycje to crash serwera w trakcie meczu, utrata hosta, niedostępność regionu, awaria zależności backendowej (sesje, uwierzytelnianie, trwałość danych), błędna wartość konfiguracji i brak pojemności w godzinach szczytu.

Przed premierą nie przećwiczysz wszystkich. Przećwicz te o największym wpływie, a pozostałym zapewnij przynajmniej sygnał wykrycia i właściciela.

9. Odpowiedzialność i runbook

Runbook jest przekazaniem. Zawiera przegląd architektury, procedury wdrożenia, rollbacku i skalowania, opis konfiguracji, dashboardy i to, jak wygląda na nich normalny stan, tabelę scenariuszy awarii, rejestr założeń, znane ograniczenia, czynniki kosztowe i ścieżkę eskalacji, łącznie z tym, co dzieje się poza godzinami pracy.

Bieżące utrzymanie po przekazaniu to osobna decyzja. Jeśli deweloper nadal uczestniczy w pracach, zakres i oczekiwany czas reakcji trzeba uzgodnić jawnie. Jeśli nie, operator musi być w stanie pracować wyłącznie na podstawie runbooka.

Checklista przekazania

Użyj tej tabeli podczas przeglądu gotowości do premiery lub LiveOps. „Deweloper” oznacza zespół odpowiedzialny za kod i build serwera; „Operator” oznacza zespół odpowiedzialny za hosting i codzienne utrzymanie.

Obszar Wymagany dowód Właściciel Gotowe, gdy
Powtarzalny build Zautomatyzowany build serwera headless z otagowanego commita; przypięte wersje silnika i pakietów; osadzony identyfikator buildu Deweloper Osoba, która nie pisała pipeline’u, buduje ten sam serwer z taga, a serwer loguje identyfikator buildu przy starcie
Obraz kontenera Definicja obrazu w repozytorium; obraz otagowany identyfikatorem buildu; udokumentowany obraz bazowy i zależności Deweloper (zawartość); Operator (rejestr i zasady obrazów) Obraz startuje na stagingu wyłącznie z udokumentowanymi danymi wejściowymi
Wdrożenie Skryptowe lub deklaratywne wdrożenie na staging i produkcję; brak ręcznych kroków na hostach Operator (platforma i dostęp); Deweloper (kontrakt uruchomieniowy) Operator wdraża nowy build na staging na podstawie dokumentacji, bez pomocy dewelopera
Konfiguracja Opis każdego ustawienia: wartość domyślna, wartość dla środowiska, czy jest sekretem, kto może je zmieniać Deweloper definiuje; Operator dostarcza wartości i sekrety Serwer nie startuje przy brakującej lub błędnej konfiguracji i loguje, która wartość jest nieprawidłowa
Kondycja i zamykanie Sygnały readiness i liveness; raportowanie stanu meczu; udokumentowany czas karencji przy zamykaniu Deweloper Zatrzymanie serwera w trakcie meczu testowego na stagingu przebiega zgodnie z dokumentacją
Regiony i pojemność Rejestr założeń z podstawą (zmierzone, oszacowane, nieznane), datą, buildem i właścicielem; lista czynników kosztowych Deweloper (zużycie zasobów na mecz); Operator (dobór, limity, budżet) Każda liczba dotycząca pojemności lub kosztów w planie odsyła do pomiaru albo jest oznaczona jako założenie z testem, który ją zastąpi
Logi Ustrukturyzowane logi z identyfikatorem buildu, serwera lub meczu i regionem; określona retencja i dostęp Deweloper emituje; Operator zbiera i przechowuje Operator znajduje wszystkie logi jednego meczu na podstawie zgłoszenia gracza
Metryki i alerty Metryki procesu i gry; dashboard; udokumentowane progi początkowe Deweloper (metryki gry); Operator (pipeline, kierowanie, dyżury) Każdy alert prowadzi do wpisu w runbooku i przynajmniej raz zadziałał na stagingu
Crashe Przechwytywanie crashy, symbole dla każdego wydanego buildu, jawna polityka restartów Deweloper (symbole, analiza); Operator (przechwytywanie, przechowywanie, restarty) Celowy crash na stagingu daje czytelny raport powiązany z identyfikatorem buildu
Wersjonowanie Spisana reguła zgodności klienta, serwera, protokołu i zawartości; egzekwowana w procesie sesji Deweloper Klient z niezgodną wersją jest odrzucany z określonym komunikatem, co zostało przetestowane
Wdrażanie i rollback Strategia wdrażania z drainingiem; procedura rollbacku; zachowany poprzedni obraz; wskazana osoba decyzyjna Operator wykonuje; Deweloper określa ograniczenia Rollback został przećwiczony na stagingu, łącznie z obsługą trwających meczów
Scenariusze awarii Tabela scenariuszy: zachowanie dla gracza, sygnał wykrycia, krok w runbooku Wspólnie Każdy scenariusz ma właściciela i sygnał; te o największym wpływie są przećwiczone
Runbook i odpowiedzialność Runbook, ścieżka eskalacji, znane ograniczenia, umowa wsparcia lub jawne „brak wsparcia” Wspólnie, zatwierdzone przez obie strony Operator wykonuje wdrożenie, rollback i jedno ćwiczenie incydentu wyłącznie na podstawie runbooka

Na czym się opieramy

Naszym własnym punktem odniesienia jest Bad Goons, obecne autorskie IP Sourcegarden Studio, które jest w aktywnej produkcji. Gra uruchamia buildy headless Unity na autorytatywnych serwerach dedykowanych Linux z konteneryzowanymi wdrożeniami, a pojemność, zamykanie, kondycję, logi i wdrażanie wersji traktujemy jako sprawy dotyczące samej gry, a nie cudzy problem infrastrukturalny. Bad Goons projektujemy z myślą o meczach dla 64 graczy; to cel projektowy, a nie zmierzona pojemność, i właśnie dlatego ten artykuł zaleca rejestr założeń zamiast efektownej liczby.

Checklista to ogólne zalecenia praktyczne oparte na tej pracy. Nie twierdzimy, że każdy jej punkt został już sprawdzony przy rzeczywistym ruchu graczy.

Gdzie to się mieści w projekcie

Checklista jest końcem procesu, który zaczyna się znacznie wcześniej. Jeśli granice między meczem w czasie rzeczywistym a otaczającymi go usługami wciąż są niejasne, zacznij od modelu sieciowego po stronie tworzenia gier multiplayer oraz od tego, co określić, zanim poprosisz o wycenę backendu gry. Najtańszy moment na uzgodnienie odpowiedzialności to czas przed pierwszym wdrożeniem, a nie tydzień przed premierą.

Jeśli Twój serwer już działa, ale powyższych dowodów jest niewiele, krótki przegląd według tej tabeli zwykle pokazuje, od czego zacząć. Takimi zadaniami zajmujemy się w ramach backendu do gier: wdrożenie, obserwowalność i przekazanie, z którym Twój zespół poradzi sobie samodzielnie.