Membuat Cronjob Di Nodejs - CRUDPRO

Membuat Cronjob Di Nodejs

Membuat Cronjob Di Nodejs

Semua developer cepat atau lambat menghadapi masalah bagaimana menangani Cron Job. Daftar kasus penggunaan untuk Cron Job sangat banyak. Ini termasuk membatalkan cache, membuat laporan, memperbarui data dari sumber eksternal, pemberitahuan, pencadangan, dan lainnya. Tentu saja, salah satu favorit saya adalah layanan malam dimulai ulang dengan kebocoran memori :) Implementasi beberapa tugas terschedule dari perspektif developeran dan infrastruktur.

Secara historis, Cron Job memiliki bentuk khusus dari definisi schedule https://en.wikipedia.org/wiki/Cron. Agak lucu bahwa kami masih menggunakan format yang dikembangkan pada tahun 70-an. Tidak intuitif sama sekali. Ada banyak alat daring yang mengubah tanda bintang, garis miring, dan angka menjadi bentuk yang dapat dibaca manusia. Misalnya, https://www.freeformatter.com/cron-expression-generator-quartz.html.

Oke cukup berceritanya. Mari kita lanjutkan untuk berlatih.

Cara jadul (pendekatan Linux)

Semua mesin Linux menginstal dan menjalankan daemon cron. Jadi cukup buat skrip tugas yang melakukan semua operasi yang diperlukan dan keluar, dan tambahkan ke cron menggunakan Ansible atau Puppet. Ini adalah solusi klasik, tetapi memiliki beberapa kelemahan.

  • Pertama-tama, developer tidak perlu khawatir tentang lingkungan server karena sangat erat kaitannya dengan OS server.
  • distribusi beban. Administrator Linux perlu menemukan server dengan sumber daya gratis yang cukup untuk setiap tugas cron baru. Cron Job berjalan sesuai schedule, dan administrator Linux perlu melihat data pemantauan historis tentang beban server pada waktu yang dischedulekan sebelumnya, yang bisa sangat menantang.
  • Konkurensi. Tidak apa-apa jika Anda hanya memiliki satu server. Namun, jika Anda memiliki banyak server, Anda harus memastikan bahwa tugas cron diterapkan hanya ke satu server. Jika tidak, mereka akan berjalan secara bersamaan. Tugas pemberitahuan cron diterapkan dua kali, sehingga pelanggan tidak senang menerima dua email yang identik.

Seperti yang saya katakan sebelumnya, ini adalah solusi klasik yang mapan. Ini adalah pilihan yang baik jika Anda menggunakan proyek kecil di satu server Linux.

Cron di sisi Node.js

Pendekatan ini merupakan kebalikan dari pendekatan sebelumnya. Alih-alih mengandalkan infrastruktur, penschedulean cron dapat diletakkan di Node.js menggunakan pustaka seperti https://www.npmjs.com/package/node-cron. Sebagai contoh:

//cron-0.js
const cron = require('node-cron');

cron.schedule('* * * * *', () => {
  console.log('running a task every minute');
});

Skrip ini tidak pernah keluar dan bertindak seperti daemon. Solusi ini bersifat agnostik infrastruktur dan dapat dijalankan di mana saja, termasuk Docker. Anda juga dapat menggabungkan beberapa tugas cron menjadi satu skrip. Selain itu, Anda dapat membuat tugas cron baru secara dinamis saat runtime. Ini sangat nyaman dan fleksibel, tetapi seperti solusi sebelumnya, Anda harus memastikan bahwa aplikasi Anda hanya berjalan pada satu contoh.

modul Bull

Bull adalah pustaka Node.js untuk https://www.npmjs.com/package/bull antrian tugas yang mendukung Cron Job. Berbeda dengan dua solusi sebelumnya, ini menjamin bahwa pekerjaan tidak akan berjalan bersamaan. Ini sangat mudah digunakan:

//cron-1.js
const Bull = require('bull')

const redisURI = 'redis://127.0.0.1'

const testQueue = new Bull('test', redisURI);

testQueue.process(() => {
  console.log('Bull job executes every minute')
})

testQueue.add({}, {
  repeat: {
    cron: '* * * * *'
  }
})

Seperti yang Anda ketahui, Bull menggunakan Redis untuk penyimpanan tugas. Tapi apa yang terjadi jika Anda me-restart skrip ini? Apakah testQueue akan dischedulekan ulang dan menjalankan dua tugas setiap menit? Tidak, Bull akan mengurus ini. Mari schedulekan banyak tugas dari tugas yang sama:

// cron-2.js 
const Bull = require('bull')

const redisURI = 'redis://127.0.0.1'

const testQueue = new Bull('test', redisURI);

testQueue.process(() => {
  console.log('Bull job executes every minute')
})

testQueue.add({}, {
  repeat: {
    cron: '* * * * *'
  }
})

testQueue.add({}, {
  repeat: {
    cron: '* * * * *'
  }
})

testQueue.add({}, {
  repeat: {
    cron: '* * * * *'
  }
})

testQueue.add({}, {
  repeat: {
    cron: '* * * * *'
  }
})

Itu masih mencetak satu pesan per menit. Bull tidak akan membuat pekerjaan baru jika sudah disimpan di Redis. Apa yang terjadi jika Anda menjalankan skrip ini lebih dari sekali pada waktu yang bersamaan? tebak apa? Bull membagi tugas antar skrip. Sangat berguna untuk Cron Job yang berat. Bull juga mendukung pekerjaan yang tertunda seperti Cron Job yang dischedulekan, tetapi hanya dijalankan sekali.

Pikiran terakhir tentang Bull:

  • Infrastruktur agnostik, kecuali membutuhkan Redis
  • Melindungi dari eksekusi pekerjaan bersamaan
  • sepenuhnya dinamis
  • terukur

Menurut pendapat saya, Bull adalah pilihan terbaik untuk menangani Cron Job.

Cronjob Kubernetes

Ini adalah fitur yang benar-benar baru di Kubernetes. Anda dapat membaca dokumentasinya di https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/.

//cron-3.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

CronJob Kubernetes melakukan sesuatu yang sangat sederhana. Jalankan Docker Image sesuai schedule. Ini berarti Anda harus membuat Docker Image terlebih dahulu. CronJob Kubernetes dapat menjadi alternatif yang baik untuk Bull karena menghemat sumber daya Kubernetes. Bull harus berjalan seperti daemon dan menghabiskan sumber daya server selamanya. CronJob Kubernetes memulai sebuah Pod, menunggu sampai selesai, dan kemudian menghapus Pod tersebut.

Saya tidak ingin menulis kesimpulan, saya membaca tentang 4 pendekatan berbeda beserta pro dan kontranya, sehingga Anda dapat memutuskan sendiri mana yang lebih baik untuk Anda :)