如何使用 node-cron 在 Node.js 中运行预定任务

介绍

cron提供了在特定的时间间隔中重复任务的方法,可能有重复性的任务,例如记录和执行备份,需要每天或每周或每月进行。

在 Node.js 服务器上实现cron的一种方法是使用node-cron模块(https://www.npmjs.com/package/node-cron),该库使用了crontab语法,这些语法可能熟悉以前在类似 Unix 的操作系统中使用cron的用户。

Screenshot of a task repeatedly running every minute

在本文中,您将使用node-cron来定期从服务器中删除日志文件,您还将被介绍两个其他常见的使用案例 - 备份数据库和发送计划电子邮件。

<$>[info] 简化使用 DigitalOcean App Platform的 cron 任务部署。

前提条件

要通过这个教程,你需要:

本教程已通过 Node v17.2.0、npm v8.1.4、node-cron v2.0.3、shelljs v0.8.4 和nodemailer v6.7.2 进行验证。

步骤 1 — 创建一个节点应用程序和安装依赖性

要开始,请通过打开终端并为您的项目创建一个新的文件夹来创建一个新的 Node 应用程序:

1mkdir node-cron-example

接下来,更改到新项目目录:

1cd node-cron-example

然后初始化它,创建一个package.json文件,您将使用它来跟踪依赖:

1npm init --yes

通过运行以下命令添加node-cron模块:

1npm install [email protected]

node-cron模块是任务计划器。

项目依赖性已安装. 让我们构建服务器。

步骤二:安排一个任务

现在,您可以构建服务器,并使用node-cron来安排一个任务每分钟运行。

创建一个新的 cron-ping.js 文件:

1nano cron-ping.js

然后,需要node-cron:

1[label cron-ping.js]
2const cron = require('node-cron');

接下来,添加以下代码行到 cron-ping.js:

1[label cron-ping.js]
2// ...
3
4// Schedule tasks to be run on the server.
5cron.schedule('* * * * *', function() {
6  console.log('running a task every minute');
7});

这些星座是crontab语法的一部分,代表不同的时间单位:

1* * * * * *
2  | | | | | |
3  | | | | | day of week
4  | | | | month
5  | | | day of month
6  | | hour
7  | minute
8  second ( optional )

一个星座就像一张野卡一样行事,这意味着该任务将为该时间单位的每个实例运行。

代替星座的数字将被视为该时间单位的值,从而允许您安排任务每天和每周或更复杂地发生。

<$>[注] 注:如何在VPS上使用Cron来自动化任务中了解有关该标注的更多信息。

现在,运行脚本:

1node cron-ping.js

几分钟后,你会得到以下结果:

1[secondary_label Output]
2running a task every minute
3running a task every minute
4running a task every minute
5...

您每分钟都有一个示例任务运行,您可以用CTRL+C(CONTROL+C)阻止服务器。

现在,让我们看看如何更详细地执行任务。

步骤三:删除错误日志

考虑一个场景,您需要在每个月的二十一日从服务器上定期删除日志文件。

创建一个名为error.log的示例日志文件:

1nano error.log

然后,添加一个测试消息:

1[label error.log]
2This is an example error message that in a log file that will be removed on the twenty-first day of the month.

创建一个新的 cron-delete.js 文件:

1nano cron-delete.js

此任务将使用fs解链接一个文件. 将其添加到文件的顶部:

1[label cron-delete.js]
2const cron = require('node-cron');
3const fs = require('fs');

接下来,添加以下代码行:

 1[label cron-delete.js]
 2// ...
 3
 4// Remove the error.log file every twenty-first day of the month.
 5cron.schedule('0 0 21 * *', function() {
 6  console.log('---------------------');
 7  console.log('Running Cron Job');
 8  fs.unlink('./error.log', err => {
 9    if (err) throw err;
10    console.log('Error file successfully deleted');
11  });
12});

注意模式: 0 0 21 *

  • 它将分钟和小时的值定义为00(00:00 - 白天的开始)。
  • 它将白天的值定义为21

现在,运行脚本:

1node cron-delete.js

在本月二十一日,您将获得以下结果:

1[secondary_label Output]
2---------------------
3Running Cron Job
4Error file successfully deleted

您可能不想等到一个月的二十一日来验证任务已经执行. 您可以更改日程安排器以在更短的时间间隔内运行 - 就像每分钟一样。

检查您的服务器目录. 将删除 error.log 文件。

您可以运行日程表中的任何操作. 操作从创建文件到发送电子邮件和运行脚本。

步骤 4 — 探索使用node-cron来备份数据库

确保用户数据的保存是任何业务的关键。如果发生意外事件,您的数据库被破坏或损坏,您将需要从备份中恢复您的数据库。

考虑一个场景,您需要每天晚上11点59分定期备份数据库的漏洞,您可以使用node-cron来实现这一点。

<$>[注] :此用例涉及设置本地 SQLite 数据库。 安装和创建数据库的细节不包括在这里。

假设您已安装并在您的环境中运行 SQLite. 考虑到名为 `database.sqlite’ 的数据库,您创建数据库备份的壳命令可能类似于此:

1sqlite3 database.sqlite .dump > data_dump.sql

此命令将数据库database.sqlite并运行.dump命令,并将结果输出为名为data_dump.sql的文件。

接下来,安装shelljs,一个节点模块,允许您运行之前的壳命令:

1npm install [email protected]

创建一个新的 cron-dump.js 文件:

1nano cron-dump.js

然后,需要shelljs:

1[label cron-dump.js]
2const cron = require('node-cron');
3const shell = require('shelljs');

接下来,添加以下代码行:

 1[label cron-dump.js]
 2// ...
 3
 4// Backup a database at 11:59 PM every day.
 5cron.schedule('59 23 * * *', function() {
 6  console.log('---------------------');
 7  console.log('Running Cron Job');
 8  if (shell.exec('sqlite3 database.sqlite .dump > data_dump.sql').code !== 0) {
 9    shell.exit(1);
10  }
11  else {
12    shell.echo('Database backup complete');
13  }
14});

请注意图案: 59 23 * *

  • 它将每分钟的值定义为 `59′.
  • 它将每小时的值定义为 23′(或 24 小时时钟中的 11 PM)。

此代码将运行备份壳命令. 如果成功,它将响应消息.否则,如果有错误,它将退出。

现在,运行脚本:

1node cron-dump.js

下午11点59分,您将收到以下输出:

1[secondary_label Output]
2---------------------
3Running Cron Job
4Database backup complete

您可能不想等到下午11点59分才能验证任务已经执行,您可以更改日程表以在更短的时间间隔内运行。

检查您的服务器目录. 将出现一个 data_dump.sql 文件。

接下来,让我们看看发送定期电子邮件。

步骤 5 — 探索使用节点cron发送预定电子邮件

考虑一个场景,你策划一个有趣的链接列表,然后每周三向订阅者发送电子邮件。

创建一个Ethereal帐户,并使用为您生成的用户名和密码。

<$>[警告] 警告:强烈建议您不要为此步骤使用您的个人电子邮件帐户。

接下来,安装nodemailer,一个节点模块,允许您发送电子邮件:

1npm install [email protected]

创建一个新的 cron-mail.js 文件:

1nano cron-mail.js

然后,需要nodemailer:

1[label cron-mail.js]
2const cron = require('node-cron');>
3const nodemailer = require('nodemailer');

添加一个部分,定义邮件发送商,并为电子邮件帐户设置用户名和密码:

 1[label cron-mail.js]
 2// ...
 3
 4// Create mail transporter.
 5let transporter = nodemailer.createTransport({
 6  host: 'your_demo_email_smtp_host.example.com',
 7  port: your_demo_email_port,
 8  auth: {
 9    user: '[email protected]',
10    pass: 'your_demo_email_password'
11  }
12});

<$>[警告] 警告:此步骤仅用于示例用途。在生产环境中,您将使用环境变量来保密您的密码。

接下来,添加以下代码行:

 1[label cron-mail.js]
 2// ...
 3
 4// Sending emails every Wednesday.
 5cron.schedule('0 0 * * 3', function() {
 6  console.log('---------------------');
 7  console.log('Running Cron Job');
 8
 9  let messageOptions = {
10    from: '[email protected]',
11    to: '[email protected]',
12    subject: 'Scheduled Email',
13    text: 'Hi there. This email was automatically sent by us.'
14  };
15
16  transporter.sendMail(messageOptions, function(error, info) {
17    if (error) {
18      throw error;
19    } else {
20      console.log('Email successfully sent!');
21    }
22  });
23});

注意模式: 0 0 * 3

  • 它定义了分钟和小时的值为00(00:00 - 天开始)。
  • 它不定义一个月或一个月的日
  • 它定义了周日的值为3(星期三)。

此代码将使用所提供的身份证来向您发送电子邮件。主题行:计划电子邮件和身体文本:`你好,这个电子邮件是由我们自动发送的。

现在,运行脚本:

1node cron-mail.js

周三,你会得到以下结果:

1[secondary_label Output]
2---------------------
3Running Cron Job
4Email successfully sent!

您可能不想等到周三才能验证任务已执行. 您可以更改日程表以在更短的时间间隔内运行。

打开Ethereal电子邮件邮箱,在收件箱中会出现一个新的预定电子邮件

结论

在本文中,您了解了如何使用node-cron来在 Node.js 服务器上安排工作。

还有其他任务编程工具可用,请确保对它们进行评估,以确定哪个工具最适合您的特定项目。

如果您想了解有关 Node.js 的更多信息,请参阅 我们的 Node.js 主题页面以获取练习和编程项目。

Published At
Categories with 技术
comments powered by Disqus