Server Debugger

Server Debugger

El_Neuman

Mod dla właścicieli serwerów. Odpowiada na pytanie "dlaczego mój serwer laguje" - i jeśli winny jest jakiś mod, nazywa go po imieniu. Samodzielny mod, niczego za sobą nie ciągnie. Instalowany tylko na serwerze, gracze nie muszą go pobierać.

Został napisany z założeniem, że nie jesteś programistą. Polecenia poniżej są wyjaśnione prostymi słowami: co robią, po co i co pokażą.


Ogólne informacje - co właściwie się dzieje, gdy "serwer laguje"

 

Serwer co ułamek sekundy robi "tik" (tick) - oblicza świat: moby, ogniska, temperaturę, wszystko naraz. Jeśli jeden tik zajmuje nie 0.05 sekundy, a powiedzmy 5 sekund - dla graczy to freeze (zacięcie): moby zamierają, bloki się nie stawiają, wszystkich "teleportuje".

Przyczyn długiego tika jest niewiele i różnią się one sposobem leczenia. Ten mod potrafi je od siebie odróżnić i pokazać, z którą dokładnie masz do czynienia.

Dwie rzeczy, które musisz wiedzieć, aby zrozumieć wyniki działania moda:

  • Śmieci i ich sprzątanie (GC). Gra i mody stale tworzą w pamięci obiekty tymczasowe. Gdy nagromadzi się ich dużo, system uruchamia "zbieranie śmieci" (GC - garbage collection): zamiera, przechodzi przez całą pamięć i wyrzuca to, co niepotrzebne. Dopóki trwa sprzątanie - serwer stoi. Zazwyczaj są to ułamki sekund i jest to niezauważalne. Ale jeśli w pamięci zgromadziły się gigabajty, jedno sprzątanie może zająć sekundy - i stąd freeze.
  • Wyciek pamięci. Sprzątanie wyrzuca tylko to, co nie jest już nikomu potrzebne. Jeśli jakiś mod przez pomyłkę nadal "trzyma" już martwe moby (nie zwalnia referencji do nich) - GC nie może ich usunąć. Gromadzą się one. Pamięć rośnie, sprzątania stają się coraz dłuższe, serwer laguje coraz bardziej. To właśnie jest wyciek. Dokładnie coś takiego złapałem na swoim serwerze - mod trzymał dziesiątki tysięcy dawno znikniętych mobów.

 


Czym Server Debugger różni się od MemLeakInspector?

MemLeakInspector - to specjalistyczne narzędzie do badania pamięci. Pokazuje, jakie obiekty znajdują się w pamięci, pozwala analizować ich stan i porównywać zrzuty pamięci między sobą. Jednak nie określa automatycznie przyczyny problemu - interpretować wyniki i szukać winowajcy trzeba samodzielnie.

Server Debugger - to kompleksowe narzędzie do diagnostyki serwera. Analizuje zawieszenia głównego wątku (main-thread), lagi, pauzy GC, problemy z dyskiem i wycieki pamięci. Po wykryciu wycieku natychmiast próbuje określić winny mod, co znacznie przyspiesza znalezienie problemu. Jednocześnie nie zapewnia głębokiej analizy obiektów w pamięci, tymczasowych zrzutów ani szczegółowego panelu zużycia pamięci.

Innymi słowy, Server Debugger odpowiada na pytanie "jaki mod powoduje problem?", a MemLeakInspector - "jakie obiekty znajdują się w pamięci i jak zmieniają się w czasie". Narzędzia te nie zastępują się nawzajem, ale świetnie ze sobą współpracują.


Co mod potrafi, a czego nie

 

Łapie pewnie i samodzielnie

  • Wycieki pamięci. Kiedy jakiś mod przez błąd gromadzi w pamięci martwe byty (moby) i ich nie puszcza - pamięć rośnie, serwer laguje coraz bardziej. Mod znajduje to i nazywa winowajcę po imieniu (polecenie whodunit). 
  • Zrozumienie, skąd w ogóle lag. Na każdy freeze mod mówi, na co poszedł czas: na sprzątanie śmieci, na zbyt długi kod, czy serwer po prostu czekał (dysk, sprzęt). Kierunek wskaże zawsze - nie będziesz zgadywać i kopać w złym miejscu.
  • Kto ręcznie wywołuje sprzątanie śmieci. Czasami mod sam każe "posprzątać śmieci teraz", a przy dużej pamięci to powoduje freeze. Polecenie /sdebug gccallers pokazuje, jaki mod to robi (szczegółowo i z przykładem - w dziale o poleceniach poniżej).
  • Złe ustawienia sprzątania śmieci. Polecenie /sdebug env pokaże, czy włączony jest szybki tryb sprzątania, a jeśli nie - można to naprawić (przykład wyniku i jak to naprawić - poniżej).

Pomaga, ale sam nie wskaże winowajcy

  • "Ciężki kod". Wyobraź sobie: autor moda popełnił błąd, i jego mod co każdy tik niepotrzebnie przelicza wszystkie 5000 grządek na serwerze, jak na przykład mod Wild Farming.  Pamięć nie rośnie - kod po prostu wykonuje za dużo pracy. To NIE jest wyciek, i whodunit jest tu bezużyteczny.

  • Co zrobi mod: stalls (patrz niżej) dokładnie napisze "to jest ciężki kod, a nie sprzątanie śmieci" - czyli da właściwy kierunek. A żeby znaleźć konkretny mod, jest profile (patrz niżej) - mierzy on czas dla fragmentów kodu. Ale patrzy on nie na wszystkie mody po kolei, lecz na te, które są wskazane w ustawieniach (lub podobne do nich). Czyli nie ma tu zasady "kliknąłeś - masz imię", jak w przypadku wycieku: być może trzeba będzie podpowiedzieć debuggerowi, gdzie szukać. Jest pomoc, nie ma automatyzmu, trzeba będzie przejrzeć podejrzane mody.

W ogóle nie potrafi

  • Lagi z powodu dysku, sieci lub słabego sprzętu hostingu. Mod powie "przyczyna nie leży w kodzie modów" - ale naprawić tego nie zdoła. To do hostingu.
  • Lagi u gracza (niski FPS, szarpiący obraz). Mod jest czysto serwerowy, w ogóle nie widzi klienta.
  • "Ciężko, ale poprawnie". Jeśli te 5000 grządek uczciwie trzeba przeliczać i w kodzie nie ma błędu - mod pokaże, że czas ucieka tam, ale to już nie bug, lecz kwestia tego, jak mod jest zbudowany. Leczy się to nie debugowaniem, ale przebudową moda (lub zmniejszeniem obciążenia na serwerze).

Jednym zdaniem

Wyciek pamięci - znajdzie i nazwie winowajcę sam. Cała reszta - wskaże właściwy kierunek ("to kod", "to dysk", "to sprzątanie śmieci"), ale dalej musisz myśleć sam.


Od czego zacząć


/sdebug stalls - analiza ostatnich zacięć (freezów)

Kiedy wpisywać: jako pierwsze, gdy tylko serwer laguje lub lagował niedawno. To punkt wejścia do każdej analizy - sama wskaże, w którym kierunku kopać dalej. Na świeżo uruchomionym, spokojnym serwerze pokaże pustkę (nie było jeszcze freezów) - to normalne.

Mod sam wyłapuje freezy i zapisuje ich analizę. To polecenie pokazuje ostatnie (domyślnie 5). Każdy freeze to blok, a ostatnia linia w nim to werdykt prostym tekstem, na co poszedł czas. Przykład:

ServerDebugger: ZACIĘCIE 
  Czas trwania         : 5084 ms
  GC pause             : 5008 ms  (99%)
  ...
  WERDYKT : PAUZA GC. Serwer sprzątał śmieci. Sprawdź, czy nie ma wycieku: /sdebug leak

Lub, jeśli winne nie są śmieci, ale kod:

  WERDYKT : PROCES FAKTYCZNIE LICZYŁ, GC nie ma z tym nic wspólnego => gorący kod.
            Włącz /sdebug profile on, aby dowiedzieć się jaki.

  • Ważne i uczciwe: stalls sam nie nazwie konkretnego moda. Wskazuje tylko kierunek - "to sprzątanie śmieci" / "to kod" / "to oczekiwanie na dysk". Kto dokładnie jest winny, szukają kolejne polecenia, każde pod swój kierunek. Gdzie iść po werdykcie:werdykt "PAUZA GC" -> to pamięć. Idź do sekcji "O wyciekach" poniżej (leak i whodunit), a przy okazji sprawdź gc.
  • werdykt "gorący kod" -> idź do profile / top.
  • werdykt "oczekiwanie na dysk / lock" -> to najczęściej sprzęt hostingu, nie da się naprawić kodem.

/sdebug env - ogólny stan serwera

Kiedy wpisywać: w dowolnym momencie, zaraz po stalls w celu ogólnego przeglądu. Serwer musi po prostu działać, nie trzeba uruchamiać sprzątania - polecenie czyta bieżący stan.

Pokaże blok w takim stylu (usunąłem zbędne):

ServerDebugger: środowisko 
  ProcessorCount       : 24
  Server GC            : False        <- ta linia jest ważna
  Pause time %         : 18.5         <- i ta
  Memory load          : 6400 MB / 16000 MB

Jak czytać:

  • Server GC - czy włączony jest szybki tryb sprzątania śmieci. False = powolny, jednowątkowy, sprzątanie spowalnia bardziej, niż by mogło. To "złe ustawienie" serwera. Jak naprawić - w sekcji "Przyspieszyć sprzątanie śmieci" na samym końcu README. Po naprawie linia zmieni się na True.
  • Pause time % - jaki procent czasu zajmuje sprzątanie śmieci. Pojedyncze procenty to norma. 15% i wyżej (jak 18.5 w przykładzie) - sprzątanie jest twoim problemem.
  • Memory load - ile pamięci jest zajęte. Blisko limitu - pamięć sama w sobie może stać się przyczyną.

O wyciekach - dwa polecenia po kolei

Jeśli stalls pokazał werdykt "PAUZA GC" - najprawdopodobniej to wyciek. Łapie się go w dwóch krokach: najpierw /sdebug leak sprawdza, czy w ogóle istnieje, potem /sdebug whodunit nazywa winowajcę. Używa się ich dokładnie w tej kolejności.


/sdebug leak - KROK 1: czy wyciek w ogóle istnieje?

Kiedy wpisywać: gdy pamięć serwera rośnie z czasem i lagi się nasilają - i koniecznie pozwalając serwerowi popracować (godzinę-dwie po starcie, lub po nocy w grze, gdy pojawiło się dużo mobów). Na nowo uruchomionym serwerze wyciek jeszcze się nie nagromadził, i test pokaże pustkę.

Polecenie przeprowadza ręczne sprzątanie śmieci (serwer zatrzyma się na kilka sekund) i liczy, ile martwych mobów je przetrwało.

"Przetrwały" = powinny zniknąć, ale ktoś je trzyma, i GC nie mogło ich usunąć. Logika jest prosta: żywych mobów GC nie rusza, ale jeśli dawno zniknięty mob "przetrwał" sprzątanie - to znaczy, że ktoś go nielegalnie trzyma, i jest to wyciek.

Co pokaże: procent tych, co przetrwały.

  • W okolicach zera - nie ma wycieku. Na tym kończymy z wyciekami, szukaj przyczyny lagów gdzie indziej (patrz stalls, env).
  • 80% i więcej - wyciek istnieje. Przejdź do kroku 2 - /sdebug whodunit.

/sdebug whodunit - KROK 2: kto jest winny wyciekowi?

Kiedy wpisywać: zaraz po tym, jak /sdebug leak pokazał wysoki procent (wyciek potwierdzony). Wcześniej nie ma sensu - jeśli nie ma wycieku, nie ma powodu szukać winowajcy.

To polecenie wykonuje podobne kroki:

  1. Przeprowadza ręczne sprzątanie śmieci (serwer może zamrzeć na kilka sekund).
  2. Znajduje wszystkie martwe moby, które ktoś wciąż trzyma.
  3. Śledzi, kto dokładnie je trzyma, i przez który mod przechodzi ta referencja.
  4. Wydaje listę: jaki mod ile martwych obiektów zatrzymuje, z nazwą pliku i miejscem w kodzie.

Nie trzeba niczego wcześniej konfigurować. Wynik wygląda tak:

     KTO TRZYMA WYCIEK
  prześledzono 14203 obiektów do posiadacza w 8 s
      zatrzymanych obiektów, według modów    
    14203  <- Rust and Rustbound Creatures
        plik  : RustboundCreatures.dll
        typ   : RustCreaturesReworked.BowtornTuning
        pole  : MoveSpeedBaselines
       18  <- Inny mod
        3  <- vanilla / silnik

Pierwsza linia - główny winowajca. Następnie decydujesz: usunąć mod, zaktualizować go, lub napisać do autora o problemie.

/sdebug entities - ile łącznie żywych mobów jest w świecie

Kiedy wpisywać: w dowolnym momencie, gdy chcesz zrozumieć, czy faktycznie jest dużo mobów na świecie, czy tylko "wiszą" one w pamięci. Przydatne w połączeniu z /sdebug leak - razem odróżniają wyciek od rzeczywistego natłoku mobów.

Pokazuje, ile istot gra sama uważa za załadowane, z podziałem na gatunki i na najbardziej "zaludnione" obszary mapy.

Po co: odróżnić wyciek od rzeczywistego natłoku. Jeśli polecenie pokazuje 80 000 mobów - one naprawdę są w świecie, coś zepsuło limity spawnu. Jeśli pokazuje 200, a /sdebug leak znajduje przy tym tysiące "martwych" - to znaczy, że moby dawno zniknęły, ale wiszą w pamięci. To jest wyciek.

Inne

  • /sdebug threshold [ms] - od jakiego czasu trwania freeze trafia do logu (domyślnie 500 ms = pół sekundy).
  • /sdebug lang [kod] - język komunikatów (patrz niżej).
  • /sdebug reset - wyczyszczenie zebranych statystyk.

Jak czytać blok "ZACIĘCIE" (zawieszenie serwera) czyli /sdebug stalls

 

Każdy taki blok to jeden przechwycony freeze. Poniżej omówiono każdą linię na rzeczywistym przykładzie.

ZACIĘCIE main-wątku
  Czas                 : 20:19:12.952
  Czas trwania         : 751.7 ms

Czas - kiedy wystąpił freeze. Czas trwania - jak długo serwer stał. 751.7 ms = 0.75 sekundy serwer nie odpowiadał. Zwykły tik trwa ~50 ms, więc to 15 razy dłużej niż norma - gracze odczuli to jako zacięcie.

na co poszedł czas (delty za okno zacięcia)
  GC pause             : 697.6 ms  (93%)

Najważniejsze, rozbierzmy szczegółowo.

GC pause - to czas, w którym serwer stał z powodu sprzątania śmieci (GC = garbage collector, zbieracz śmieci). Sprzątanie - to moment, w którym system zamiera, przeszukuje pamięć i wyrzuca niepotrzebne obiekty. Dopóki trwa sprzątanie, serwer nie tyka.

  • 697.6 ms - ile dokładnie trwało sprzątanie wewnątrz tego freezu.
  • (93%) - jaką część całego freezu ono zajęło.

Czyta się to tak: freeze trwał 751.7 ms, i z tego 697.6 ms (93%) to sprzątanie śmieci. Czyli prawie cały freeze to GC. Znaczy to, że winne jest właśnie ono, a nie coś innego. Gdyby było tu (5%) - GC nie miałoby z tym nic wspólnego, przyczyny trzeba by szukać gdzie indziej.

  CPU procesu         : 187.5 ms  (25%)  <= LICZYŁ lub CZEKAŁ: oto odpowiedź

CPU procesu - ile podczas trwania freezu serwer faktycznie pracował procesorem (obliczał), a nie tylko stał w miejscu.

  • 187.5 ms - tyle serwer liczył.
  • (25%) - to 25% czasu trwania freezu.

Kluczowa myśl: freeze trwał 751 ms, a serwer liczył tylko przez 187 ms. Gdzie podziało się pozostałe 564 ms? Serwer je przeczekał, nic nie robiąc. To odróżnia "serwer ciężko pracował" od "serwer zawiesił się w oczekiwaniu". Gdyby było tu (95%) - serwer rzetelnie harował. A (25%) oznacza - głównie czekał.

  ThreadPool latency   : 5.6 ms

Na ile opóźniały się zadania w tle. Drobiazg, rzadko ważny. Duża liczba (sekundy) oznaczałaby, że wątki w tle są zapchane - tutaj wszystko w normie.

  tło PRZEZ 9.3 s PRZED zacięciem (oto faktyczne obciążenie)
  Alokacje             : 23.0 MB/s
  CPU procesu          : 20.6% od jednego rdzenia

To nie jest informacja o samym freezie, ale o 9.3 sekundy przed nim - aby zrozumieć, co działo się na serwerze w spokojnym momencie, tuż przed zacięciem.

  • Alokacje 23.0 MB/s - z jaką prędkością kod tworzył w pamięci nowe obiekty tymczasowe. Im więcej, tym częściej system musi usuwać śmieci. 23 MB/s - to umiarkowanie. Setki MB/s - to już mod-śmieciarz, który zapycha pamięć i prowokuje częste sprzątania.
  • CPU 20.6% od jednego rdzenia - jak bardzo serwer był zajęty przed freezem. 20% - to praca na luzie. Gdyby było tu pod 100% - to znaczy, że serwer i tak już sapał, a freeze nastąpił na granicy wytrzymałości.
  --- pamięć ---
  Przyczyna ostatniego GC : gen0, AllocSmall, NonConcurrent (BLOCKING)

Dlaczego uruchomiło się sprzątanie. Rozszyfrowanie pojęć technicznych:

  • gen0 / gen1 / gen2 - "generacja", głębokość sprzątania. gen0 - lekkie, szybkie, tylko świeże śmieci. gen2 - pełne i ciężkie, skanuje całą pamięć (to ono daje długie pauzy). Tutaj gen0 - najlżejsze.
  • AllocSmall - przyczyna: "w pamięci skończyło się miejsce na małe obiekty". To sprzątanie naturalne, pamięć sama się przepełniła. Przeciwieństwem jest Induced, kiedy sprzątanie wywołał ręcznie jakiś mod (wtedy trzeba szukać winowajcy).
  • BLOCKING - sprzątanie było "blokujące": serwer stał w miejscu, dopóki ono trwało. Bywa też Background - w tle, niemal bez zatrzymywania.
  Kolekcje w oknie (GC) : gen0 +1, gen1 +0, gen2 +0

Ile razy wystąpiło sprzątanie poszczególnych poziomów podczas freezu. gen0 +1 - jedno lekkie sprzątanie. Gdyby było tu gen2 +1 - to byłoby ciężkie, pełne sprzątanie, w pełni wyjaśniające pauzę trwającą setki ms.

  Zaalkowano w oknie : 13 MB  (przy zamrożonym main to niemal zawsze ~0 — mało miarodajne)

Ile pamięci utworzono podczas trwania freezu. Zwykle mało pouczające (bo serwer stał), sam mod to zaznacza - nie zwracaj uwagi.

  Heap (Sterta)        : 4027 MB -> 4031 MB

Heap - całkowity rozmiar pamięci przeznaczonej na obiekty (sterta) przed i po freezie. Tutaj prawie się nie zmienił. Jeśli po sprzątaniu sterta zauważalnie spadła (np. 4027 > 2800) - GC znalazło sporo śmieci i je wyrzuciło. Jeśli nie spada, a jest duża - to oznaka wycieku (są śmieci, ale nie można ich wyrzucić, bo ktoś je trzyma).

 Committed : 4226 MB, sfragmentowano 449 MB (11% sterty) 
  • Committed - ile pamięci serwer zarezerwował w systemie (zazwyczaj nieco więcej niż heap).
  • Sfragmentowano 449 MB (11%) - "dziurawość" pamięci. 11% - do przyjęcia. 25%+ - to już przeszkadza.
  Working set / commit : 4396 MB / 4509 MB  (w RAM 97%)

Ile pamięci serwera faktycznie siedzi w szybkiej pamięci operacyjnej (RAM), a nie zeszło na powolny dysk.

  • w RAM 97% - niemal cała pamięć serwera jest w RAM-ie. To dobrze.
  • Gdyby było tu np. w RAM 60% - oznaczałoby to, że 40% pamięci system zrzucił na dysk (do pliku wymiany/pagefile), a sprzątanie GC musi wyciągać ją z powrotem z dysku - to jest powolne. Oznaka braku pamięci RAM w maszynie.
  Page faults w oknie  : +1573

Ile razy podczas freezu serwer musiał sięgać po pamięć na dysk, bo nie znalazł jej w pamięci operacyjnej. Trochę - to norma. Tysiące, dziesiątki tysięcy - wyraźny sygnał, że brakuje RAM na maszynie i serwer używa pliku wymiany (swap).

  Obciążenie pamięci (Memory load) : 113274 MB / 39060 MB  (próg 124992 MB, wolne -)

Jak bardzo zajęta jest pamięć na całej maszynie (nie tylko dla twojego serwera - na całym węźle fizycznym hostingu).

  • 113274 MB - ile zajęte jest w tej chwili na maszynie.
  • próg 124992 MB - czerwona linia, po przekroczeniu której system zaczyna wpadać w panikę i agresywnie sprzątać śmieci.
  • Jeśli pierwsza liczba zbliża się do progu - to znaczy, że pamięci na maszynie jest na styk. Często to nie z twojego powodu, lecz przez inne serwery na tym samym sprzęcie.
  kod
  Main był wewnątrz      : (profiler wyłączony)

Gdyby profiler był włączony (/sdebug profile on), stałaby tutaj nazwa fragmentu kodu, w którym utknął serwer w momencie freezu. Jeśli wyłączony - znaczy brak informacji, co jest normalne podczas rutynowej diagnozy.

  WERDYKT : GC CZEKAŁ, a NIE LICZYŁ: 187.5 ms CPU na 751.7 ms pauzy.
            To hard page faults — sterta wyładowana do pagefile,
            GC wyciąga ją z dysku. Problem z pamięcią MASZYNY.

Gotowy wniosek zapisany prostym tekstem. Mod sam generuje go na podstawie wierszy powyżej. W tym przypadku mówi: sprzątanie śmieci trwało 751 ms, lecz serwer z tego czasu przetwarzał tylko 187 ms - resztę czasu czekał na dysk. Powód - zabrakło pamięci operacyjnej na maszynie, część sterty zeszła na dysk i sprzątacz czołgał się podnosząc ją z powrotem. Winny jest sprzęt hostingu, a nie kod modów.


Jak czytać werdykt w dwóch słowach

Wszystko sprowadza się do porównania dwóch liczb: GC pause (ile serwer stał przez sprzątanie) oraz CPU procesu (ile w tym czasie faktycznie liczył).

  • GC pause duża + CPU niemal równe jej > sprzątanie rzetelnie pracowało. Rozwiązaniem jest zmniejszenie sterty lub przyspieszenie GC (Server GC).
  • GC pause duża, a CPU małe (jak tutaj: 697 ms pauzy, 187 ms pracy) > sprzątanie nie liczyło, lecz czekało na dysk. Rozwiązanie to dodanie pamięci na maszynie - zgłoś do hostingu.
  • GC pause ≈ 0, a CPU duże > GC nie ma nic do rzeczy, winny jest ciężki kod. Szukaj moda przy użyciu /sdebug profile.
  • Obydwa małe > serwer po prostu czekał (na dysk lub blokadę / lock).

Konfiguracja moda

 

Przy pierwszym uruchomieniu tworzy się plik ModConfig/ServerDebuggerConfig.json:

{
  "Language": "en",
  "StallThresholdMs": 500,
  "WatchedModMarkers": [ "xskills", "xlib", "xleveling", "xeffects" ]
}
  • Language - domyślny język komunikatów.
  • StallThresholdMs - od jakiego czasu trwania (w milisekundach) freeze uważany jest za wart zapisania do logu. 500 = pół sekundy.
  • WatchedModMarkers - podpowiedź dla /sdebug profile oraz /sdebug findroot, na które mody zwracać uwagę domyślnie. Wartości takie jak xskills, xlib itp. są tu podane tylko dla przykładu (mod początkowo pisany był pod debugowanie tych konkretnych modów). To nie jest zależność: sam ServerDebugger od modów xskills/xlib w żaden sposób nie zależy i działa na dowolnym serwerze z każdymi modami. Jeśli chcesz - możesz je wymazać i wpisać swoje, albo zostawić tak, jak są. Główne komendy (whodunit, leak, entities, stalls, gc, gccallers, env) zignorują tę listę i i tak będą działać poprawnie. Zwykły gracz nie musi tego ruszać.

Język

 

Aby zmienić język "w locie":

/sdebug lang pl

Wybór jest zapisywany. Komenda wpisana bez parametru pokaże aktualny język i listę dostępnych.

Dodawanie własnego języka: skopiuj plik assets/serverdebugger/lang/en.json do pliku z odpowiednim kodem (np. pl.json) i przetłumacz w nim wartości. Placeholdery takie jak {0}, {1} oraz komendy zaczynające się od /sdebug ... muszą pozostać nienaruszone - tłumacz jedynie tekst dookoła. Plik zostanie załadowany automatycznie. Jeśli jakiegoś tekstu będzie brakowało w nowym pliku, automatycznie użyty zostanie w jego miejscu język angielski, dlatego tłumaczenie można przygotowywać etapami.

Słowa czysto techniczne (jak AllocSmall oznaczające przyczynę usuwania czy nazwy w kodzie w logu findroot) są intencjonalnie nieprzetłumaczone, bo to identyfikatory i jako takie powinny pozostać bez zmian.


 

Przyspieszyć sprzątanie śmieci (jeśli env pokazało Server GC : False)

 

 

To ten przypadek "jak to naprawić", o którym wspomniałem w opisie komendy /sdebug env. Jeśli komenda wykazała Server GC : False na wydajnym serwerze, to znaczy że sprzątanie śmieci odbywa się tylko w jednym wątku (powoli), a lagi będą trwać dłużej niż by mogły. Rozwiązaniem jest edycja jednego z plików konfiguracyjnych.


Co należy zrobić:

  1. Używając menedżera plików hostingu odszukaj plik VintagestoryServer.runtimeconfig.json (znajduje się tam, gdzie same pliki serwera).
  2. Przede wszystkim zrób jego kopię zapasową - w razie, gdybyś coś popsuł, szybko cofniesz zmiany.
  3. Otwórz ten plik. Wewnątrz zobaczysz sekcję configProperties. Dopisz do niej te cztery linijki (nie zapomnij o przecinku na końcu poprzedniego wiersza!):
"System.GC.Server": true,
"System.GC.Concurrent": true,
"System.GC.HeapCount": 6,
"System.GC.HeapHardLimitPercent": 30

Cały plik w finalnej postaci będzie wyglądał mniej więcej tak:

{
  "runtimeOptions": {
    "tfm": "net10.0",
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "10.0.0"
    },
    "configProperties": {
      "System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
      "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false,
      "System.Runtime.TieredPGO": true,
      "System.GC.Server": true,
      "System.GC.Concurrent": true,
      "System.GC.HeapCount": 6,
      "System.GC.HeapHardLimitPercent": 30
    }
  }
}
  1. Zapisz plik, a następnie całkowicie zrestartuj serwer - nie wystarczy polecenie "reload", trzeba to zrobić przez restart procesu. Te ustawienia są ładowane wyłącznie w momencie uruchamiania, więc przy "reloadzie" po prostu nie zostaną odczytane.
  2. Dla weryfikacji wpisz: /sdebug env. Wiersz powinien przyjąć wartość Server GC : True, a statystyka Pause time % powinna diametralnie spaść.


Co oznaczają wymienione wiersze (mówiąc po ludzku):

  • Server GC - jest najważniejsze, to ono aktywuje używanie kilku wątków do szybkiego usuwania śmieci, zamiast jednego.
  • Concurrent - sprawia, że część czynności GC ma miejsce w tle i nie blokuje (nie zawiesza) całego serwera.
  • HeapCount - określa, w ilu maksymalnie wątkach (na ilu rdzeniach) wolno się rozprzestrzenić sprzątaniu. 6 to bezpieczna wartość, dzięki temu będzie szybko, a jednocześnie gra nie zajmie całości pamięci (gdyby jej nie zablokować, proces pochłaniałby z miejsca niemal całą operacyjną).
  • HeapHardLimitPercent - całkowity pułap RAM dla tego serwera, jest zabezpieczeniem przed drastycznym przepełnieniem operacyjnej przez ten konkretny proces. Zwróć uwagę: zwłaszcza jeśli hosting był tani, instalacja potrafi "widzieć" RAM na całej fizycznej jednostce w DC (zamiast tylko limitu zakupionego przez gracza), a wtedy wyliczony tu procent jest liczony od całości wielkiej płyty - tak wyliczone np. 30% maszyny stanowić może wartość znacznie przekraczającą plan, co grozi zamknięciem procesu przez panel. Jeśli twój plan to mało RAM (np. 4 czy 6GB), ustaw to bezpiecznie na mniejszą liczbę (chociażby na 12-15).

Efekty i rezultaty:

Zabieg ten na funkcjonującym prawdziwym serwerze obniżył czas przerw z blisko 28% do poziomu poniżej 1%, a zacięcia (freezy) będące efektem czyszczenia śmieci przez GC stały się ledwo widoczne. Nie łata to samego problemu istnienia wycieku na serwerze (tu musisz wciąż wyszukać sam winny mod w whodunit i go np. usunąć z paka), natomiast każdy przypadek zwyczajowego usuwania "legalnych" śmieci zostaje zwielokrotniony pod kątem szybkości wykonania.


Report Page