FiveM Server laggt: die Resource finden, die den Lag verursacht
Server hängt oder FPS im Keller? So unterscheidest du beides, liest den FXServer-Profiler, zählst Commands pro Resource und findest das Script hinter dem Lag.
Von Termi
- Performance
- Debugging
- Lua
Auf dieser Seite
- Zwei Arten von Lag
- Den Server-Profiler lesen
- Die FPS eines Spielers messen
- Die Ursache, die keins der Tools zeigt
- Die üblichen Verdächtigen
- Häufige Fragen
- Was bedeutet „server thread hitch warning“ in FiveM?
- Warum hitcht mein FiveM-Server alle paar Sekunden?
- Wie finde ich heraus, welche Resource meinen FiveM-Server laggen lässt?
- Was zeigt resmon in FiveM?
- Was bedeutet die oxmysql-Warnung „took … ms to execute a query“?
- Dieselbe Suche mit einem Befehl
„Der Server laggt“ meint zwei verschiedene Probleme. Mal hängt der Server-Thread, und alle ruckeln gleichzeitig. Mal verlieren nur einige Spieler FPS, während der Server sauber läuft. Diese Anleitung zeigt, wie du beides auseinanderhältst, wie du den Profiler von FXServer liest und wie du die Ursache findest, die sich vor beiden versteckt: eine Resource, die Tausende Commands registriert. Am Ende dieselbe Suche mit einem einzigen Befehl.
Zwei Arten von Lag
Beide brauchen andere Werkzeuge. Prüfe also zuerst, welches Problem du hast: Gibt es Hitch-Warnungen, und spüren es alle oder nur einige Spieler?
Den Server-Profiler lesen
FXServer bringt einen Profiler mit, der jede Resource, jeden Thread und jeden Event-Handler misst. In der Server-Konsole:
profiler record start
profiler record stop
profiler saveJSON lag.jsonStarte ihn, während der Server laggt, stoppe ihn nach etwa zehn Sekunden und speichere die Aufnahme. lag.json ist ein Chrome-Trace: Öffne die DevTools in Chrome, geh zu Performance und lade die Datei. Jeder Server-Frame ist ein Resource Manager Tick. Darin findest du den tick (name) jeder Resource, ihre Threads als thread @resource/file.lua[from..to], ihre Event-Handler und ihre Exports.
Suche Frames, die viel länger dauern als der Rest, und schau, welche Resource sie füllt. Der Zeilenbereich verrät, welcher CreateThread oder Handler es war.
Eine Resource kann den Profiler nicht selbst starten. ExecuteCommand('profiler record start') aus einem Script wird abgelehnt, solange die server.cfg es nicht erlaubt: add_ace resource.<name> command.profiler allow, dazu dieselbe Zeile für command.record und command.saveJSON.
Die FPS eines Spielers messen
Auf Spielerseite hat F8 zwei Werkzeuge. resmon 1 zeigt live die CPU-Zeit und den Speicher jeder Resource, was reicht, wenn eine Resource klar heraussticht. Für einen genaueren Blick läuft derselbe Profiler im Spiel:
resmon 1
profiler record 500
profiler saveJSON lag.jsonDas nimmt 500 Frames auf. Lade die Datei genauso in die DevTools und such nach Client-Threads, die jeden Frame laufen. Eine Wait(0)-Schleife, die in jedem Frame echte Arbeit leistet, etwa die Distanz zu Hunderten Markern misst, ist meist der erste Verdächtige.
Die Ursache, die keins der Tools zeigt
Eine Art von Lag versteckt sich vor beiden. Ein Server fügt ein Emote-Pack hinzu und kurz darauf laggt es. Der Profiler zeigt keinen schweren Thread, und die Suche nach RegisterCommand im Pack findet eine Handvoll Aufrufe.
Die Aufrufe stehen in einer Schleife, hinter einem lokalen Alias, einer pro Emote:
local register = RegisterCommand
for _, emote in ipairs(Emotes) do
register(emote.command, function() PlayEmote(emote) end, false)
TriggerEvent('chat:addSuggestion', '/' .. emote.command, emote.label)
endBei zweitausend Emotes sind das zweitausend Commands und zweitausend Chat-Vorschläge im Spiel jedes Spielers. Eine Textsuche kann sie nicht zählen, das Spiel aber schon: GetRegisteredCommands() gibt jeden Command mit der Resource zurück, die ihn registriert hat.
local counts = {}
for _, command in ipairs(GetRegisteredCommands()) do
counts[command.resource] = (counts[command.resource] or 0) + 1
end
for resource, count in pairs(counts) do
if count > 100 then print(resource, count) end
endFühr es als Client-Script und als Server-Script aus. Eine Resource mit Hunderten Commands ist einen Blick wert. Eine mit Tausenden registriert fast immer einen Command pro Emote oder Item, wo ein Command mit Argument reichen würde.
Die üblichen Verdächtigen
Häufige Fragen
Was bedeutet „server thread hitch warning“ in FiveM?
Der Haupt-Thread von FXServer soll 20-mal pro Sekunde ticken, also alle 50 ms. Vergehen zwischen zwei Ticks mehr als 150 ms, gibt die Konsole server thread hitch warning: timer interval of 212 milliseconds aus, und die Zahl ist die Dauer dieser Lücke. In der Lücke läuft auf dem Server-Thread nichts anderes, deshalb spürt sie jeder Spieler im selben Moment. Etwas auf dem Server hat den Thread zu lange festgehalten, meist eine Resource, die in einem einzigen Frame viel erledigt.
Warum hitcht mein FiveM-Server alle paar Sekunden?
Ein Hitch im festen Takt kommt meist von einem Server-Thread, der ein paar Sekunden per Wait schläft und dann auf einmal schwer arbeitet, etwa alle Spieler, Fahrzeuge oder Job-Punkte durchläuft. Der Server-Profiler zeigt, welcher Thread es ist: Die langen Frames nennen die Resource und die Zeilen des Threads, zum Beispiel thread @jobs_garbage/server/main.lua[88..131].
Wie finde ich heraus, welche Resource meinen FiveM-Server laggen lässt?
Nimm den eingebauten Profiler von FXServer. Gib profiler record start in der Server-Konsole ein, etwa zehn Sekunden später profiler record stop, dann profiler saveJSON lag.json, und lade die Datei im Performance-Tab der Chrome DevTools. Tick, Threads und Event-Handler jeder Resource erscheinen mit ihrer Zeit, die Resource hinter einem langen Frame fällt also auf. Laggen nur einige Spieler, lass sie stattdessen resmon 1 in F8 eingeben, um die CPU-Zeit jeder Client-Resource live zu sehen.
Was zeigt resmon in FiveM?
resmon 1, in die F8-Konsole getippt, öffnet den Resource-Monitor: eine Live-Liste aller Client-Resources mit der CPU-Zeit, die sie pro Frame brauchen, und dem Speicher, den sie belegen. Er misst nur das Spiel des Spielers, der ihn geöffnet hat. Er erklärt also dessen FPS und sagt nichts über einen Server-Hitch.
Was bedeutet die oxmysql-Warnung „took … ms to execute a query“?
oxmysql gibt eine Zeile wie [10.11.6-MariaDB] jobs_garbage took 312.4512ms to execute a query! aus, gefolgt von der Query, wenn eine Query länger läuft als die Convar mysql_slow_query_warning, standardmäßig 200 ms. Der Resource-Name verrät, welches Script sie geschickt hat. Die Query läuft asynchron und blockiert den Server-Thread daher nicht selbst, aber das Script, das auf das Ergebnis wartet, kommt zu spät, und Spieler erleben eine Garage oder ein Inventar, das langsam aufgeht. Ein fehlender Index auf der Spalte in der WHERE-Klausel ist eine häufige Ursache. Setz EXPLAIN vor die Query, um zu sehen, ob MySQL einen nutzt.
Dieselbe Suche mit einem Befehl
Der Agent von FiveDock übernimmt das alles. Mit den drei add_ace-Zeilen in der server.cfg nimmt fivedock perf zehn Sekunden lang den Profiler auf, zählt die Commands jeder Resource auf dem Server und im Spiel von drei Spielern und fragt jeden Spieler nach seinen FPS:
my-city profiled 10 s · 214 players online
server thread late by 3.8 ms on average, 212 ms at worst in the last minute
Server 198 ticks, the slowest took 212 ms
resource total per tick worst tick
jobs_garbage 1,236 ms 6.2 ms 205 ms
hud 412 ms 2.1 ms 6.3 ms
oxmysql 96 ms 0.5 ms 14 ms
emotes 12 ms 0.1 ms 0.4 ms
Where exactly the threads, events and exports that took longest
jobs_garbage 611 ms thread · server/main.lua:88-131 · 3× · worst 203 ms
jobs_garbage 598 ms thread · server/main.lua:12-40 · 198× · worst 6.1 ms
hud 380 ms event hud:sync · server.lua:52-77 · 1,420× · worst 4.2 ms
oxmysql 88 ms export · dist/build.js:310 · 402× · worst 14 ms
Commands on the server, and in the game of 3 sampled players
resource server players
emotes – 2,034
admin_menu 61 12
hud 9 4
total 248 2,310
A command per emote or item adds up fast. Check whether that resource needs them all.Der Thread des Müllabfuhr-Jobs in server/main.lua:88-131 hält den Server alle paar Sekunden etwa 200 ms lang auf, und das Emote-Pack hat 2.034 Commands im Spiel der Spieler. Hängt der Server-Thread, während niemand hinschaut, nimmt der Agent die nächsten zehn Sekunden selbst auf, sodass der nächste Report schon sagt, was passiert ist.
Finden, was laggt behandelt die Einrichtung und jeden Teil des Reports.