Gereksinimler ve Ön Hazırlık
Uygulamaya başlamadan önce sisteminizde 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 yılı itibarıyla Node.js 22 veya üzeri sürümler, performans ve güvenlik iyileştirmeleri nedeniyle önerilmektedir.
- Node.js (v22+) yüklü olmalıdır.
- Proje dizininizi oluşturun ve
npm init -ykomutu ile başlatın. - Zamanlanmış görevler için endüstri standardı olan
node-cronpaketini kurun.
Projenizi hazırlamak için terminalinizde şu komutları çalıştırın:
mkdir node-cron-app
cd node-cron-app
npm init -y
npm install node-cron
Bu komutlar, projenizin temelini atacak ve gerekli bağımlılığı node_modules klasörüne ekleyecektir. Artık kodlamaya başlamaya hazırsınız.
Node-cron Kütüphanesi ile İlk Görevi Oluşturma
Node-cron, Linux sistemlerdeki standart cron sözdizimini (syntax) Node.js ortamına taşıyan güçlü bir kütüphanedir. İlk adım olarak, her dakika çalışan basit bir loglama görevi oluşturalım.
const cron = require('node-cron');
// Her dakikanın başında çalışan görev
cron.schedule('* * * * *', () => {
console.log('Görev çalıştırıldı: ' + new Date().toLocaleString());
});
Yukarıdaki kod bloğu, * * * * * ifadesini kullanarak görevi her dakika tetikler. Bu ifade sırasıyla; dakika, saat, ayın günü, ay ve haftanın günü alanlarını temsil eder.
Cron Zamanlama Sözdizimi (Syntax) Anlama
Cron ifadeleri, görevlerinizin ne zaman tetikleneceğini belirleyen 5 ana bileşenden oluşur. Bu yapıyı doğru anlamak, görev yönetimi başarınız için kritiktir.
| Alan | Açıklama | Örnek |
|---|---|---|
| Dakika | 0-59 | */15 (Her 15 dakikada) |
| Saat | 0-23 | 0 9 (Her gün 09:00'da) |
| Ayın Günü | 1-31 | 1 (Her ayın 1'inde) |
| Ay | 1-12 | * (Her ay) |
| Haftanın Günü | 0-7 (0 ve 7 Pazar'dır) |
Örneğin, her gün saat 03:00'te veritabanı yedeği alan bir görev için 0 3 * * * ifadesini kullanmalısınız.
Görev Yönetiminde Hata Yönetimi ve Güvenlik
Zamanlanmış görevler arka planda çalıştığı için, bir hata oluştuğunda uygulamanın çökmemesi gerekir. Görevlerinizi her zaman try-catch blokları ile sarmalayın ve loglama mekanizmaları kullanın.
cron.schedule('0 0 * * *', async () => {
try {
console.log('Günlük temizlik başladı...');
// Veritabanı temizleme işlemi
await performDatabaseCleanup();
} catch (error) {
console.error('Görev sırasında hata oluştu:', error.message);
// Hata raporlama servisine gönder (örn: Sentry)
}
});
Bu yaklaşım, bir hata gerçekleştiğinde uygulamanın geri kalanının çalışmaya devam etmesini sağlar. Ayrıca, hassas verilerle işlem yaparken çevre değişkenlerini (environment variables) kullanmayı ihmal etmeyin.
Kritik Güvenlik Uyarısı: Üretim ortamında cron görevleri ile veritabanı işlemlerini yönetirken, asla veritabanı kimlik bilgilerini kod içerisinde açık metin olarak bulundurmayın.
dotenvpaketini kullanarak bu bilgileri güvenli bir şekilde yönetin.
Ölçeklenebilir Görev Yönetimi: Görevleri Durdurma ve Başlatma
Bazen bir görevi dinamik olarak durdurmanız veya başlatmanız gerekebilir. node-cron, döndürdüğü Task nesnesi üzerinden bu kontrolü sağlar.
const task = cron.schedule('* * * * *', () => {
console.log('Bu görev durdurulabilir.');
}, {
scheduled: false // Başlangıçta çalışmasın
});
// Görevi başlat
task.start();
// 5 dakika sonra görevi durdur
setTimeout(() => {
task.stop();
console.log('Görev durduruldu.');
}, 300000);
Bu yöntem, özellikle kullanıcı bazlı zamanlanmış bildirimler gibi dinamik ihtiyaçlarda oldukça kullanışlıdır.
Üretim Ortamı İçin İpuçları (Best Practices)
Uygulamanızı sunucuya taşıdığınızda, Node.js sürecinin (process) beklenmedik şekilde sonlanması durumunda görevlerinizin aksamaması gerekir. PM2 gibi bir süreç yöneticisi kullanmak, uygulamanızın her zaman ayakta kalmasını sağlar.
# PM2 kurulumu
npm install pm2 -g
# Uygulamanızı PM2 ile başlatın
pm2 start app.js --name "cron-service"
PM2, uygulamanız çökerse otomatik olarak yeniden başlatır ve cron görevlerinizin sürekliliğini garanti altına alır.
Sıkça Sorulan Sorular
Node-cron ile saniye bazlı görev tanımlayabilir miyim?
Evet, node-cron kütüphanesi 6. bir alan olarak "saniye" desteği sunar. */10 * * * * * ifadesi, görevin her 10 saniyede bir çalışmasını sağlar.
Cron görevleri uygulamanın performansını etkiler mi?
Eğer görevleriniz çok yoğun işlem gücü (CPU) gerektiriyorsa, ana iş parçacığını (main thread) bloke edebilir. Bu durumda görevleri ayrı bir Worker Thread veya mikroservis yapısı ile çalıştırmanız önerilir.
Birden fazla görev için ayrı dosyalar oluşturmalı mıyım?
Evet, projeniz büyüdükçe görevleri tasks/ adında bir klasör altında modüler hale getirmek, bakım kolaylığı sağlar.
Zaman dilimi (Timezone) sorunlarını nasıl çözerim?
node-cron içerisinde timezone seçeneğini kullanarak görevin sunucunun yerel saati yerine belirli bir zaman dilimine göre çalışmasını sağlayabilirsiniz.
Cron görevlerini test etmek için ne yapmalıyım?
Görevlerinizi test ederken zaman aralıklarını * * * * * yerine daha kısa periyotlara çekerek (örn: 10 saniye) sonuçları hızlıca gözlemleyebilirsiniz.
Sorumluluk Reddi: Bu rehberdeki kod örnekleri genel eğitim amaçlıdır. Üretim ortamında çalışacak kritik görevler için hata toleransı, loglama ve güvenlik denetimlerini (SQL injection, XSS vb.) kendi uygulama mimarinize göre özelleştirmeniz gerekmektedir.
Redis Tabanlı Kuyruk Sistemlerine Geçiş: BullMQ
Node-cron, basit ve zamanlanmış görevler için mükemmel bir çözüm olsa da, uygulamanız büyüdükçe ve görevleriniz daha karmaşık hale geldikçe (örneğin; binlerce e-posta gönderimi, ağır veri işleme süreçleri) tek bir işlem (process) üzerinde çalışmak darboğazlara yol açabilir. Bu noktada BullMQ gibi Redis tabanlı kuyruk sistemleri devreye girer.
BullMQ, görevlerinizi kalıcı hale getirir, hata durumunda otomatik olarak yeniden deneme (retry) mekanizması sunar ve görevlerin farklı worker süreçleri tarafından işlenmesine olanak tanır. İşte temel bir BullMQ kuyruk yapısı örneği:
const { Queue, Worker } = require('bullmq');
// Kuyruk oluşturma
const emailQueue = new Queue('email-queue', {
connection: { host: '127.0.0.1', port: 6379 }
});
// Görev ekleme
async function addEmailJob(data) {
await emailQueue.add('send-email', data, {
attempts: 3, // Hata durumunda 3 kez dene
backoff: { type: 'exponential', delay: 1000 }
});
}
// Worker (İşleyici) oluşturma
const worker = new Worker('email-queue', async job => {
console.log(`İşleniyor: ${job.id}`);
// Burada ağır e-posta gönderme işlemini yapın
}, { connection: { host: '127.0.0.1', port: 6379 } });
Cron Görevlerinde "Race Condition" ve Çakışma Yönetimi
Özellikle veritabanı üzerinde işlem yapan cron görevlerinde, bir önceki görev henüz bitmeden diğerinin başlaması ciddi veri tutarsızlıklarına neden olabilir. Bu duruma Race Condition denir. Bunu önlemek için görevlerinizi "kilitli" (locking) bir yapıda çalıştırmanız önerilir.
Görev Kilitleme Mekanizması
Görevlerin çakışmasını engellemek için bir bayrak (flag) değişkeni veya Redis üzerinde bir "lock" anahtarı kullanabilirsiniz. Aşağıdaki örnekte, görev çalışırken bir bayrak kontrolü yapılarak çakışma önlenmektedir:
let isTaskRunning = false;
cron.schedule('*/1 * * * *', async () => {
if (isTaskRunning) {
console.log('Önceki görev hala devam ediyor, atlanıyor...');
return;
}
isTaskRunning = true;
try {
await performHeavyDatabaseOperation();
} catch (error) {
console.error('Görev hatası:', error);
} finally {
isTaskRunning = false;
}
});
Bu yaklaşım, özellikle veritabanı temizleme veya dış API'lerden veri çekme gibi uzun süren işlemlerde uygulamanızın kararlılığını korumak için kritik öneme sahiptir. Eğer dağıtık bir sistemde (birden fazla sunucuda) çalışıyorsanız, bu kilit mekanizmasını Redis gibi merkezi bir veri deposunda tutmanız gerektiğini unutmayın.
Sonuç
Node.js ile cron jobs kullanarak görev yönetimi yapmak, uygulamanızın otomasyon kapasitesini ciddi oranda artırır. Bu rehberde, kütüphane kurulumundan başlayarak, cron sözdizimini anlamaya, hata yönetiminden üretim ortamı ipuçlarına kadar geniş bir perspektif sunduk. Bir sonraki adım olarak, karmaşık görevlerinizi yönetmek için BullMQ gibi Redis tabanlı kuyruk sistemlerini inceleyerek, görevlerinizi daha ölçeklenebilir bir yapıya taşıyabilirsiniz.


Yorumlar (0)
Yorum Yaz