RE:NODE

Minecraft11 წუთის საკითხავი

Minecraft crash report-ები: watchdog და ლაგი

როგორ წავიკითხოთ Minecraft სერვერის crash report: მნიშვნელოვანი სექციები, watchdog-ის thread dump-ები, Can't keep up გაფრთხილება და plugin-ის პოვნა stack trace-ში.

0 მკითხველი

Minecraft სერვერის crash report არის ტექსტური ფაილი crash-reports/-ში, რომელიც ასახელებს, რას აკეთებდა სერვერი, როცა მოკვდა: გამონაკლისს, stack trace-ს და - ხშირად - ზუსტ entity-ს ან block entity-ს, რომელიც tick-ში იყო, მისი კოორდინატებით. წაიკითხე სამი რამ ამ თანმიმდევრობით: Description ხაზი, stack trace-ის პირველი ხაზები, სადაც ეძებ package-ის სახელს, რომელიც Minecraft-ს ან Paper-ს არ ეკუთვნის, და "being ticked" სექცია, თუ არსებობს. შემთხვევების უმეტესობაში ეს მიზეზს ამოიცნობს. ლაგთან დაკავშირებული გათიშვები სხვაგვარია: ისინი watchdog-იდან მოდის, crash ფაილის ნაცვლად ლოგში thread dump-ს ბეჭდავს და იკითხება იმის ყურებით, რაზე იყო გაჭედილი მთავარი thread. "Can't keep up" გაფრთხილება კი საერთოდ არ არის კრაში.

ეს პოსტი Paper და vanilla სერვერებს ეხება. Mod-იანი სერვერები იგივე report-ებს ქმნიან, უბრალოდ მეტი ხაზით - mod-იანი სერვერი კრაშების გარეშე განიხილავს იმას, რაც Forge-ის, NeoForge-ისა და Fabric-ისთვის სპეციფიკურია.

"სერვერი დაკრაშდა"-ს სამი სახე#

ხალხი ერთ სიტყვას სამი სხვადასხვა მოვლენისთვის იყენებს და თითოეული სხვადასხვა კვალს ტოვებს.

რა მოხდამტკიცებულებასად
გამონაკლისი, რომელსაც სერვერი ვერ გაუმკლავდაcrash-YYYY-MM-DD_HH.MM.SS-server.txtcrash-reports/
მთავარმა thread-მა პასუხი შეწყვიტაWatchdog-ის thread dumplogs/latest.log
პროცესი გარედან მოკლესსერვერისგან საერთოდ არაფერიჰოსტის კონსოლი ან exit კოდი

მესამე შემთხვევა ხალხს ყველაზე მეტად აბნევს. თუ ლოგი უბრალოდ ხაზის შუაში წყდება crash report-ისა და გათიშვის შეტყობინებების გარეშე, Java პროცესი არ დაკრაშულა - ის შეწყვიტეს. ჰოსტინგზე ჩვეულებრივი მიზეზი მეხსიერების ლიმიტის მიღწევაა: container-ს kernel აჩერებს და Java-ს რამის ჩაწერის შანსი არ ეძლევა. RE:NODE-ზე სერვერი, რომელიც მეხსიერების ლიმიტს მიაღწევს, ჩერდება და სუფთად გადაიტვირთება, swap-ში დატოვების ნაცვლად, ხოლო პანელის მეხსიერების გრაფიკი აჩვენებს, როგორ აღწევს ის ზღვარს ზუსტად მანამდე. Linux swap და OOM killer ხსნის, რა ხდება ამ მომენტში, ხოლო რატომ გადაიტვირთება შენი თამაშის სერვერი განიხილავს ნიმუშს, როცა ის მეორდება.

Crash report-ის ანატომია#

Crash report-ს ყოველთვის ერთი და იგივე სტრუქტურა აქვს. აი შემოკლებული მაგალითი:

crash-reports/crash-2026-10-07_21.14.03-server.txt
---- Minecraft Crash Report ----// Shall we play a game?Time: 2026-10-07 21:14:03Description: Ticking entityjava.lang.NullPointerException: Cannot invoke "org.bukkit.Location.getWorld()" because "loc" is null    at com.example.petsplus.PetTask.follow(PetTask.java:88)    at com.example.petsplus.listener.PetListener.onMove(PetListener.java:41)    at net.minecraft.world.entity.Entity.tick(Entity.java:...)    ...A detailed walkthrough of the error, its code path and all known details is as follows:----------------------------------------------------------------------------------------- Head --Thread: Server thread-- Entity being ticked --Details:    Entity Type: minecraft:wolf    Entity's Exact location: -412.50, 64.00, 1290.31...-- System Details --Details:    Minecraft Version: 1.21.x    Java Version: 21.0.x    Memory: 2140000000 bytes (2040 MiB) / 4294967296 bytes (4096 MiB) up to ...    JVM Flags: ...

რას გეუბნება თითოეული ნაწილი:

  • კომენტარი სათაურის ქვეშ შემთხვევითი ხუმრობაა. უგულებელყავი.
  • Description კატეგორიაა: Ticking entity, Ticking block entity, Exception in server tick loop, Watching Server, Exception generating new chunk. ის გეუბნება, ქვემოთ რომელ სექციაში იქნება კოორდინატები.
  • გამონაკლისის ხაზი - ტიპი და შეტყობინება. NullPointerException, ConcurrentModificationException, StackOverflowError, OutOfMemoryError და ClassCastException შემთხვევების უმეტესობას ფარავს.
  • Stack trace - მეთოდების გამოძახებების ჯაჭვი, რომელმაც შეცდომამდე მიიყვანა, უახლესი პირველი.
  • "Being ticked" სექცია - tick-ის კრაშებისთვის entity-ს ან ბლოკის ტიპი და მისი ზუსტი მდებარეობა. ეს ოქროა: გეუბნება, სამყაროს სად არის პრობლემა.
  • System Details - Minecraft-ის ვერსია, Java-ს ვერსია, მეხსიერება იმ მომენტში, JVM flag-ები. შეამოწმე ისინი ყოველთვის, როცა კრაში აუხსნელი ჩანს; არასწორი Java ვერსია ან პაწაწინა heap ბევრს ხსნის.

Stack trace-ის წაკითხვა#

Stack trace მეთოდების გამოძახებებს ჩამოთვლის, ზემოთ იმით, რომელიც ჩავარდა. ყოველი ხაზი არის at package.Class.method(File.java:line). მის გამოსაყენებლად პროგრამისტი არ უნდა იყო; package-ების სახელების ამოცნობა გჭირდება.

  1. წაიკითხე ზემოდან ქვემოთ და გაჩერდი პირველ ხაზზე, რომელიც თამაში არ არის. Minecraft-ის საკუთარი კოდი net.minecraft-ის ქვეშაა, Paper და Bukkit - io.papermc-ის, org.bukkit-ისა და org.spigotmc-ის ქვეშ, თავად Java - java.-სა და jdk.-ის ქვეშ. მათ გარეთ პირველი frame ჩვეულებრივ დამნაშავეა. ზემოთ მოცემულ მაგალითში com.example.petsplus plugin-ია და ის სულ ზემოთაა.
  2. მოძებნე "Caused by:". გამონაკლისები ხშირად შეფუთულია: ზედა გამონაკლისი ამბობს "error while ticking", ხოლო ქვემოთ Caused by: ნამდვილს შეიცავს. ჯაჭვში ბოლო Caused by: ძირეული მიზეზია; მისი პირველი frame-ები ისევე წაიკითხე.
  3. დაუკავშირე package plugin-ს. Package-ების სახელები ჩვეულებრივ plugin-ის ან ავტორის სახელს შეიცავს. თუ აშკარა არ არის, მოძებნე plugins/ საქაღალდეში: ყოველი jar-ის plugin.yml ან paper-plugin.yml მის მთავარ კლასს ასახელებს, რომელიც იმავე package-ით იწყება.
  4. ჩაინიშნე ვერსია. რასაც არ უნდა უგზავნიდე plugin-ის ავტორს, მიუთითე plugin-ის ვერსია, Paper-ის build და სრული crash report და არა ბოლო ათი ხაზის screenshot.

როცა მთელი stack net.minecraft-ის შიგნითაა plugin-ის frame-ების გარეშე, კრაში თავად თამაშშია ან სამყაროს ცუდი მონაცემებით არის გამოწვეული - დაზიანებული entity-თი ან chunk-ით. მაშინ "being ticked" კოორდინატები report-ის ყველაზე სასარგებლო ნაწილი ხდება; დაზიანებული chunk-ები და region ფაილები განიხილავს, რა უნდა გააკეთო მათთან.

შეცდომები, რომლებიც ლოგში ჩნდება, მაგრამ სერვერს არ აკრაშებს#

ყოველი stack trace კრაში არ არის. Plugin-ის შეცდომები ხშირად იჭერენ და ლოგავენ, სერვერი კი აგრძელებს. Bukkit-ის ორი შეტყობინების ამოცნობა ღირს:

code
[ERROR]: Could not pass event PlayerInteractEvent to ShopKeeperX v2.4.1org.bukkit.event.EventException: null    ...Caused by: java.lang.NullPointerException: ...
code
[ERROR]: Error occurred while enabling WarpsPlus v1.3 (Is it up to date?)java.lang.NoSuchMethodError: ...

კონსოლში საგანგაშოდ გამოიყურება, მაგრამ სხვადასხვა რამეს ნიშნავს:

  • "Could not pass event X to Y" - Y plugin-მა event-ის დამუშავებისას გამონაკლისი ისროლა. Plugin-ის ეს ფუნქცია ამ მოქმედებისთვის გაფუჭებულია; სერვერი რიგზეა. წაიკითხე Caused by ხაზი.
  • "Error occurred while enabling X (Is it up to date?)" - plugin-მა ვერ დაიწყო მუშაობა, ჩვეულებრივ იმიტომ, რომ Minecraft-ის სხვა ვერსიისთვის აიწყო ან დამოკიდებულება აკლია. Plugin გამორთულია.

Java-ს შეცდომის ტიპი ხშირად პრობლემის სახეს გეუბნება, სანამ შემდგომ წაიკითხავ:

შეცდომაჩვეულებრივ ნიშნავს
NoSuchMethodError, NoSuchFieldErrorPlugin Minecraft-ის ან Paper-ის სხვა ვერსიისთვის აიწყო
NoClassDefFoundError, ClassNotFoundExceptionაკლია დამოკიდებული plugin, ან არასწორი ვერსიაა
UnsupportedClassVersionErrorJava ზედმეტად ძველია plugin-ისთვის ან სერვერისთვის
NullPointerExceptionBug plugin-ში, ან ცუდი მონაცემები, რომელსაც არ ელოდა
ConcurrentModificationExceptionPlugin რაღაცას არასწორი thread-იდან ცვლის
StackOverflowErrorუსასრულო რეკურსია, ხშირად ორი plugin, რომლებიც ერთმანეთს იწვევენ
OutOfMemoryError: Java heap spaceHeap ზედმეტად პატარაა, ან მეხსიერება ჟონავს

UnsupportedClassVersionError შეტყობინებები class ფაილის ვერსიას ასახელებს: 61.0 ნიშნავს, რომ კოდს Java 17 სჭირდება, 65.0 - Java 21. თუ სერვერის Java ამაზე ძველია, კოდი ვერ ჩაიტვირთება. JVM flag-ები და Java-ს ვერსიები ვერსიების მატრიცას შეიცავს.

OutOfMemoryError ცალკე შენიშვნას იმსახურებს, რადგან მისი შეტყობინება ამბობს, რომელი მეხსიერება ამოიწურა. Java heap space ნიშნავს, რომ -Xmx-ით დაწესებული heap სავსეა: ან ზედმეტად პატარაა სამყაროსა და plugin-ებისთვის, ან რაღაც ჟონავს და heap ნებისმიერ ზომაზე გაივსებოდა. GC overhead limit exceeded იგივე პრობლემაა garbage collector-ის მხრიდან დანახული - ის თითქმის მთელ დროს ხარჯავს თითქმის არაფრის გასათავისუფლებლად. Metaspace კლასების მეტამონაცემებია და plugin-ების სერვერზე ჩვეულებრივ მიუთითებს plugin-ზე, რომელიც /reload-ით ან plugin manager-ით განმეორებით იტვირთება, რაც ყოველი კლასის ძველ ასლებს ჟონავს. Heap-ის შეცდომა არ არის მიზეზი, რომ -Xmx გეგმის სრულ ზომამდე გაზარდო: JVM-ს heap-ის გარეთაც სჭირდება მეხსიერება, ხოლო container-ის ლიმიტამდე დაყენებული heap Java-ს შეცდომას report-ით აქცევს მოკვლად, რომელსაც report საერთოდ არ აქვს.

"Can't keep up!" გაფრთხილებაა და არა კრაში#

code
[WARN]: Can't keep up! Is the server overloaded? Running 5214ms or 104 ticks behind

სერვერი წამში 20 tick-ს ისახავს მიზნად, თითოეული 50 ms. როცა გრაფიკს რამდენიმე წამზე მეტით ჩამორჩება, ამას ლოგში წერს და გამოტოვებულ tick-ებს ტოვებს, ნაცვლად იმისა, რომ დაწევა სცადოს. შეტყობინება ნიშნავს, რომ სერვერმა გარკვეული დროის განმავლობაში 50 ms სამუშაოს 50 ms-ში შესრულება ვერ შეძლო.

რას არ გეუბნება, ესაა რატომ. გაშვების შემდეგ ერთი შეტყობინება ნორმალურია - სამყაროს ჩატვირთვას და plugin-ების ინიციალიზაციას დრო სჭირდება. დიდი ივენთის დროს დროდადრო შეტყობინება ნორმალურია. მათი მუდმივი ნაკადი ლაგის პრობლემაა და მიზეზი ერთ-ერთია:

  • რაღაც ძვირი მთავარ thread-ზე: ზედმეტად ბევრი entity, ფერმა, chunk-ების გენერაცია, ნელი plugin.
  • Garbage collection-ის პაუზები, ზედმეტად პატარა heap-ისგან ან ცუდად მორგებული flag-ებისგან.
  • CPU-ის შიმშილი, როცა პროცესი საკმარის CPU დროს არ იღებს. ჰოსტზე CPU-ის მკაცრი ლიმიტებით, სერვერი, რომელსაც თავის წილზე მეტი სჭირდება, იზღუდება, რაც ზუსტად ლაგს ჰგავს.

ჩამორჩენილი tick-ების რაოდენობა არ არის სიმძიმის ქულა, რომელსაც პირდაპირ გამოიყენებ; ის დამოკიდებულია იმაზე, რამდენ ხანს გაგრძელდა გაჩერება. ნამდვილი მიზეზის საპოვნელად გამოიყენე spark, ხოლო ჩვეულებრივი გამოსწორებებისთვის - რატომ ეცემა TPS.

Watchdog: როცა სერვერი პასუხს წყვეტს#

თუ ერთ tick-ს ზედმეტად დიდი დრო სჭირდება, სერვერი თვლის, რომ მთავარი thread სამუდამოდ გაიჭედა და თავს თავად თიშავს. ეს არის watchdog. ორი პარამეტრია, ერთი vanilla-დან და ერთი Spigot-იდან:

server.properties
max-tick-time=60000
spigot.yml
settings:  timeout-time: 60  restart-on-crash: true  restart-script: ./start.sh

რას აკეთებს თითოეული პარამეტრი და რას არ უნდა შეეხო:

  • max-tick-time vanilla-ს watchdog-ია, მილიწამებში. თუ ერთ tick-ს მეტი დრო სჭირდება, სერვერი წერს crash report-ს აღწერით Watching Server და ჩერდება. -1 მას თიშავს - რაც გაჭედილ სერვერს აქცევს ისეთად, რომელიც გადატვირთვის ნაცვლად სამუდამოდ კიდია. ნუ გააკეთებ.
  • timeout-time Spigot-ის watchdog-ია, წამებში. Paper მას იყენებს იმის გადასაწყვეტად, როდის დაბეჭდოს thread dump და გაჩერდეს.
  • restart-on-crash და restart-script სერვერს საშუალებას აძლევს, საკუთარი თავის გადასატვირთად სკრიპტი გაუშვას. პანელ ჰოსტზე გადატვირთვა პანელს მიანდე; სკრიპტის გზა container-ში იშვიათად არსებობს.

Paper ადრეულ გაფრთხილებებს ამატებს, რომლებიც config/paper-global.yml-ში იმართება:

config/paper-global.yml
watchdog:  early-warning-every: 5000  early-warning-delay: 10000

როცა მთავარი thread early-warning-delay მილიწამი გაჭედილია, Paper ყოველ early-warning-every მილიწამში thread dump-ს ბეჭდავს, სერვერის მოკვლის გარეშე. ეს ნიშნავს, რომ მტკიცებულებას იღებ მაშინაც, როცა სერვერი თავისით გამოჯანმრთელდება.

Thread dump-ის წაკითხვა

code
[ERROR]: --- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH ---[ERROR]: The server has not responded for 10 seconds! Creating thread dump[ERROR]: ------------------------------[ERROR]: Server thread dump (Look for plugins here before reporting to Paper!):[ERROR]: Current Thread: Server thread[ERROR]:     PID: 27 | Suspended: false | Native: false | State: RUNNABLE[ERROR]:     Stack:[ERROR]:         com.example.claims.Storage.saveAll(Storage.java:212)[ERROR]:         com.example.claims.ClaimsPlugin.onAutosave(ClaimsPlugin.java:77)[ERROR]:         org.bukkit.craftbukkit.scheduler.CraftTask.run(...)

ზუსტი ფორმულირება Paper-ის ვერსიის მიხედვით იცვლება. მნიშვნელოვანია "Server thread"-ის stack: ის აჩვენებს, რას აკეთებდა მთავარი thread dump-ის მომენტში. წაიკითხე ზემოდან ქვემოთ, ზუსტად ისე, როგორც კრაშის stack trace. მაგალითში claim-ების plugin მთელ თავის მონაცემებს სინქრონულად ინახავს მთავარ thread-ზე, რაც ამ plugin-ის bug-ი ან კონფიგურაციის პრობლემაა.

თუ რამდენიმე ზედიზედ dump ერთსა და იმავე frame-ებს აჩვენებს, ეს გაჭედილი კოდია. თუ ყოველ ჯერზე განსხვავდება, thread დაკავებულია და არა გაჭედილი - ზოგადად გადატვირთულობა, და profiler მას dump-ებზე უკეთ აჩვენებს. თუ stack ბაზის ან ქსელის გამოძახებას აჩვენებს (java.net, jdbc, SocketInputStream), plugin მთავარი thread-იდან რაღაც დისტანციურს ელოდება; MySQL plugin-ებისთვის ხსნის, რატომ არის ეს მტკივნეული.

ნატიური კრაშები და hs_err ფაილები#

ძალიან იშვიათად თავად Java-ს ვირტუალური მანქანა კრაშდება. ის სერვერის სამუშაო დირექტორიაში წერს ფაილს სახელით hs_err_pid<number>.log, ლოგი კი უეცრად წყდება. მიზეზებია JVM-ის bug, plugin-ის ნატიური ბიბლიოთეკა ან აპარატურის პრობლემა. პირველი, რაც უნდა სცადო, სწორი ძირითადი ვერსიის Java-ს ამჟამინდელი build-ია; მეორე - ნებისმიერი plugin-ის მოხსნა, რომელსაც ნატიური კოდი მოჰყვება. ეს იმდენად იშვიათია, რომ ერთი შემთხვევაც გამოკვლევას იმსახურებს და არა უგულებელყოფას.

რუტინა ნებისმიერი კრაშისთვის#

  1. შეაგროვე მტკიცებულება, სანამ ისევ გადატვირთავ. დააკოპირე logs/latest.log და ნებისმიერი ახალი ფაილი crash-reports/-ში. გადატვირთვა ლოგს ცვლის.
  2. დაახარისხე: crash report, watchdog-ის dump, თუ ლოგი, რომელიც უბრალოდ წყდება.
  3. იპოვე პირველი არა-თამაშის frame stack-ში, ან კოორდინატები "being ticked" სექციაში.
  4. შეცვალე ერთი რამ: განაახლე ან მოხსენი ეს plugin, ან გაუმკლავდი ამ entity-ს ან chunk-ს. შემდეგ დააკვირდი.
  5. თუ სხვადასხვა მიზეზით მეორდება, შეხედე საერთო ფაქტორებს: მეხსიერება, Java-ს ვერსია, ბოლო განახლება.

RE:NODE-ზე დამკვირვებელი კრაშებს ითვლის: შენ მიერ მოთხოვნილი გადატვირთვები არ ითვლება, მაგრამ საათში სამი დაუგეგმავი სერვერის გვერდზე გაფრთხილებას აჩენს და ავტომატურად ticket-ს ხსნის, ხოლო ექვსი სერვერს აჩერებს, სანამ ვინმე არ ნახავს. ეს მიზეზია, რომ კრაშების ციკლს სასწრაფოდ მოეპყრა და არ მისცე საშუალება, მთელი ღამე თავისით გადაიტვირთოს. პანელის კონსოლი სრულ, გაუფილტრავ გამოსავალს აჩვენებს, ამიტომ პირველი ნაბიჯის მტკიცებულება ხელმისაწვდომია მაშინაც, როცა სერვერი ჩართული ვერ რჩება.

FAQ#

სად ინახება Minecraft სერვერის crash report-ები?

სერვერის ძირეულ დირექტორიაში crash-reports საქაღალდეში, თარიღითა და დროით დასახელებული და -server.txt-ით დამთავრებული. Watchdog-ის dump-ები და plugin-ის შეცდომები ნაცვლად logs/latest.log-შია, ხოლო ძველი ლოგები gzip-ით შეკუმშულია logs/-ში.

რატომ არ არის crash report, როცა ჩემი სერვერი ჩერდება?

იმიტომ, რომ ის Java პროცესის გარედან გააჩერეს, ჩვეულებრივ მეხსიერების ლიმიტის გადაჭარბების გამო. Java-ს report-ის დაწერა არ შეუძლია, როცა მას კლავენ. გაჩერების დროის გარშემო მეხსიერების გრაფიკი შეამოწმე.

საშიშია "Can't keep up"?

თავისთავად არა. ნიშნავს, რომ სერვერი ჩამორჩა და tick-ები გამოტოვა. მუდმივი გაფრთხილებები ნიშნავს ნამდვილ ლაგს, რომელსაც მოთამაშეები გრძნობენ, და მიზეზის პოვნაა საჭირო, მაგრამ გაფრთხილება სამყაროს არ აზიანებს.

გამოვრთო watchdog, რომ სერვერმა კრაში შეწყვიტოს?

არა. Watchdog მხოლოდ მაშინ ამოქმედდება, როცა სერვერი უკვე გაყინულია. მისი გამორთვა გაყინულ სერვერს სამუდამოდ გაშვებულს ტოვებს, მტკიცებულების შექმნისა და გადატვირთვის ნაცვლად. გაასწორე ის, რის გამოც tick-ებს ამდენი დრო სჭირდება.

Crash report მხოლოდ Minecraft-ის კლასებს ახსენებს. Paper-ის bug-ია?

შესაძლოა, მაგრამ უფრო ხშირად ეს სამყაროს ცუდი მონაცემებია, მაგალითად დაზიანებული entity, ან plugin, რომლის ეფექტიც მოგვიანებით vanilla კოდში ჩანს. Upstream-ზე შეტყობინებამდე შეამოწმე "being ticked" კოორდინატები და plugin-ების გარეშე გამოსცადე.


კომენტარები

სრულიად ანონიმურად: ანგარიშის, ელფოსტის და cookie-ის გარეშე. ინახება მხოლოდ სახელი, ტექსტი და დრო - სხვა არაფერი. ბმულების რაოდენობა ლიმიტირებულია.

0/2000