Введение

cron позволяет повторять задачу через определенный интервал времени. Могут быть повторяющиеся задачи, такие как ведение журнала и создание резервных копий, которые необходимо выполнять ежедневно, еженедельно или ежемесячно.

Одним из способов реализации cron на сервере Node.js является использование модуля node-cron. Эта библиотека использует синтаксис crontab, который может быть знаком пользователям с предыдущим опытом использования cron в Unix-подобных операционных системах.

Для того чтоб пройти этот мини курс вам понадобится локальная среда разработки для Node.js.

*Это руководство было проверено с помощью Node v17.2.0, npm v8.1.4, node-cron v2.0.3, shelljs v0.8.4.

Создание приложения Node и установка зависимостей

Для начала создайте новое приложение Node, открыв терминал и создав новую папку для своего проекта:

mkdir node-cron-example

Затем перейдите в новый каталог проекта:

cd node-cron-example

Затем инициализируйте его, создав файл package.json, который вы будете использовать для отслеживания зависимостей:

npm init -y

Установите модуль node-cron, выполнив следующую команду:

npm install node-cron@3.0.0

Создание планировщика задач

Создайте новый файл cron-ping.js:

nano cron-ping.js

Затем потребуется node-cron:

const cron = require('node-cron');

Затем добавьте следующие строки кода в cron-ping.js:

// ...
// Schedule tasks to be run on the server.
cron.schedule('* * * * ', function() {
console.log('running a task every minute');
});

Эти звездочки являются частью синтаксиса crontab для представления различных единиц времени:

 _________________ second ( optional )
| ________________ minute
| |  _____________ hour
| | |  ___________ day of month
| | | |  _________ month
| | | | |  _______ day of week
| | | | | |
* * * * * *

Одна звездочка ведет себя как подстановочный знак. Это означает, что задача будет выполняться для каждого экземпляра этой единицы времени. Пять звездочек (* * * * *) обозначают запуск crontab по умолчанию каждую минуту.

Числа вместо звездочек будут рассматриваться как значения для этой единицы времени. Позволяет планировать выполнение задач ежедневно, еженедельно или более сложно.

Примечание. Узнайте больше о том, как работает эта нотация, в разделе Как использовать Cron для автоматизации задач на VPS.

Теперь запустите скрипт:

node cron-ping.js

Через несколько минут вы получите следующий результат:

Output:
running a task every minute
running a task every minute
running a task every minute
...

У вас есть пример задачи, которая выполняется каждую минуту. Вы можете остановить сервер с помощью CTRL+C (CONTROL+C).

Теперь давайте более подробно рассмотрим, как запускать задачи.

Пример использования node-cron для резервного копирования баз данных

Рассмотрим сценарий, в котором вам необходимо регулярно создавать резервную копию дампа базы данных в 23:59 каждый день. Вы можете сделать это с помощью node-cron.

Примечание. Этот вариант использования предполагает настройку локальной базы данных SQLite. Более тонкие детали установки и создания базы данных здесь не рассматриваются. Не стесняйтесь заменять на другую команду оболочки.

Предположим, что у вас установлен и запущен SQLite в вашей среде. При наличии базы данных с именем database.sqlite ваша команда оболочки для создания резервной копии базы данных может выглядеть следующим образом:

sqlite3 database.sqlite .dump > data_dump.sql

Эта команда берет базу данных database.sqlite, запускает команду .dump и выводит результат в виде файла с именем data_dump.sql.

Затем установите shelljs, модуль Node, который позволит вам запустить предыдущую команду оболочки:

npm install shelljs@0.8.4

Создайте новый файл cron-dump.js:

nano cron-dump.js

Затем потребуйте shelljs:

const cron = require('node-cron');
const shell = require('shelljs');

Затем добавьте следующие строки кода:

// ...
// Backup a database at 11:59 every day.
cron.schedule('59 23 * * *', function() {
console.log('---------------------');
console.log('Running Cron Job');
if (shell.exec('sqlite3 database.sqlite .dump > data_dump.sql').code !== 0) {
shell.exit(1);
}
else {
shell.echo('Database backup complete');
}
});

Обратите внимание на шаблон: 59 23 * * *.

  • Определяет значение минуты как 59.

  • Определяет значение часа как 23 (или 23:00 в 24-часовом формате).

  • Он не определяет день, месяц или день недели.

Этот код запустит команду оболочки резервного копирования. В случае успеха будет выведено сообщение. В противном случае, если есть ошибка, он выйдет.

Теперь запустите скрипт:

node cron-dump.js

В 23:59 вы получите следующий вывод:

Output---------------------
Running Cron Job
Database backup complete

На этом у меня всё! Надеюсь кому-то да помог)

Комментарии (11)


  1. yarkov
    24.12.2023 19:40

    Зачем? Чем обычный cron не устраивает?


    1. dos
      24.12.2023 19:40

      Здесь должна быть картинка с троллейбусом из буханки хлеба :)


    1. nee77
      24.12.2023 19:40

      Например, если nodejs приложение крутится в docker-контейнере, то так удобнее, чем обычный cron.


      1. kellas
        24.12.2023 19:40

        Тогда не мешало бы реализацию механизма блокировок написать, чтобы несколько инстансов одну задачу не запускали

        Механизм контроля успешности выполнения...

        Короче rabbitmq нужен )


        1. ilnuribat
          24.12.2023 19:40

          Мне хватает postgres, select for update


        1. nee77
          24.12.2023 19:40

          Ну дальше уже от задачи зависит. Мне как раз нужно, чтобы несколько инстансов одну операцию запускали. Обхожусь очередями в редисе.


  1. Metotron0
    24.12.2023 19:40

    Вроде, тут описание узкоспецифичной библиотеки, которая есть только в ноде. То есть, статья заинтересует только тех, кто пользуется нодой и кому нужен крон в ней. Но примеры кода начинаются с самых азов создания директории для проекта. Если нужно было раздуть статью, можно было описать и установку разных операционок. Кажется, всю подготовку вплоть до установки самого пакета можно убрать под спойлер, тем более, что человек, который пользуется нодой, пакеты ставить точно умеет, ему достаточно подсказвть название и путь к документации на всякий случай.

    Мне кажется, вся эта статья по сути может быть заменена ссылкой на документацию.


    1. yarkov
      24.12.2023 19:40

      Именно так. Особенно позабавило вот это:

      Вы можете остановить сервер с помощью CTRL+C (CONTROL+C).

      То есть нам предлагают обёртку на cron, которая будет по расписанию выполнять задачи пока активна вкладка терминала, где запущен скрипт.


      1. Metotron0
        24.12.2023 19:40

        Ну-у, есть же tmux.


  1. Neoldian
    24.12.2023 19:40

    Node-schedule такой же простой и минималистичный, но хотя бы есть graceful shutdown из коробки. Мне кажется очень важно для подобных сервисов иметь graceful restart, иначе могут быть сайд эффекты в виде пропусков при деплое или тех. работах, для большей надежности лучше конечно шедулер выносить отдельно с общей БД на задачи, например agenda та же самая.


  1. bankir1980
    24.12.2023 19:40

    А что же автор умолчал о такой важной фиче, о которой в документации по node-cron не написано? Если в функции schedule указать не функцию, которая должна запускаться по таймеру, а путь до js файла, то по таймеру будет запускаться отдельный процесс, который будет запускать функцию task из этого файла? Т.е. задачи можно запускать вне текущего процесса, а в отдельном. Это может быть важно, когда главный поток(процесс) нагружается.