Gereksinimler ve Ön Hazırlık
Çalışmalara başlamadan önce bilgisayarınızda Node.js'in güncel bir LTS (Long Term Support) sürümünün yüklü olduğundan emin olmalısınız. 2026 itibarıyla Node.js 22.x veya üzeri bir sürüm kullanmanız önerilir. Projenizi başlatmak için bir terminal açın ve aşağıdaki komutları izleyin.
# Yeni bir dizin oluşturun ve içine girin
mkdir node-cron-projesi
cd node-cron-projesi
# Projeyi başlatın
npm init -y
# Gerekli kütüphaneyi kurun
npm install node-cron
Yukarıdaki adımlarla projenizi başlattınız ve en popüler zamanlama kütüphanesi olan node-cron paketini yüklediniz. Bu kütüphane, Unix tabanlı sistemlerdeki "cron" sözdizimini kullanarak görevlerinizi planlamanıza olanak tanır.
Node-cron Kullanarak Basit Görev Zamanlama
node-cron, zamanlama işlemlerini standart cron sözdizimi ile yapar. Bu sözdizimi beş ana parametreden oluşur: dakika, saat, ayın günü, ay ve haftanın günü. İlk örneğimizde, her dakika çalışan basit bir loglama mekanizması kuracağız.
const cron = require('node-cron');
// Her dakikanın 0. saniyesinde çalışır
cron.schedule('* * * * *', () => {
console.log('Görev çalıştırıldı: ' + new Date().toLocaleString());
});
Bu kod bloğu, uygulamanız çalıştığı sürece her dakika konsola o anki zamanı yazdırır. * * * * * ifadesi "her dakika" anlamına gelir.
Zamanlama Sözdizimi ve Detaylı Ayarlar
Zamanlanmış görevlerinizi daha spesifik hale getirmek için cron sözdizimini doğru anlamak gerekir. Örneğin, her gün gece yarısı saat 00:00'da çalışacak bir görev için şu yapıyı kullanırız:
// Her gün saat 00:00'da çalışır
cron.schedule('0 0 * * *', () => {
console.log('Günlük yedekleme işlemi başladı.');
});
Aşağıdaki tablo, sık kullanılan cron zamanlama yapılarını özetlemektedir:
| Sözdizimi | Açıklama |
|---|---|
| * * * * * | Her dakika |
| 0 * * * * | Her saatin başında |
| 0 0 * * * | Her gün gece yarısı |
| 0 0 * * 0 | Her Pazar gece yarısı |
Görevleri Yönetme: Başlatma ve Durdurma
Bazen bir görevi koşullara bağlı olarak durdurmanız veya başlatmanız gerekebilir. node-cron, döndürdüğü nesne üzerinden stop() ve start() metodlarını kullanmanıza izin verir.
const gorev = cron.schedule('* * * * *', () => {
console.log('Görev aktif.');
}, {
scheduled: false // Otomatik başlamasını engeller
});
// Görevi manuel başlat
gorev.start();
// Görevi 5 saniye sonra durdur
setTimeout(() => {
gorev.stop();
console.log('Görev durduruldu.');
}, 5000);
Bu yöntem, özellikle kullanıcı etkileşimine bağlı olarak arka plan işlemlerini kontrol etmeniz gereken durumlarda oldukça kullanışlıdır.
Kritik Uyarı: Üretim ortamında (production) zamanlanmış görevleri çalıştırırken, uygulamanızın beklenmedik şekilde çökmesi durumunda görevlerin tekrar tetiklenip tetiklenmeyeceğini planlamalısınız. Veritabanı işlemleri yapıyorsanız, aynı görevin aynı anda iki kez çalışmasını engelleyen "lock" (kilitleme) mekanizmaları kullanın.
Node.js ile Asenkron Görev Yönetimi
Çoğu zaman, zamanlanmış görevleriniz veritabanı sorgusu veya API çağrısı gibi asenkron işlemler içerecektir. Bu durumlarda async/await yapısını kullanmak, kodunuzun okunabilirliğini ve hata yönetimini artırır.
const cron = require('node-cron');
cron.schedule('*/5 * * * *', async () => {
try {
console.log('Veritabanı temizliği başlıyor...');
// Örnek: await Veritabani.temizle();
console.log('Temizlik başarıyla tamamlandı.');
} catch (error) {
console.error('Görev sırasında hata oluştu:', error);
}
});
Bu örnekte, try-catch bloğu kullanarak olası hataları yakaladık. Asenkron görevlerde hata yönetimi, uygulamanın genel kararlılığı için hayati önem taşır.
Dağıtık Sistemlerde Zamanlanmış Görevler
Eğer uygulamanızı birden fazla sunucuda (load balancer arkasında) çalıştırıyorsanız, aynı görevin her sunucuda ayrı ayrı çalışması ciddi veri tutarsızlıklarına yol açabilir. Bu gibi durumlarda merkezi bir kuyruk sistemi (örneğin Redis tabanlı BullMQ) kullanmak, "sadece bir kez çalıştır" prensibini garanti altına alır.
// BullMQ örneği (kavramsal)
const { Queue } = require('bullmq');
const gorevKuyrugu = new Queue('gunluk-rapor');
async function gorevEkle() {
await gorevKuyrugu.add('rapor-olustur', { tarih: new Date() });
}
Bu yaklaşım, büyük ölçekli uygulamalarda standart bir yöntemdir. Görevler bir kuyruğa atılır ve sadece bir worker (çalışan) tarafından işlenir.
Güvenlik Sorumluluk Reddi: Zamanlanmış görevlerinizde dış kaynaklardan gelen verileri kullanıyorsanız, SQL Injection ve XSS saldırılarına karşı verilerinizi mutlaka doğrulayın ve sterilize edin. Asla kullanıcıdan gelen ham veriyi doğrudan veritabanı sorgusunda çalıştırmayın.
Sıkça Sorulan Sorular
Node-cron yerine neden BullMQ kullanmalıyım?
Basit projeler için node-cron yeterlidir. Ancak dağıtık sistemlerde, görevlerin tekrar denenmesi (retry), hata takibi ve ölçeklenebilirlik gerekiyorsa BullMQ gibi kuyruk sistemleri çok daha güvenlidir.
Zamanlanmış görevler sunucuyu yavaşlatır mı?
Eğer görevleriniz ağır hesaplamalar içeriyorsa, ana event loop'u bloklayabilirler. Bu durumda işlemleri ayrı bir worker thread veya ayrı bir mikroservis üzerinde çalıştırmalısınız.
Zaman dilimi (Timezone) ayarlarını nasıl yaparım?
node-cron, schedule fonksiyonunun üçüncü parametresinde timezone seçeneğini destekler. Örneğin: { timezone: "Europe/Istanbul" }.
Görevlerin çalıştığını nasıl test ederim?
En basit yöntem, her görev tetiklendiğinde bir log dosyasına kayıt yazmaktır. Ayrıca jest gibi test kütüphaneleri ile zamanlayıcıyı mock'layarak (taklit ederek) test edebilirsiniz.
Sunucu yeniden başlatıldığında görevler ne olur?
Node.js uygulaması kapandığında zamanlayıcı da durur. Uygulama tekrar başlatıldığında görevler kaldığı yerden devam eder. Eğer görevlerin kaçırılmaması gerekiyorsa, veritabanı tabanlı bir görev takip sistemi kullanmalısınız.
Zamanlanmış Görevlerde Hata Ayıklama ve Loglama Stratejileri
Zamanlanmış görevler genellikle arka planda çalıştığı için, bir hata oluştuğunda bunu fark etmek zor olabilir. Görevlerin sessizce başarısız olmasını engellemek için merkezi bir loglama mekanizması kurmak kritik öneme sahiptir. Winston veya Pino gibi kütüphaneler kullanarak, her görev başlangıcını ve bitişini zaman damgalarıyla kayıt altına almalısınız.
Aşağıdaki örnek, bir görevin hata alması durumunda nasıl yakalanacağını ve loglanacağını göstermektedir:
const cron = require('node-cron');
const logger = require('./logger'); // Winston veya benzeri bir logger
cron.schedule('0 * * * *', async () => {
logger.info('Veri temizleme görevi başladı.');
try {
await performDatabaseCleanup();
logger.info('Veri temizleme görevi başarıyla tamamlandı.');
} catch (error) {
logger.error('Veri temizleme görevi sırasında hata oluştu:', {
message: error.message,
stack: error.stack
});
// Burada hata bildirim servisine (Sentry vb.) bildirim gönderebilirsiniz
}
});
Zamanlanmış Görevler İçin İleri Seviye İzleme (Monitoring)
Uygulamanız büyüdükçe, görevlerin zamanında çalışıp çalışmadığını manuel kontrol etmek imkansız hale gelir. "Dead Man's Snitch" veya "Healthchecks.io" gibi servisler, görevlerinizin düzenli olarak "ping" atmasını bekler. Eğer görev belirlenen zamanda çalışmazsa, bu servisler size e-posta veya Slack üzerinden uyarı gönderir.
Bu yöntem, sunucunuzun çökmesi veya görevin sessizce hata vermesi durumunda sizi anında haberdar eder:
const axios = require('axios');
const cron = require('node-cron');
cron.schedule('0 9 * * *', async () => {
try {
await generateDailyReport();
// Görev başarılı olduğunda izleme servisine sinyal gönder
await axios.get('https://hc-ping.com/your-uuid-here');
} catch (error) {
console.error('Rapor oluşturulamadı:', error);
}
});
Görev Önceliklendirme ve Kaynak Yönetimi
Sunucuda aynı anda çok sayıda zamanlanmış görev çalışıyorsa, CPU ve bellek kullanımı ciddi şekilde artabilir. Bu durumu yönetmek için şu stratejileri uygulayabilirsiniz:
- Görevleri Dağıtın: Tüm görevleri aynı dakikada (örneğin 00:00) başlatmak yerine, aralarında 5-10 dakikalık boşluklar bırakın.
- İş Parçacığı (Worker) Kullanımı: Ağır hesaplama gerektiren görevleri ana Event Loop'u bloklamamak için
worker_threadsmodülü ile ayrı bir iş parçacığında çalıştırın. - Limitleme (Throttling): Aynı anda çalışan maksimum görev sayısını belirlemek için bir semafor (semaphore) yapısı kullanın.
Aşağıdaki kod, basit bir semafor mantığı ile görevlerin üst üste binmesini engeller:
let isTaskRunning = false;
cron.schedule('* * * * *', async () => {
if (isTaskRunning) {
console.warn('Önceki görev hala çalışıyor, atlanıyor.');
return;
}
isTaskRunning = true;
try {
await heavyComputationTask();
} finally {
isTaskRunning = false;
}
});
Sonuç
Node.js ile sunucu tarafında zamanlanmış görev çalıştırmak, uygulamanızın otomasyon kapasitesini artıran temel bir yetenektir. Başlangıç seviyesinde node-cron ile hızlıca sonuç alabilir, uygulamanız büyüdükçe BullMQ gibi daha profesyonel kuyruk sistemlerine geçiş yapabilirsiniz. Bir sonraki adım olarak, görevlerinizin başarısızlık durumlarını izleyen bir "monitoring" (izleme) paneli kurmayı deneyebilirsiniz.


Yorumlar (0)
Yorum Yaz