aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Discord-Bots

Discord-Bot-Uptime: Crash-Erkennung und Auto-Neustart

Selbst ein gut geschriebener Bot kann um 3 Uhr nachts klanglos sterben; deshalb geht es bei der Discord-Bot-Uptime weniger um Code als um operative Disziplin. Das Problem ist selten, dass der Bot „schlecht" ist — sondern dass niemand bemerkt, wenn er abstürzt, und es keinen Mechanismus gibt, der ihn wieder hochfährt. In dieser Anleitung richten wir Schritt für Schritt ein, wie du erkennst, warum ein Bot ausfällt, wie er sich mit pm2 selbst erholt und wie du ihn von außen mit einem einfachen Healthcheck überwachst.

Warum stürzen Bots ab?

Kenne zuerst deinen Gegner. Die überwältigende Mehrheit der Discord-Bots stoppt aus einer Handvoll wiederkehrender Gründe:

  • Nicht abgefangene Fehler: Eine Exception, die in einem Event-Handler geworfen wird und nicht in try/catch liegt, reißt den gesamten Node.js-Prozess mit.
  • Verschluckte Promise-Rejections: Ein Promise ohne await oder .catch() lässt den Prozess auf modernen Node-Versionen abstürzen.
  • WebSocket-Abbrüche: Netzwerkaussetzer oder Neustarts auf Discords Seite brechen die Verbindung; discord.js verbindet sich meist von selbst neu, bleibt aber manchmal in einem disconnect-Zustand hängen.
  • Speicherlecks: Ein stetig wachsender Cache oder nicht aufgeräumte setIntervals lassen den Prozess innerhalb von Stunden per OOM (Out Of Memory) beenden.
  • Rate Limits und ungültige Tokens: Wird der Token zurückgesetzt oder löst schlechter Code eine Flut von 429ern aus, wird die Gateway-Verbindung abgelehnt.

Beim Blick auf diese Liste wird die Lösung klar: Mach Fehler sichtbar, setze einen Wächter vor den Prozess und miss von außen, ob der Bot wirklich „lebt".

Schritt 1: Höre auf, Fehler zu verschlucken

Die erste Verteidigungslinie ist der Code selbst. Selbst wenn der Bot abstürzt, muss er protokollieren, warum er abgestürzt ist, sonst wiederholst du denselben Fehler unter Neustarts endlos. Füge dem discord.js-Client und den globalen Prozessereignissen Listener hinzu:

client.on('error', (err) => console.error('[client error]', err));
client.on('shardError', (err) => console.error('[shard error]', err));

process.on('unhandledRejection', (reason) => {
  console.error('[unhandledRejection]', reason);
});

process.on('uncaughtException', (err) => {
  console.error('[uncaughtException]', err);
  process.exit(1); // bewusst beenden; pm2 startet neu
});

Hier steckt eine wichtige Designentscheidung: Wenn uncaughtException auslöst, beenden wir den Prozess absichtlich. Den Prozess nach einem unbekannten Fehler am Leben zu halten, bedeutet, in einem halb-kaputten Zustand weiterzulaufen. Der saubere Ansatz lautet: protokollieren und beenden, und die Wiederherstellung einem Prozessmanager überlassen.

Schritt 2: Automatische Neustarts mit pm2

pm2 ist ein Prozessmanager, der Node-Apps im Hintergrund ausführt, sie bei einem Absturz automatisch neu startet und ihre Logs sammelt. Installiere ihn global auf deinem VPS:

npm install -g pm2

Du kannst den Bot direkt starten, aber die Konfiguration in einer ecosystem.config.js-Datei zu halten, ist viel sauberer:

module.exports = {
  apps: [{
    name: 'discord-bot',
    script: './index.js',
    instances: 1,
    autorestart: true,
    max_memory_restart: '300M',
    restart_delay: 5000,
    max_restarts: 10,
    min_uptime: '10s',
    env: { NODE_ENV: 'production' }
  }]
};

Die wichtigen Felder:

  • autorestart: Wenn der Prozess beendet wird, startet pm2 ihn neu.
  • max_memory_restart: Startet den Bot proaktiv neu, wenn der Speicher 300 MB übersteigt — eine Versicherung gegen Lecks.
  • restart_delay: Wartet 5 Sekunden vor dem Neustart, damit ein dauerhafter Fehler wie ein ungültiger Token keine Endlosschleife erzeugt, die die CPU auslastet.
  • min_uptime + max_restarts: Stürzt der Bot 10-mal ab, ohne 10 Sekunden zu laufen, markiert pm2 ihn als „errored" und stoppt; das verhindert, dass du ein echtes Problem unter endlosen Neustarts versteckst.

Zum Starten und damit er nach einem Server-Neustart wieder hochkommt:

pm2 start ecosystem.config.js
pm2 save
pm2 startup   # den ausgegebenen Befehl ausführen

Nutze pm2 logs discord-bot und pm2 status, um Logs und Status zu verfolgen.

Schritt 3: Ein Healthcheck-Endpoint

pm2 beantwortet die Frage „läuft der Prozess?", kann aber den Zustand „Prozess läuft, aber die Discord-Gateway ist abgerissen" nicht erfassen. Um zu verifizieren, dass der Bot wirklich lebt, füge einen kleinen HTTP-Healthcheck hinzu. Das eingebaute http-Modul reicht aus:

const http = require('http');

http.createServer((req, res) => {
  // client.ws.status === 0 -> READY
  const healthy = client.isReady() && client.ws.status === 0;
  res.writeHead(healthy ? 200 : 503, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({
    status: healthy ? 'ok' : 'degraded',
    ping: client.ws.ping,
    uptime: process.uptime()
  }));
}).listen(3001);

Jetzt zeigt curl http://localhost:3001 den Gateway-Status und den Ping des Bots. Es ist entscheidend, dieses Endpoint daran zu koppeln, ob die Gateway wirklich READY ist, und nicht nur an process.uptime() — sonst hältst du einen „lebenden toten" Bot für gesund.

Schritt 4: Externe Überwachung und Alarme

Das letzte Glied ist, benachrichtigt zu werden, wenn etwas schiefläuft. Verbinde das Healthcheck-Endpoint mit einem kostenlosen Monitoring-Dienst (UptimeRobot, Better Stack oder deinem eigenen Cron), sodass du bei einer 503 oder ausbleibender Antwort eine E-Mail-/Discord-Webhook-Benachrichtigung erhältst. Auch ein einfacher Selbstüberwachungsansatz funktioniert:

setInterval(() => {
  if (!client.isReady()) {
    console.error('[health] Bot nicht READY, beende');
    process.exit(1); // pm2 sauber neu starten lassen
  }
}, 60_000);

Bleibt die Gateway still hängen, lässt diese Schleife den Prozess absichtlich fallen, damit pm2 eine saubere Neuverbindung herstellen kann. Meist ist es besser, die eigene Reconnect-Logik von discord.js abzuwarten, aber für „Zombie"-Zustände ist dieser letzte Ausweg sicher.

Häufige Fragen

Kann ich meinen Bot auf kostenlosem Hosting (wie Replit) rund um die Uhr laufen lassen?

Die meisten kostenlosen Stufen versetzen den Prozess ohne Traffic in den Ruhezustand, daher ist der zuverlässigste Weg zu echter 24/7-Uptime ein kleiner VPS. Keep-Alive-Ping-Tricks sind fragil und verstoßen gegen die Nutzungsbedingungen vieler Plattformen. Für einen einzelnen Bot ist ein VPS für ein paar Euro im Monat plus pm2 weitaus verlässlicher.

Sollte ich systemd oder Docker statt pm2 verwenden?

Alle drei sind gültig. systemd ist in Linux integriert und bietet Neustarts auf Service-Ebene; Docker leistet dasselbe mit einer restart: unless-stopped-Policy. pm2 ist deshalb attraktiv, weil Log-Sammlung, speicherbasierte Neustarts und Ergonomie wie pm2 status in einem einzigen Werkzeug stecken. Nutzt du bereits Docker, reicht die Restart-Policy des Containers meist aus.

Wie stoppe ich eine Neustartschleife, die ständig abstürzt?

min_uptime und max_restarts existieren genau dafür: Stürzt der Bot in kurzer Zeit zu oft ab, gibt pm2 auf. Nutze dann pm2 logs, um die Grundursache zu finden (meist ein ungültiger Token, eine fehlende Env-Variable oder ein harter Fehler im Code) und behebe sie.

Fällt dein Bot immer noch ohne erkennbaren Grund aus? Ich kann Crash-Erkennung, pm2-Konfiguration und Healthcheck-Überwachung für dich einrichten; für eine robuste, sich selbst heilende Bot-Infrastruktur, nimm Kontakt mit mir auf.

Bu kategorideki tüm yazılar →

Devamı için