介绍
cron
提供了在特定的时间间隔中重复任务的方法,可能有重复性的任务,例如记录和执行备份,需要每天或每周或每月进行。
在 Node.js 服务器上实现cron
的一种方法是使用node-cron
模块(https://www.npmjs.com/package/node-cron),该库使用了crontab
语法,这些语法可能熟悉以前在类似 Unix 的操作系统中使用cron
的用户。
在本文中,您将使用node-cron
来定期从服务器中删除日志文件,您还将被介绍两个其他常见的使用案例 - 备份数据库和发送计划电子邮件。
<$>[info] 简化使用 DigitalOcean App Platform的 cron 任务部署。
前提条件
要通过这个教程,你需要:
- Node.js 的本地开发环境 遵循 如何安装 Node.js 并创建本地开发环境。
本教程已通过 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 *
。
- 它将分钟和小时的值定义为
0
和0
(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
。
- 它定义了分钟和小时的值为
0
和0
(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 主题页面以获取练习和编程项目。