İyi yazılmış bir bot bile gece yarısı sessizce düşebilir; bu yüzden discord bot uptime meselesi koddan çok işletim disiplinidir. Sorun genellikle botun "kötü" olması değil, çöktüğünde kimsenin haberinin olmaması ve onu tekrar ayağa kaldıracak bir mekanizmanın bulunmamasıdır. Bu yazıda botun neden düştüğünü tespit etmeyi, pm2 ile kendini toparlamasını ve basit bir healthcheck ile dışarıdan izlenmesini adım adım kuruyoruz.
Botlar neden çöker?
Önce düşmanı tanıyalım. Discord botlarının ezici çoğunluğu birkaç tekrar eden nedenden ötürü durur:
- Yakalanmamış hatalar: Bir event handler içinde fırlatılan ve
try/catchile sarılmamış bir istisna, Node.js sürecini komple sonlandırır. - Yutulan promise reddi:
awaitedilmeyen ya da.catch()verilmeyen bir promise, modern Node sürümlerinde süreci düşürür. - WebSocket kopması: Ağ dalgalanması veya Discord tarafındaki yeniden başlatmalar bağlantıyı koparır; discord.js çoğu zaman kendi yeniden bağlanır ama bazen
disconnectdurumunda takılır. - Bellek sızıntısı: Sürekli büyüyen cache veya temizlenmeyen
setInterval'lar saatler içinde süreci OOM (Out Of Memory) ile öldürtür. - Rate limit ve geçersiz token: Token sıfırlanırsa ya da kötü kod 429 yağmuruna yol açarsa gateway bağlantısı reddedilir.
Bu listeye bakınca çözüm netleşiyor: hataları görünür kıl, süreci gözeten bir bekçi koy, ve botun gerçekten "canlı" olup olmadığını dışarıdan ölç.
Adım 1: Hataları sessizce yutturma
İlk savunma hattı kodun kendisidir. Botun çökse bile neden çöktüğünü loglaması gerekir, yoksa restart döngüsünde aynı hatayı sonsuza dek tekrarlarsınız. discord.js istemcisine ve global süreç olaylarına dinleyici ekleyin:
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); // bilinçli olarak çık; pm2 yeniden başlatsın
});
Burada önemli bir tasarım kararı var: uncaughtException yakalandığında süreci kasıtlı olarak sonlandırıyoruz. Bilinmeyen bir hatadan sonra süreci yaşatmaya çalışmak, yarı bozuk bir durumla devam etmek demektir. Temiz çözüm, logla ve çık; ayağa kaldırma işini bir süreç yöneticisine bırak.
Adım 2: pm2 ile otomatik yeniden başlatma
pm2, Node uygulamalarını arka planda çalıştıran, çöktüklerinde otomatik yeniden başlatan ve loglarını toplayan bir süreç yöneticisidir. VPS'inize global kurun:
npm install -g pm2
Botu doğrudan başlatabilirsiniz ama yapılandırmayı bir ecosystem.config.js dosyasında tutmak çok daha temizdir:
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' }
}]
};
Önemli alanlar:
- autorestart: Süreç çıktığında pm2 onu yeniden başlatır.
- max_memory_restart: Bellek 300 MB'ı aşarsa botu proaktif olarak yeniden başlatır; sızıntılara karşı sigorta.
- restart_delay: Yeniden başlatmadan önce 5 saniye bekler, böylece geçersiz token gibi kalıcı hatalarda CPU'yu kızdıran sonsuz döngü oluşmaz.
- min_uptime + max_restarts: Bot 10 saniye ayakta kalamadan 10 kez çökerse pm2 onu "errored" olarak işaretler ve durdurur; bu, gerçek bir sorunu sonsuz restart altında gizlemenizi engeller.
Başlatma ve sunucu yeniden açıldığında otomatik kalkması için:
pm2 start ecosystem.config.js
pm2 save
pm2 startup # çıktıdaki komutu çalıştırın
Logları ve durumu izlemek için pm2 logs discord-bot ve pm2 status komutlarını kullanın.
Adım 3: Bir healthcheck endpoint'i
pm2 süreç çalışıyor mu sorusuna cevap verir, ama "süreç ayakta ama Discord gateway'i kopmuş" durumunu yakalayamaz. Botun gerçekten canlı olduğunu doğrulamak için küçük bir HTTP healthcheck ekleyin. Yerleşik http modülü yeterlidir:
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);
Artık curl http://localhost:3001 ile botun gateway durumunu ve ping'ini görebilirsiniz. Bu endpoint'i sadece process.uptime() ile değil, gerçekten gateway'in READY olup olmadığıyla ilişkilendirmek kritik; aksi halde "yaşayan ölü" bir botu sağlıklı sanırsınız.
Adım 4: Dışarıdan izleme ve uyarı
Son halka, bir şeyler ters gittiğinde haberdar olmak. Healthcheck endpoint'ini ücretsiz bir izleme servisine (örneğin UptimeRobot, Better Stack veya kendi cron'unuz) bağlayın; 503 dönerse ya da yanıt vermezse size e-posta/Discord webhook bildirimi gelsin. Basit bir kendi kendini izleyen yaklaşım da işe yarar:
setInterval(() => {
if (!client.isReady()) {
console.error('[health] bot READY değil, çıkılıyor');
process.exit(1); // pm2 temiz bir başlangıç yapsın
}
}, 60_000);
Bu döngü, gateway sessizce takılırsa süreci bilinçli olarak düşürüp pm2'nin temiz bir yeniden bağlanma yapmasını sağlar. discord.js'in kendi yeniden bağlanma mantığını çoğu zaman beklemek daha iyidir, ama "zombi" durumlar için bu son çare güvenlidir.
Sık Sorulan Sorular
Botumu bedava barındırmada (Replit gibi) 7/24 ayakta tutabilir miyim?
Çoğu ücretsiz katman, trafik olmadığında süreci uyutur; bu yüzden gerçek 7/24 uptime için en sağlam yol küçük bir VPS'tir. Ping atarak uyanık tutma hileleri kırılgandır ve birçok platformun kullanım şartlarına aykırıdır. Tek bir bot için aylık birkaç dolarlık bir VPS + pm2 çok daha güvenilirdir.
pm2 yerine systemd veya Docker kullanmalı mıyım?
Üçü de geçerlidir. systemd Linux'a yerleşiktir ve servis düzeyinde restart sunar; Docker, restart: unless-stopped politikasıyla aynı işi yapar. pm2'yi öneren şey, log toplama, bellek tabanlı restart ve pm2 status gibi ergonomilerin tek araçta gelmesidir. Zaten Docker kullanıyorsanız konteyner restart politikası genelde yeterlidir.
Sürekli yeniden başlayan bir restart döngüsünü nasıl durdururum?
min_uptime ve max_restarts tam olarak bunun içindir: bot kısa sürede çok kez çökerse pm2 vazgeçer. Bu noktada pm2 logs ile kök nedeni (genelde geçersiz token, eksik env değişkeni veya kodda atılan sabit bir hata) bulup düzeltin.
Botunuz hâlâ açıklanamayan şekilde düşüyor mu? Çökme tespiti, pm2 yapılandırması ve healthcheck izlemeyi sizin için kurabilirim; dayanıklı, kendini toparlayan bir bot altyapısı için benimle iletişime geçin.