Obszerny poradnik dotyczący optymalizacji serwerów Minecraft (1.13+)

Tagi: #<Tag:0x00007f2adf642010> #<Tag:0x00007f2adf641d68> #<Tag:0x00007f2adf641c50>

:zap: Obszerny i kompleksowy poradnik dotyczący optymalizacji serwerów Minecraft (1.13+)
:point_down: Spis treści:

  1. Wprowadzenie
  2. Wybór specyfikacji serwera i sztywne liczenie zasobów?
  3. Zoptymalizowana linia startowa dla serwera Minecraft
  4. Wybór silnika
  5. Przydatne wtyczki (pluginy) na serwerach, jakie i ile wgrywać, by nie zwariować?
  6. A co z tymi skryptami… Lagują czy nie lagują?
  7. Timingi, czyli co laguje mój serwer, problem z entities
  8. Optymalizacja plików konfiguracyjnych serwera
  9. Pregenerowanie całej mapy przed startem serwera
  10. Kopie zapasowe serwera
  11. Panel zarządzania serwerem
  12. Instalacja SWAP na serwerze jako dodatkowego buforu pamięci
  13. Optymalizacja villagerów na wersjach Minecraft 1.14+
  14. Automatyczny restart serwera w nocy
  15. Obciążenie łącza, ping do serwera, ataki
  16. Podsumowanie

:closed_lock_with_key: Jeśli szukasz informacji o zabezpieczeniu swojego serwera, sprawdź inny mój poradnik stale aktualizowany o nowe treści: Kompleksowy poradnik dotyczący bezpieczeństwa serwerów Minecraft.


1. Wprowadzenie
Minecraft jest grą napisaną w języku Java. W celu zoptymalizowania działania należy dołożyć wszelkich starań do kodu klienta gry oraz silnika serwera, aby działała ona wydajnie. Ze względu na otwartość świata w grze i mnogość funkcji często jest to trudne, również jeśli chodzi o serwery. Utrzymanie dużego publicznego serwera wymaga odpowiedniej wiedzy technicznej i mocy obliczeniowej serwera. Ale w tym poradniku postaram się pokazać, że z tej specyfikacji maszyny, którą być może już posiadasz można, a nawet trzeba wycisnąć znacznie więcej!
Serwery oparte na starszych wersjach gry (tj. poniżej 1.13) wymagały mniej zasobów i po prostu działały znacznie lepiej. Dziś na najnowszej wersji (jaką w momencie pisania tego poradnika jest 1.15.2) utrzymanie dużej ilości graczy na pojedynczej instancji serwera jest praktycznie niemożliwe na znanych silnikach Spigot/PaperSpigot bez ich patchowania, czyli zaawansowanej modyfikacji. Nadchodząca wersja 1.16 z nowym światem netheru najpewniej tego nie zmieni na lepsze. Ale spokojnie! Są na to rozwiązania, które możesz wykonać bez większego problemu sam i realnie wpłynąć na wydajność Twojego serwera. Wszystko piszę z perspektywy człowieka z ośmioletnim doświadczeniem w prowadzeniu dużych serwerów Minecraft (+400 osób).
Warto rozgraniczyć też na początku typy lagów, bo często jedno określenie używane jest błędnie do różnych problemów:

  • lagi po stronie serwera (najczęściej dostrzegamy je przez spadek ilości TPS),
  • lagi w postaci problemów z połączeniem (wysoki ping, niestabilność połączenia),
  • lagi po stronie klienta gracza (spadek ilości FPS).
    Kiedy mamy już konkretnie rozgraniczone dane problemy możemy przejść do rzeczy. Gotowy do lektury? Zaczynamy więc! Będzie merytorycznie, konkretnie, czyli tak, jak oczekujesz. Jedziemy!

2. Wybór specyfikacji serwera i sztywne liczenie zasobów?
Temu tematowi poświęcę nieco mniej uwagi, bo skupiamy się na tym, co możemy zrobić, aby zoptymalizować serwer na tym co już masz. Oczywiście z całego serca polecam usługi hostingu, na którego forum się znajdujesz i mówię to obiektywnie, serio! Z doświadczenia wiem, że znane hostingi serwerów Minecraft stosują tzw. overselling, czyli upychają na jednej maszynie zbyt dużo serwerów klientów przez co są one przeciążone i nie działają płynnie.
:thinking: No dobra, ale oferta jest szeroka, co tu wybrać?

:fr: Oferta FR jest nieco tańsza w odniesieniu do ilości pamięci RAM. Ping będzie większy o około ~ 20-25ms, ale przy serwerze Minecraft ma to małe znaczenie. Dopiero przy pingu wyższym niż 100ms np. na serwerach PvP może być odczuwalna różnica wpływająca na jakość rozgrywki.

:poland: Oferta PL ma mocniejsze procesory (a CPU jest często ważniejsze niż RAM!) i szybsze dyski oraz niższy ping.
Ja na publicznej sieci serwerów korzystam z lokalizacji FR i jestem zadowolony. W 99% przypadków Ty też będziesz.

Im więcej vCPU, czyli wątków procesora przypisanych dla Twojej maszyny tym lepiej.
Kiedyś utarł się trochę mit z wyliczaniem pamięci RAM na gracza. Najpierw było to sztywno 64MB, potem nieco więcej. Pamiętajmy, że zapotrzebowanie na pamięć jest zmienna i zależna od np. ilości i typu pluginów, skryptów, zachowania graczy, dlatego warto zostawić sobie jakiś zapas.

:exclamation: Uwaga! Pamiętaj, żeby nie przypisywać całej dostępnej pamięci RAM na Twoim VPS do serwera Minecraft. System oraz inne usługi na nim uruchomione (jak np. Apache, TeamSpeak 3) również jej potrzebują. Sprawdź zużycie pamięci komendami top lub htop i dostosuj ją odpowiednio. Jeśli masz VPS z 4GB RAM, systemem Ubuntu 18.04 i oprócz jednej instancji serwera Minecraft serwer Apache (swoją drogą możesz zmienić na serwer nginx, który jest mniej zasobożerny), to przypisz do 3GB RAM serwerowi Minecraft, nie więcej! Pamiętajmy też o tym, że zużywanie maksymalnej przypisanej ilości pamięci RAM przez serwer w wielu sytuacjach nie jest powodem do niepokoju, bowiem maszyna wirtualna JVM rezerwuje sobie tę pamięć, a w razie potrzeby zwalnia.

:warning: Pamiętaj, że korzystanie z serwera VPS wymaga wiedzy na temat konfiguracji systemu Linux. Więcej znajdziesz w sekcji poradników na forum.
:speech_balloon: Pss! Jeśli chcesz zamówić swój serwer VPS z 10% rabatem, możesz użyć kodu CRAFTCODE.PL.

3. Zoptymalizowana linia startowa dla serwera Minecraft
Uruchamiając serwer Minecraft korzystamy z technologii Java (najczęściej JDK w wersji 8 lub 11). Wersja 11 może być nieco wydajniejsza od 8, ale za to niektóre pluginy nie są jeszcze z nią kompatybilne. Do uruchomienia serwera możemy użyć prostej komendy, ale lepiej jest użyć dodatkowych, zalecanych flag. Usprawniają one ogólne działanie serwera, ładowanie chunków i są dostosowane pod najnowsze wersje gry.

Dokładna zalecana linia startowa:
java -Xms10G -Xmx10G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar paperclip.jar nogui

Tworzymy plik o nazwie np. start.sh w folderze z serwerem i wklejamy powyższą zawrtość. Pamiętamy też o nadaniu uprawnień do wykonywania się skryptu komendą chmod +x start.sh. W argumencie Xms oraz Xmx zmieniamy przypisaną ilość pamięci do serwera (z zachowaniem reguł opisanych w poprzednim punkcie). Xms to początkowa ilość, Xmx maksymalna. Nazwę naszego pliku z silnikiem zmieniamy po argumencie -jar. Serwer uruchamiamy komendą ./start.sh.
:thinking: Co dokładnie robią te flagi? Włączają implementację GC pod nazwą G1GC. Służą zminimalizowaniu negatywnych skutków czasu trwania procesu GC, w którym uwalniana jest pamięć (usuwane są niepotrzebne już obiekty). Parametry te mają na celu możliwe zmniejszenie tzw. pause time, który jest odczuwalny w postaci zwyczajnego laga.

Źródło: https://aikar.co/2018/07/02/tuning-the-jvm-g1gc-garbage-collector-flags-for-minecraft/

4. Wybór silnika
Skoro flagi startowe dla silnika mamy już omówione, to pora zastanowić się nad jego wyborem. Pod uwagę bierzemy w zasadzie trzy dostępne publicznie. Czwartym jest BungeeCord, ale to tak naprawdę nie silnik, a proxy, które spina nam serwery oparte na jednym z trzech silników.
Dlaczego nie ma tu CraftBukkita? Bo jego wsparcie jest już bardzo kiepskie i w zasadzie każdy korzysta jedynie z trzech wymienionych poniżej.

  • Spigot - niejako kontynuacja CraftBukkita stawiająca na wydajność i wsparcie szerokiego community. Aktualizowany do najnowszych wersji, oferujący dobrą wydajność na małej i średniej wielkości serwerach. Link do strony silnika: https://www.spigotmc.org/
  • PaperSpigot - zalecany fork Spigota w szczególności dla większych serwerów oczekujących lepszej optymalizacji i większej ilości opcji dostosowania opcji gameplayu, które mogą wpłynąć na wydajność. Na mniejsze serwery również się nada. Link do strony silnika: https://papermc.io/
  • Tuinity - stosunkowo nowy silnik. Jest to fork PaperSpigota (fork forka, huh!) dodający szereg patchy wpływających w znaczny sposób na wydajność serwerów opartych o najnowszą wersję 1.15.2, z którą są największe problemy. Link do strony silnika: https://github.com/Spottedleaf/Tuinity (pobrać możesz tu: https://ci.codemc.io/job/Spottedleaf/job/Tuinity/). Uwaga! Projekt do niedawna wymagał JDK11, ale już można go uruchomić również na JDK8!
  • BungeeCord - proxy do łączenia różnych serwerów. Wymaga znacznie mniej zasobów (twórca zaleca 512MB RAM na 500 graczy, ale za to potrafi zużyć dużo CPU przy większej ilości graczy). Pamiętaj, że pluginy zainstalowane po stronie proxy też zużywają zasoby. Używanie niebezpiecznych pluginów takich jak do banowania czy innego wpływania na serwer ze względów bezpieczeństwa często nie jest zalecane. Generalnie aktualnie zalecane są lepiej zabezpieczone i z dodaną obsługą wielu wersji forki np. Waterfall (autorstwa twórców PaperSpigota), Travertine, FlameCord lub płatny Aegis.
    Istnieją też płatne forki Spigota wpływające na optymalizację przez wielowątkowść czy łatanie luk związanych z crasherami np. AtomSpigot lub SSSpigot.

5. Przydatne wtyczki (pluginy) na serwerach, jakie i ile wgrywać, by nie zwariować?
Najpopularniejsze i zarazem najpotrzebniejsze pluginy to:

  • EssentialsX - nowa wersja pluginu Essentials, który dostarcza szkielet naszego serwera w postaci przydatnych komend, posiada również wbudowany system ekonomii, konfiguracji chatu i wiele innych. Link do pluginu: https://www.spigotmc.org/resources/essentialsx.9089/
  • WorldEdit - plugin do szybkiej edycji świata np. zmiany bloków, równania terenu czy tworzenia cylindrów, kul itp. Istnieje również jego wydajniejsza wersja działająca asynchronicznie, czyli w dużym uproszczeniu w tle. Link do pluginów: https://dev.bukkit.org/projects/worldedit oraz https://www.spigotmc.org/resources/asyncworldedit.327/
  • WorldGuard - plugin działający razem z WorldEditem. Służy do ochrony świata czyli tworzenia tzw. cuboidów. Na wyznaczonych terenach możemy ustawiać flagi definiując tym samym sposób zachowania gracza, czyli umożliwienie mu bądź nie używania PvP, kładzenia bloków czy wejścia na dany obszar. Link do pluginu: https://dev.bukkit.org/projects/worldguard
  • AuthMe Reloaded - jeśli zezwalamy graczom non-premium na wejście na nasz serwer musimy autoryzować ich konta w celu zapobiegnięcia podszywaniu się. Link do pluginu: https://dev.bukkit.org/projects/authme-reloaded
  • LuckPerms - plugin służący tworzeniu grup, nadawaniu im permisji, czyli uprawnień.
    :information_source: Uwaga! Nie zaleca się korzystania z nieaktualizowanego pluginu PermissionsEx. Jedna z komend potrafi scrashować serwer, są problemy z kompatybilnością, a część funkcjonalności powoduje duże spadki wydajności serwera. Użyj LuckPerms!

To na tyle z absolutnych podstaw. Generalnie każdy serwer rządzi się swoimi prawami i potrzebuje inną ilość pluginów. Pamiętajmy jednak, aby korzystać z wtyczek ze sprawdzonych źródeł i autorów (np. korzystanie z pluginów z wycieków ze znanych stron nie jest dobrą opcją). Nie wgrywajmy też masy pluginów, których funkcje się pokrywają.
Istnieją również pluginy do obsługi wielu wersji np. ProtocolSupport czy ViaVersion. Możemy ich używać, ale pamiętajmy, że mogą wpływać na problemy z kompatybilnością u graczy grających na np. starszych wersjach gry. Warto zwrócić też uwagę na formy zapisu danych w pluginach. Rozróżniamy typ zapisu lokalnego w formie plików YAML/JSON i w tym przypadku jeśli metoda jest odpowiednio napisana może być wydajna. Tak samo ma się sprawa przy bazach danych. MySQL, SQLite czy Redis to najpopularniejsze z nich, mają swoje wady i zalety, ale warto zwrócić uwagę na czas dostępu do bazy (jeśli nie jest hostowana lokalnie) oraz klasę od zarządzania bazą w pluginie, na ile jest zoptymalizowana, czy wykonuje zapis asynchronicznie itp. Chwilowy lag na serwerze przy wykonywaniu konkretnych komend może mieć związek właśnie z niezoptymalizowanym zaspiem. Pamiętajmy też o regularnym aktualizowaniu pluginów, gdyż są łatane wszystkie błędy mogące powodować wycieki pamięci itp.

6. A co z tymi skryptami… Lagują czy nie lagują?
Wojna o plugin Skript i to czy jego używanie jest dobre dla serwera czy nie trwa od wielu lat. Nie chcę otwierać tej puszki pandory i powiem tyle. Jeden czy drugi skrypt o podstawowej funkcjonalności jak wywoływanie komend z wiadomością nie zabije nam całkowicie serwera. Ale korzystanie z wielu bardzo rozbudowanych skryptów, które zapisują dużą ilość danych w zmiennych już nie jest dobrym rozwiązaniem. Jak we wszystkim ważny jest więc zdrowy rozsądek. Problemem Skripta jest przetwarzanie danych w głównym wątku serwera, brak wielowątkowości. Na większych serwerach zdecydowanie nie polecam używać tego pluginu.

7. Timingi, czyli co laguje mój serwer, problem z entitites
Zanim przejdziemy do części o konfiguracji silnika warto wspomnieć o timingach, czyli potężnym narzędziu wbudowanym w każdy silnik oparty o Spigota. Pozwala na uzyskanie podstawowych informacji na temat działania naszego serwera. Nie jest to narzędzie idealne, pełny obraz mogą dać jedynie pełnoprawne profilery, ale warto na początku zainteresować się tym narzędziem, bo jest wbudowane w silnik, szybkie i proste w użyciu.
Warto wspomnieć coś o TPS. Czym one są? Główna pętla gry wykonuje 20 cykli (tzw. ticków) w ciągu sekundy i wtedy mamy 20 TPS, wszystko gra. Jeśli jednak coś laguje nasz serwer, to obliczenia nie są w stanie być w takim czasie zrealizowane i wtedy owa ilość spada. Aby sprawdzić ich ilość używamy komendy /tps posiadając uprawnienia operatora na serwerze.
Przejdźmy teraz do rzeczy. Jak wykonać timingi na serwerze?

  1. Wpisujemy komendę /timings on.
  2. Czekamy minimum 3 minuty.
  3. Wpisujemy komendę /timings paste.

Odczytywanie informacji zawartych w timingach to już dość skomplikowana sprawa. Obszerny opis jest dostępny w języku angielskim pod tym adresem: https://www.spigotmc.org/wiki/timings/
Skracając sprawę do najważniejszych kwestii. Rzeczą, która najczęściej laguje serwery są tzw. entities, czyli np. pozostawione przedmioty na ziemi itp. Znany jest na najnowszych wersjach plugin EntityTrackerFixer. Zasada jego działania jest taka, że usuwa z przetwarzania co tick wszystkie entities, dopiero w momencie gdy gracz się do nich zbliży, to zaczyna to robić. Z moich testów wynika, że w niewielu sytuacjach może pomóc, przy tym niektórzy zgłaszali błędy np. przy wielu światach. Może nam pomóc też zmiana w Spigocie czasu usuwania itemów czy spawnowania mobów o czym niżej lub takie pluginy jak ClearLagg czy płatny ServerBooster.
Warto też zwrócić uwagę na sekcje z pluginami, czy jakieś konkretne działania, komendy, wydarzenia w pluginie nie pochłaniają zbyt dużo wspomnianych ticków. U góry timingów widzimy też ogólne statystyki takie jak średnia ilość TPS, graczy.

:information_source: Najważniejsze dane w wygenerowanym rapocie i co one oznaczają dla serwera:

  • Total - łączny czas poświęcony na obsługę zdarzeń
  • Sample Time - czas spędzony na zbieranie próbki do raportu
  • Average Entities - uśredniona ilość entity na serwerze podczas robienia testu
  • Average Players - uśredniona ilość graczy znajdująca się na serwerze podczas robienia testu
  • Average TPS - uśredniona ilość ticków na sekundę na serwerze podczas robienia testu

Dla pluginów widzimy następujące dane:

  • Total - ilość czasu którą plugin poświęcił na przetworzenie zdarzeń podczas testu
  • Pct - procentowa wartość powyższych danych

Dla konkretnych wtyczek możemy dostrzec następujące dane:

  • Pct Total - procent całkowitego czasu próbki poświęcony na dane zdarzenie
  • Pct Tick - procent czasu ticka dla danego zdarzenia
  • Total - całkowity czas poświęcony na dane zdarzenie
  • Avg - uśredniony czas poświęcony na dane zdarzenie
  • Count - ilość wywołanych zdarzeń obsłużonych przez daną wtyczkę
  • Vio - całkowita liczba naruszeń dla pluginu
  • Event - nazwa zdarzenia

Prostym i dość skutecznym (choć nie zawsze!) sposobem znajdowania lagów jest obserwacja kolumny Pct Tick. Jeśli widzimy tam dużą liczbę np. dla eventu PlayerMoveEvent, to znaczy, że jakiś plugin, który odpowiada za wykonywanie akcji podczas poruszania się gracza jest źle zoptymalizowany.

8. Optymalizacja plików konfiguracyjnych serwera
Kluczem do sprawnie działającego serwera jest właśnie ustawienie opcji konfiguracyjnych silnika. W zależności od trybu, efektu, który chcemy osiągnąć te opcje mogą się różnić, ale podam uśrednione wartości, których warto użyć, aby zoptymalizować nasz serwer nawet o 300%! Wszystkie omawiane pliki znajdują się w głównym folderze serwera. Możemy wygodnie je edytować przy użyciu edytora np. Sublime Text lub NotePad++. Pierwszy raz opiszemy też po polsku konfigurację silnika Tuinity, który jest idealnym wyjściem z sytuacji, kiedy mamy problemy z lagami na wersji 1.15.2.

:point_down: PLIK KONFIGURACYJNY BUKKIT.YML
spawn-limits
domyślnie: monsters:70, animals:10, water-animals:15, ambient:15
zoptymalizowane: monsters:50, animals:8, water-animals:3, ambient:1
Ograniczenie ilości spawnowania mobów. Wpływ na wydajność średni.

chunk-gc.period-in-ticks
domyślnie: 600
zoptymalizowane: 400
Szybsze odładowywanie chunków, może podwyższyć ilość TPS. Wpływ na wydajność średni.

ticks-per.monster-spawns
domyślnie: 1
zoptymalizowane: 4
Jak często serwer ma próbować spawnować potwory. Wpływ na wydajność średni.

Opcję auto-save pozostaw domyślnie, czyli na 6000, chyba, że masz osobny skrypt/plugin, który wykonuje za Ciebie cykliczne zapisywanie świata, wtedy ustaw 0.

:point_down: PLIK KONFIGURACYJNY SPIGOT.YML
mob-spawn-range
domyślnie: 8
zoptymalizowane: 4-8 (w zależności od ustawienia view-distance)
Definiuje maksymalną liczbę spawnowanych mobów w obrębie gracza na chunk. Wpływ na wydajność mała.

entity-activation-range
domyślnie: animals:32, monsters:32, misc:16
zoptymalizowane: animals:24, monsters:24, misc:8
Funkcja zmienia odległość w jakiej moby od gracza zaczynają się poruszać. Wpływ na wydajność średni.

tick-inactive-villagers
domyślnie: true
zoptymalizowane: false
Czy niezaładowani villagerowie mają mieć AI. W 1.14+ wpływ na wydajność ogromna (patrz punkt 13 poradnika).

merge-radius
domyślnie: item:2.5, exp:3.0
zoptymalizowane: item:4.0, exp:6.0
W jakiej odległości od siebie przedmioty i doświadczenie pozostawione na ziemi mają się łączyć. Wpływ na wydajność duży.

nerf-spawner-mobs
domyślnie: false
zoptymalizowane: true
Włączając to ustawienie moby ze spawnerów nie będą miały żadnej inteligencji. Wpływ na wydajność duży.

item-despawn-rate
domyślnie: 6000
zoptymalizowane: 2000-3000
Czas w tickach kiedy pozostawione przedmioty mają znikać. Domyślnie ustawienie to 5 minut. Można zmniejszyć. Wpływ na wydajność duży.

arrow-despawn-rate
domyślnie: 1200
zoptymalizowane: 300
Jak szybko mają znikać wystrzelone strzały. Wpływ na wydajność średni.

:point_down: PLIK KONFIGURACYJNY PAPER.YML
dla osób korzystających z silnika PaperSpigot.
max-auto-save-chunks-per-tick (1.14+)
domyślnie: 24
zoptymalizowane: 6
Zmieniamy jak wiele chunków serwer może zapisać w ciągu jednego ticka. Wpływ na wydajność bardzo duży.

optimize-explosions
domyślnie: false
zoptymalizowane: true
Nie wymaga większego tłumaczenia. Optymalizujemy algorytm eksplozji. Wpływ na wydajność średni.

mob-spawner-tick-rate
domyślnie: 1
zoptymalizowane: 2
Zmieniamy częstotliwość odświeżania spawnerów. Wpływ na wydajność średni.

disable-chest-cat-detection
domyślnie: false
zoptymalizowane: true
Wyłączamy możliwość siadania kotów na skrzynkach. Wpływ na wydajność mały.

container-update-tick-rate
domyślnie: 1
zoptymalizowane: 2-3
Jak często mają się odświeżać skrzynki. Wpływ na wydajność średni.

max-entity-collisions
domyślnie: 8
zoptymalizowane: 2
Jak sama nazwa mówi, definiuje ilość kolizji z różnymi rzeczami. Wpływ na wydajność mały.

grass-spread-tick-rate
domyślnie: 1
zoptymalizowane: 2-4
Zmienia ustawienie jak szybko ma rozrastać się trawa.

despawn-ranges
domyślnie: soft: 32, hard: 128
zoptymalizowane: soft: 24, hard: 96
Ustawienie jak daleko muszą znajdować się od nas moby, by zniknęły. Wpływ na wydajność średni.

hopper.disable-move-event
domyślnie: false
zoptymalizowane: true
Wpływ na wydajność: Wysoki
Ustawienie te określa czy hoppery mają wywoływać event przeniesienia przedmiotu z hoppera do innego klocka. Jeśli masz jakikolwiek plugin korzystający z InventoryMoveItemEvent to nie zmieniaj tego. Jeśli nie wiesz to też nie ruszaj.

non-player-arrow-despawn-rate
domyślnie: -1
zoptymalizowane: 40
Ustawienie jak szybko znikają strzały wystrzelone nie przez gracza. Wpływ na wydajność mały.

creative-arrow-despawn-rate
domyślnie: -1
zoptymalizowane: 40 (3 sekundy)
Ustawienie jak szybko znikają strzały wystrzelone na trybie gry kreatywnym. Wpływ na wydajność mały.

keep-spawn-loaded
domyślnie: true/false
zoptymalizowane: zależne od sytuacji
Jeśli gracze często migrują między mapami i co za tym idzie spawnami, to true, jeśli nie, to false.

prevent-moving-into-unloaded-chunks
domyślnie: false
zoptymalizowane: true
Zapobieganie wchodzeniu na niezaładowane chunki. Wpływ na wydajność średni.

use-faster-eigencraft-redstone
domyślnie: false
zoptymalizowane: true
Znacznie optymalizuje wszystkie mechanizmy z użyciem czerwonego proszku. Wpływ na wydajność bardzo duży.

:point_down: PLIK KONFIGURACYJNY SERVER.PROPERTIES
view-distance
Na pewno nie zostawiamy domyślnej wartości czyli 10. W zależności od potrzeb wybieramy od 3 do 10. Jest to odległość w chunkach generowania się mapy dla gracza.
network-compression-threshold
Domyślnie jest to 256. Jeśli mamy serwer spięty z BungeeCordem hostowany lokalnie (co ważne), to wpisujemy -1, a jeśli zwykły serwer, to ustawienie 512 może pomóc. Jest to ograniczenie wielkości pakietu przed jego kompresją.

:point_down: PLIK KONFIGURACYJNY TUINITY.YML
Tylko dla osób korzystających z silnika Tuinity.
no-tick-view-distance
Opcja dzięki której możemy bardzo zoptymalizować nasz serwer. Domyślne ustawienie -1 wyłącza ją, ale możemy ją odpowiednio dostosować w odniesieniu do wcześniej ustawionej opcji view-distance.
A co ona właściwie robi? Zmienia dla gracza sposób wyświetlania świata dalej od niego, a konkretnie nie ładuje np. AI mobów, dzięki czemu znacznie optymalizuje ładowanie mapy i przez to cały serwer. Więcej o tym w języku angielskim przeczytasz tu. Opcja została niedawno zaimplementowana i wciąż jest w fazie rozwoju.
Pamiętajmy tez o możliwości wyłączenia dodatkowych światów jeśli ich nie potrzebujemy zmieniając odpowiednio funkcje allow-end oraz allow-nether.

Na podstawie własnego doświadczenia i poradników anglojęzycznych m.in. tego oraz tego.

9. Pregenerowanie całej mapy przed startem serwera
Często popełnianym błędem przez początkujących administratorów serwera jest start serwera z brakiem tzw. bordera czyli ograniczenia mapy i brakiem wygenerowania całej mapy. Gdy wchodzi większa ilość graczy na serwer i każdy zaczyna w innym rejonie generować chunki, to nawet najsilniejsza maszyna może tego nie wytrzymać. Dlatego używamy pluginu WorldBorder, aby najpierw ustawić ograniczenie mapy, a potem ją wygenerować. Gdy tak się stanie, graczowi wysyłane są jedynie już wygenerowane struktury, więc serwer zużywa znacznie mniej mocy obliczeniowej.
Aby ustawić border mapy używamy komendy /wb set 5000, gdzie liczba to promień mapy w ilości kratek od miejsca, w którym stoimy. Następnie, aby rozpocząć generowanie mapy wpisujemy /wb fill oraz /wb fill confirm i czekamy aż proces zostanie zakończony. Link do pluginu: https://www.spigotmc.org/resources/worldborder.60905/
Są też dostępne inne pluginy na najnowszych wersjach 1.14+ takie jak FastChunkPregenerator czy ChunkMaster. Ten pierwszy w przypadku korzystania z silnika PaperSpigot oferuje asynchroniczność, ale niektórzy zgłaszali z nim pewne problemy (np. brak generowania struktur), więc wybierz rozważnie i jeśli zależy Ci na sprawdzonym rozwiązaniu, to wybierz WorldBorder!

10. Kopie zapasowe serwera
Warto zautomatyzować proces wykonywania kopii zapasowych serwera. W razie awarii możemy łatwo wgrać taką kopię i cofnąć się do stanu, kiedy wszystko działało poprawnie. Do robienia kopii możesz użyć tego pluginu: https://www.spigotmc.org/resources/serverrestorer.48853/
:information_source: Poradnik o robieniu kopii zapasowej serwera na zewnętrzny serwer FTP/SFTP autorstwa @DBanaszewski pod tym adresem.

11. Panel zarządzania serwerem
Nie wszyscy lubią się z konsolą systemu Linux. Mi akurat przypadł do gustu taki sposób administrowania serwerem, pełna dowolność, ale dla ułatwienia zarządzania można zainstalować jeden z gotowych paneli. Najpopularniejsze z nich to Pterodactyl oraz PufferPanel. Możemy w nim wykonywać większość akcji czy właśnie śledzić zużycie zasobów w formie wykresów. :slightly_smiling_face: Dla bardziej zaawansowanych użytkowników fajną opcją jest też system Grafana do generowania graficznych opracowań zużycia zasobów.
Poradnik autorstwa @DoreK o instalacji jednego z przytoczonych paneli: Instalacja panelu Pterodactyl i uruchomienie serwera Spigot na VPS KVM.

12. Instalacja SWAP na serwerze jako dodatkowego buforu pamięci
Czym jest SWAP? To niejako przedłużenie dostępnej pamięci RAM. Jeśli mamy niski pakiet serwera (np. 4GB KVM FR) i zaczyna nam go brakować, to wtedy dysk może nam posłużyć jako dodatkowy bufor pamięci trzymając dane w plikach tymczasowych. Dyski SSD są szybkie, a NVMe jeszcze szybsze, dzięki czemu cała operacja może przejść dosyć sprawnie i w awaryjnych sytuacjach dużego zapotrzebowania uratować nasz serwer od lagów i w konsekwencji crasha spowodowanego np. błędem out of memory.
A więc teraz pora na poradnik w poradniku, czyli jak utworzyć plik swap na serwerze Ubuntu 18.04?

  • Logujemy się do SSH i wpisujemy najpierw komendę sudo swapon -s. Jeśli nic nam się nie pokaże, to znaczy, że możemy przejść dalej, bo funkcja nie jest uaktywniona.
  • Tworzymy plik swapu i nadajemy mu odpowiednie uprawnienia. Generalnie zasada jest taka, że powinniśmy nadać dwukrotność pamięci RAM, którą mamy na serwerze. Czyli jeśli mamy serwer z 2GB RAMu, to w swapie robimy 4GB. Używamy więc odpowiednio komend sudo fallocate -l 4G /swapfile oraz chmod 600 /swapfile.
  • Tworzymy nowy swap i przypisujemy plik do niego komendą sudo mkswap /swapfile.
  • Włączamy swap dla utworzonego pliku sudo swapon /swapfile.
  • Możemy sprawdzić teraz jak wygląda nasze ustawienie komendą sudo swapon -s.
  • Otwieramy plik /etc/fstab i dodajemy linijkę /swapfile none swap sw 0 0.
  • W pliku /etc/sysctl.conf dodajemy linijkę vm.swappiness=10.
  • Przeładowujemy konfigurację komendą sudo sysctl -p.
    I tyle! Bardziej obszerny poradnik w tym temacie stworzył @bopke: Tworzenie pliku swap na serwerze VPS.

13. Optymalizacja villagerów na wersjach Minecraft 1.14+
Od wersji 1.14 w górę niestety zostało kompletnie popsute zarządzanie AI villagerów. Rozwiązaniem jest albo ich wyłączenie. W niektórych przypadkach można zaobserwować spadek TPS do absurdalnie niskich wartości przez błąd z optymalizacją. Z doświadczenia wiem, że kiedy padały pytania o lagi na serwerach, to często to było powodem problemów.
Pluginy, które mogą pomóc w rozwiązaniu problemu (ale nie są konieczne, możemy ustalić w nich dowolne limity, jeśli chcemy inteligencję villagerów całkowicie wyłączyć, możemy to zrobić w konfiguracji silnika, co jest opisane wyżej):
https://www.spigotmc.org/resources/villager-optimiser-1-14-2-1-15.68517/
https://www.spigotmc.org/resources/limitpillagers-fix-outpost-spawns-and-more.69733/

14. Automatyczny restart serwera w nocy
Dobrą praktyką jest robienie regularnego restartu serwera. Pomaga to oczyścić pamięć, odciążyć na moment VPS. W szczególności serwery oparte o najnowsze wersje gry (>1.13) przetrzymują pewne dane w pamięci (często same pluginy też to robią w postaci np. HashMap czy ArrayList, co samo w sobie nie jest złe, ale jeśli jest źle napisane przez developera pluginu, to już pojawia się problem) warto więc taki restart wykonać. Można do tego użyć metody podanej przez @riko.dev w tym temacie na forum.

15. Obciążenie łącza, ping do serwera, ataki
Zdarza się, że lagi spowodowane są nie błędną konfiguracją serwera, a maszyny pod kątem sieci, chwilowych problemów z łączem u operatora czy atakiem DDoS (chwilowym wzrostem pingu i lagiem do momentu odfiltrowania). Starsze wersje mają też mnóstwo luk bezpieczeństwa, ale i na tych nowszych można się ich doszukać, dlatego warto dobrze zabezpieczyć serwer, aby zapewnić mu stabilność (sprawdź osobny poradnik umieszczony na początku tego tematu).
Aby sprawdzić zużycie łącza na serwerze możesz użyć pakietu nload. Zainstaluj go przy użyciu komendy apt install nload, a następnie uruchom poleceniem nload. Możemy też wykonać SpeedTest używając w tym celu oficjalnego repozytorium SpeedTest CLI.

16. Podsumowanie
Jak widzicie dostosowanie serwera tak, aby działał sprawnie wymaga wielu zabiegów, ale warto przynajmniej większość z nich wykonać, aby cieszyć się płynną grą. Wiele dużych serwerów działa na ostatniej dobrze zoptymalizowanej wersji 1.12.2 i z pluginem ViaVersion akceptuje połączenia z nowszych klientów i to też jakieś rozwiązanie, ale niezależnie od użytej wersji, silnika czy trybu te porady są w dużej mierze uniwersalne.


Data ostatniej aktualizacji: 17.05.2020 r.
Serdeczne podziękowania dla wszystkich autorów podlinkowanych poradników.
Razem dajemy wartość i szerzymy wiedzę wśród naszej społeczności. Dobra robota!
Szczególne podziękowania dla @Nieznajomy11, który podzielił się swoją ekspercką wiedzą z perspektywy osoby prowadzącej jeden z największych publicznych serwerów Minecraft w Polsce i znacząco wpłynął na dopracowanie nieścisłych treści.

14lajków

Bardzo ładny poradnik, jeszcze nie wszystko zbadałem, ale mam pytanie. Co w ogóle znaczą te poszczególne składniki linii startowej? I czy będzie taka sama, jak ktoś korzysta z jakiegoś panelu (PufferPanel, Pterodactyl)?

2lajki

Sugerowanie, że to wina języka, a nie developerów. Jakieś konkretne argumenty? :slight_smile:

Timingi nie są dokładnym narzędziem. Obejmują tylko punkty wcześniej zdefiniowane przez timing pointy w postaci wstawek kodu z patchy. Jedyny pełny obraz, dają pełnoprawne profilery.

Prove it. Wszystkie rozwiązania, które wymieniłeś, mogą być z powodzeniem użyte, nie odczujesz różnicy.

Problemem skripta jest koszt abstrakcji oraz niekompetencja osób piszących skrypty bez pojęcia o tym, że jest coś innego niż Server Thread, bo przez długi czas (nie wiem jak teraz) nie było żadnej wielowątkowości, a wykonywanie zapytań do MySQL czy WWW lub o zgrozo masowej edycji bloków bez kolejek, w głównym wątku wiadomo, jak się skończy.

Jakich plików tymczasowych i co zmienia restart aplikacji z nimi?

Demonizowanie struktury danych, a nie developerów, którzy nie potrafią wtyczek bez wycieków napisać.

@Nieznajomy11
Z zarzutem co do Javy to skrót myślowy. Nie jest tajemnicą, że Java jest raczej średnią platformą do pisania gier, szczególnie tego typu. W pełni się zgadzam, że gdyby kod był lepiej zoptymalizowany przez twórców, to gra działałaby lepiej. Nie traktuj tego jako zarzut do samego języka. Wiem, że są się napisać w nim optymalny kod.
P.S. Część dużych serwerów rezygnowała z np. BungeeCorda na rzecz alternatyw w GO podając jako główny argument optymalizację.

Timingi nie są najdokładniejszym sposobem na monitorowanie co laguje, ale większość podstawowych użytkowników dla których pisany jest ten poradnik nie będzie miało pojęcia jak korzystać i odczytywać dane z bardziej zaawansowanych narzędzi. W podstawowej formie chwilowe pobranie danych z serwera przez timingi może i tak dostarczyć nam potrzebnych informacji przy zachowaniu prostoty korzystania.

Nie będę się kłócił co do sposobu zapisu. Wydajnie napisana metoda zapisu w plikach lokalnych YAML czy może bardziej JSON jasne, że może być wydajna. Przykładem IridiumSkyBlock z którego korzystam. Ale są sytuacje i pluginy, w których użycie jakiejkolwiek bazy danych z szyfrowaniem jest oczywistą oczywistością zarówno dla bezpieczeństwa jak i optymalizacji.

Jeśli chodzi o Skript, to dokładnie to napisałem. Nie lubię demonizowania na zasadzie wgrasz Skript i serwer wyleci Ci w powietrze, ale ewidentnie nadmieniłem, że zaawansowane skrypty, które zapisują dużą ilość danych i nie robią tego asynchronicznie, to zabójstwo.

Co do zapisu i demonizowania struktury danych, tu ponownie może nieprecyzyjnie napisałem, ale założenie od początku było takie, żeby nie krytykować danej formy zapisu, tylko możliwość jej błędnej implementacji w pluginie.

Dzięki za konstruktywną krytykę, na Twoją odpowiedź liczyłem i jest wartościowa. Wkrótce doprecyzuję to, o czym wspomniałem w odpowiedzi. Natomiast też pragnę nadmienić fakt, że założeniem tego poradnika była jego przystępność dla każdej grupy docelowej (w tym dla początkujących dopiero wchodzących w świat serwerów, bo takie było zapotrzebowanie). Osoby doświadczone tworzące duże, publiczne serwery mają same wystarczające know-how i najpewniej w ogóle nie muszą czytać takich poradników. Ty z perspektywy osoby, która prowadzi serwer 1000+ graczy podchodzisz do pewnych kwestii zupełnie inaczej. :wink:

@Lempik od razu odpowiem też w kwestii flag startowych. Generalnie są to flagi używane do startu maszyny wirtualnej Java. Wpływają na optymalizację zużycia pamięci, możemy też zdefiniować kilka rzeczy związanych z CPU. Na podlinkowanej stronie jest dokładny opis każdej, być może wkrótce pojawi się tu moje tłumaczenie do tej kwestii oraz odczytywania funkcji w timingach.

“Wiem, że można inaczej, ale powiem innym, że nie można i java zła i lagi, bo java” - to trochę jak z unity i tym, że jak ktoś zobaczy, że logo unity się wyświetla (bezpłatna wersja), to wiadomo, że zła gra.

A jak ktoś już ma opcję płatną z usunięciem logo przy uruchamianiu, no to już fajna gra, wiadomo, nie ma logo unity, nie ma unity, nie ma słabo napisanej gry, bo większość takich gier na płatnym unity jest już pisana przez studia, które mają developerów na trochę wyższym poziomie, a nie osoby, które pierwszy raz grę piszą.

Jeszcze się nie spotkałem, żeby ktokolwiek w środowisku Minecraft używał “szyfrowanej bazy danych”. To jedynie marnowanie zasobów. Od haseł są hashe, adresy IP jak trzeba też można hashować do porównywania i wyszukiwania “multikont”, więcej danych raczej się nie zbiera o graczach, które wymagałyby zabezpieczenia.

Obecnie jedyne co to może osiągnąć, to przekazanie błędnych informacji zamiast faktów i szerzenie dalej nieprawdziwych informacji na temat wyżej wymienionych przeze mnie rzeczy oraz innych, które pominąłem, a pewnie by się jakieś znalazły. Zamiast edukować, to idziemy w stronę wrzucania użytkowników w voodoo i dowody anegdotyczne.


Nie, te flagi nie są od optymalizacji zużycia pamięci, tylko od garbage collectora, włączają implemenetacje GC pod nazwą G1GC i ustawiają jego parametry, tak aby możliwie zmniejszyć pause time, który w minecraft jest wysoki, bo gra ma poważnie dużą alokację pamięci i bardzo dużo short-living obiektów.

Ponownie skrót myślowy z szyfrowaniem nie samej bazy, ale konkretnego typu danych w niej np. haseł. Teraz przeczytaj moje wyjaśnienie co do flag i Twoje fachowe i porównaj, ile początkująca osoba może z nich zrozumieć. Jedno i drugie sprowadza się do jednego, a i przy optymalizacji zużycia pamięci może pomóc. Po południu wrzucę zaktualizowaną wersję o Twoje wartościowe sugestie, ale nadal twierdzę - trzymajmy się prostego języka i w pewnym sensie ogólników, aby poradnik był przystępny dla typowej osoby, która szuka informacji w internecie prowadząc swój pierwszy serwer.

W informatyce nie używamy skrótów myślowych, tylko jesteśmy konkretni i zdecydowani, nie siejemy dezinformacji, bo ktoś na pewno zrozumie, co chcieliśmy przekazać - szczególnie, kiedy sam nie wie jeszcze zbyt wiele. Zdecydowanie upada tutaj funkcja edukacyjna tekstów.

Jak i w twoim poprzednim wątku - zwracam uwagę, na to, że haseł się nie szyfruje. Hasła się zapisuje w postaci wyniku funkcji skrótu. Szyfrowanie jest odwracalne, kiedy posiadamy klucz. Funkcja skrótu nie ma takiego klucza i możemy tylko próbować zgadywać metodą siłową.

Nikt nie mówi, że musi wyglądać tak jak moje, można napisać prostym językiem, bez błędów merytorycznych i nie jest to aż takie trudne, pod warunkiem, że wiemy, o czym piszemy.

Ponownie - w informatyce operujemy faktami, nie domysłami i ogólnikami. Nic z tego dobrego nie wyjdzie, a uczenie takich “ogólników” na początku przygody z technicznymi rzeczami, może tylko negatywnie wpłynąć na dalsze przyswajanie informacji i rozwój, poza ogólnym wprowadzaniem w błąd.

Duża aktualizacja treści poradnika. Dziękuję @Nieznajomy11 za wszystkie sugestie. Wspomniałem w temacie o pomocy w weryfikacji poprawności treści przedstawionych porad. Nikt nie jest nieomylny, poradnik będzie stale aktualizowany.
Warto wymienić zmiany w najistotniejszych kwestiach, które mogły wprowadzać w błąd:

  • usunięcie notki o odgórnym założeniu słabej optymalizacji gry przez język w którym została napisana jako zbyt duże uproszczenie,
  • zmiana części o timingach, nie są one najdokładniejszą metodą, wspomnienie o innych, lepszych, z jednoczesnym zastrzeżeniem, że timingi są łatwo dostępną i przystępną metodą wbudowaną w silnik,
  • usunięcie informacji o tym, że zapis w YAML/JSON jest z góry niewydajny, był to błąd, bo chociażby pluginy jak IridiumSkyBlock czy Factions używały tego bądź podobnego zapisu i przy tym były w stanie działać dobrze, dodanie informacji o rozpoznawaniu lagów przy zapisie danych,
  • aktualizacja informacji o pluginie Skript, dodanie notki o niezalecaniu go na większych serwerach
  • usunięcie informacji o plikach tymczasowych, było dodane na wyrost,
  • usunięcie demonizowania zapisu danych w HashMapach/ArrayListach, dodanie informacji, że ich optymalna implementacja zależy od autora pluginu,
  • lepsze, bardziej konkretne wytłumaczenie działania zoptymalizowanych flag startowych.
  • mniejsze zmiany.

Jeśli jeszcze coś się nasuwa, to zapraszam do propozycji, będziemy aktualizować. :slight_smile: Dziękuję raz jeszcze za wkład w treść poradnika.

Niestety nadal nie jest tak, jak powinno być. Flagi te nie zmniejszają parametrów wpływających na dużą alokację pamięci. One są do minimalizowania negatywnych skutków czasu trwania procesu GC, w którym uwalniana jest pamięć (usuwane są niepotrzebne już obiekty).

Taki “pause time” jest odczuwalny w postaci zwyczajnego laga. Mamy Young Gen i Old Gen - obie te wartości (a dokładniej czasy GC dla młodej i starej generacji) widać w timingach z papera, od jakiegoś czasu nawet na pierwszej stronie, bo problemy w nowych wersjach nasiliły się znacznie.

1lajk

Zmienione. Sądzę, że teraz wspólnymi siłami dopracowaliśmy te nieścisłe kwestie i już żadna z nich nie wprowadza w błąd. Sekcja o konfiguracji silnika myślę, że nie wymaga większych zmian i opracowana jest w miarę dobrze, a tam możemy sporo rzeczy zoptymalizować. Jeśli coś jeszcze się nasunie, to ponownie zachęcam do informowania mnie o tym (można przez PW/Discorda, żeby ten wątek nie był zbyt długi).

Możliwe, że następna aktualizacja dziś wieczorem. Postaram się jeszcze raz zweryfikować wszystkie kwestie i dodać dokładne tłumaczenie każdej flagi startowej oraz tego, co widzimy w timingach. Pozostaję dłużny za ogromną pomoc.

Dość spora aktualizacja treści poradnika dziś tj. 06.05.2020 r.
Dodano:

  • informację o dwóch alternatywnych pluginach do generowania mapy dla WorldBorder na najnowsze wersje;
  • informację o pluginie EntityTrackerFixer;
  • obszerny polski opis poszczególnych sekcji w timingach.

Myślę, że to jeszcze bardziej uprości kwestię weryfikacji lagów. :slight_smile:

Dodałbym jeszcze Waterfalla, fork Bungee’a od twórców papera

1lajk

Jest wspomniane o Travertine, czyli de facto Waterfall z dodaną obsługą wersji 1.7. Właśnie z niego większość serwerów korzysta. Ale dodam też jutro informację o Waterfallu, dzięki.

//Dodane.

Spróbowałem pobrać ten silnik, ale w świeżo wygenerowanym tuinity.yml w ogóle nie istnieje opcja no-tick-view-distance.
obrazek

Możliwe, że została ona usunięta w którejś z nowszych aktualizacji, polecam dołączyć do Discorda projektu, tam są najświeższe informacje o zmianach. :wink:

A nie, no-tick-view-distance jest w paper.yml. W takim razie nie rozumiem, dlaczego jest do tego potrzebny silnik Tuinity.

Bo on tę funkcjonalność dodaje, a że generowana jest w tym pliku to nie mam pojęcia dlaczego.

Już wiem, paper wprowadził no-tick-view-distance 6 maja, czyli dwa tygodnie temu: https://papermc.io/ci/job/Paper-1.15/247/

1lajk

Bo zmienili. Tuinity testuje rozwiązania pod Paper i jest bardziej eksperymentalne. Twórca Tuinity dodał swój kod No-Ticków do Papera i no-tick dziala teraz tylko wtedy, gdy ustawisz go w paper.yml.

@Lempik Twórca Tuinity po prostu testuje swoje patche w Tuinity, niektóre wchodzą do Papera, a niektóre nie, więc imho lepiej mieć Tuinity, bo nic tak naprawdę nie tracisz. Każde poprawki z Papera przechodzą do Tuinity i niektóre przechodzą z Tuinity do Papera, tak to ogólnie działa u niego.

1lajk

Wszystko jasne, dzięki za doprecyzowanie. :slight_smile: