node-schedule vs bull vs agenda
Node.js 任务调度库
node-schedulebullagenda类似的npm包:
Node.js 任务调度库

任务调度库用于在 Node.js 应用程序中管理和执行定时任务或后台作业。这些库提供了灵活的调度功能,允许开发者设置定时任务、重复任务和延迟任务,以便在特定时间或条件下执行特定操作。选择合适的任务调度库可以提高应用程序的效率和可维护性,确保任务按时执行并处理潜在的失败情况。

npm下载趋势
3 年
GitHub Stars 排名
统计详情
npm包名称
下载量
Stars
大小
Issues
发布时间
License
node-schedule3,021,6589,22335 kB1703 年前MIT
bull1,184,22516,171309 kB1481 年前MIT
agenda148,6669,583353 kB355-MIT
功能对比: node-schedule vs bull vs agenda

持久化

  • node-schedule:

    Node-schedule 不提供内置的持久化功能,任务在应用重启后会丢失,适合短期和简单的调度需求。

  • bull:

    Bull 使用 Redis 作为存储后端,支持任务的持久化和状态管理。即使在服务器崩溃后,任务也能恢复,确保高可用性。

  • agenda:

    Agenda 允许将任务持久化到 MongoDB 中,确保即使在应用重启后也能恢复任务状态。这使得它适合需要长期运行和管理的任务。

性能

  • node-schedule:

    Node-schedule 适合轻量级任务调度,性能良好,但在处理大量任务时可能不如 Bull 高效。

  • bull:

    Bull 在高并发场景下表现优异,能够处理大量任务,支持任务的并行处理和重试机制,适合需要高吞吐量的应用。

  • agenda:

    Agenda 的性能依赖于 MongoDB 的性能,适合中小型任务调度,但在高并发场景下可能会遇到瓶颈。

易用性

  • node-schedule:

    Node-schedule 的 API 非常简单,适合快速实现基本的定时任务,学习曲线平缓。

  • bull:

    Bull 的 API 设计清晰,适合需要复杂任务处理的应用,但学习曲线可能稍陡峭。

  • agenda:

    Agenda 提供了简单易用的 API,适合快速上手和开发,特别是对于已经使用 MongoDB 的项目。

调度灵活性

  • node-schedule:

    Node-schedule 支持 Cron 表达式,适合简单的定时任务调度,但灵活性相对较低。

  • bull:

    Bull 提供了丰富的任务管理功能,包括任务重试、延迟执行和优先级,适合需要复杂工作流的场景。

  • agenda:

    Agenda 支持复杂的调度规则,包括重复任务和优先级设置,适合需要灵活调度的应用。

社区支持

  • node-schedule:

    Node-schedule 的社区相对较小,但文档清晰,适合简单需求的开发者。

  • bull:

    Bull 拥有强大的社区支持和丰富的插件生态,适合需要扩展功能的项目。

  • agenda:

    Agenda 拥有活跃的社区和文档支持,适合需要社区帮助的开发者。

如何选择: node-schedule vs bull vs agenda
  • node-schedule:

    选择 Node-schedule 如果你需要一个简单的、基于时间的调度器,适合轻量级任务调度。它支持 Cron 表达式,易于使用,适合不需要复杂任务管理的场景。

  • bull:

    选择 Bull 如果你需要高性能的任务队列,特别是在处理大量并发任务时。Bull 提供了 Redis 支持,能够处理复杂的工作流和任务重试机制,非常适合需要高可用性和可靠性的应用。

  • agenda:

    选择 Agenda 如果你需要一个基于 MongoDB 的任务调度解决方案,适合需要持久化和复杂调度的应用。它支持重复任务和任务优先级,并且易于与现有的 MongoDB 数据库集成。

node-schedule的README

Node Schedule

NPM version Downloads Build Status Coverage Status Join the chat at https://gitter.im/node-schedule/node-schedule

NPM

Node Schedule is a flexible cron-like and not-cron-like job scheduler for Node.js. It allows you to schedule jobs (arbitrary functions) for execution at specific dates, with optional recurrence rules. It only uses a single timer at any given time (rather than reevaluating upcoming jobs every second/minute).

Node 6+ is supported.

Overview

Node Schedule is for time-based scheduling, not interval-based scheduling.

While you can easily bend it to your will, if you only want to do something like "run this function every 5 minutes", toad-scheduler would be a better choice. But if you want to, say, "run this function at the :20 and :50 of every hour on the third Tuesday of every month," you'll find that Node Schedule suits your needs better. Additionally, Node Schedule has Windows support, unlike true cron, since the node runtime is now fully supported.

Note that Node Schedule is designed for in-process scheduling, i.e. scheduled jobs will only fire as long as your script is running, and the schedule will disappear when execution completes. If you need to schedule jobs that will persist even when your script isn't running, consider using actual cron.

In case you need durable jobs that persist across restarts and lock system compatible with multi-node deployments, try agenda or bree.

Usage

Installation

You can install using npm.

npm install node-schedule

Jobs and Scheduling

Every scheduled job in Node Schedule is represented by a Job object. You can create jobs manually, then execute the schedule() method to apply a schedule, or use the convenience function scheduleJob() as demonstrated below.

Job objects are EventEmitters, and emit the following events:

  • A run event after each execution.
  • A scheduled event each time they're scheduled to run.
  • A canceled event when an invocation is canceled before it's executed.
    Note that canceled is the single-L American spelling.
  • An error event when a job invocation triggered by a schedule throws or returns a rejected Promise.
  • A success event when a job invocation triggered by a schedule returns successfully or returns a resolved Promise. In any case, the success event receives the value returned by the callback or in case of a promise, the resolved value.

(Both the scheduled and canceled events receive a JavaScript date object as a parameter).
Note that jobs are scheduled the first time immediately, so if you create a job using the scheduleJob() convenience method, you'll miss the first scheduled event, but you can query the invocation manually (see below).

Cron-style Scheduling

The cron format consists of:

*    *    *    *    *    *
┬    ┬    ┬    ┬    ┬    ┬
│    │    │    │    │    │
│    │    │    │    │    └ day of week (0 - 7) (0 or 7 is Sun)
│    │    │    │    └───── month (1 - 12)
│    │    │    └────────── day of month (1 - 31)
│    │    └─────────────── hour (0 - 23)
│    └──────────────────── minute (0 - 59)
└───────────────────────── second (0 - 59, OPTIONAL)

Examples with the cron format:

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

const job = schedule.scheduleJob('42 * * * *', function(){
  console.log('The answer to life, the universe, and everything!');
});

Execute a cron job when the minute is 42 (e.g. 19:42, 20:42, etc.).

And:

const job = schedule.scheduleJob('0 17 ? * 0,4-6', function(){
  console.log('Today is recognized by Rebecca Black!');
});

Execute a cron job every 5 Minutes = */5 * * * *

You can also get when it is scheduled to run for every invocation of the job:

const job = schedule.scheduleJob('0 1 * * *', function(fireDate){
  console.log('This job was supposed to run at ' + fireDate + ', but actually ran at ' + new Date());
});

This is useful when you need to check if there is a delay of the job invocation when the system is busy, or save a record of all invocations of a job for audit purpose.

Unsupported Cron Features

Currently, W (nearest weekday) and L (last day of month/week) are not supported. Most other features supported by popular cron implementations should work just fine, including # (nth weekday of the month).

cron-parser is used to parse crontab instructions.

Date-based Scheduling

Say you very specifically want a function to execute at 5:30am on December 21, 2012. Remember - in JavaScript - 0 - January, 11 - December.

const schedule = require('node-schedule');
const date = new Date(2012, 11, 21, 5, 30, 0);

const job = schedule.scheduleJob(date, function(){
  console.log('The world is going to end today.');
});

To use current data in the future you can use binding:

const schedule = require('node-schedule');
const date = new Date(2012, 11, 21, 5, 30, 0);
const x = 'Tada!';
const job = schedule.scheduleJob(date, function(y){
  console.log(y);
}.bind(null,x));
x = 'Changing Data';

This will log 'Tada!' when the scheduled Job runs, rather than 'Changing Data', which x changes to immediately after scheduling.

Recurrence Rule Scheduling

You can build recurrence rules to specify when a job should recur. For instance, consider this rule, which executes the function every hour at 42 minutes after the hour:

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

const rule = new schedule.RecurrenceRule();
rule.minute = 42;

const job = schedule.scheduleJob(rule, function(){
  console.log('The answer to life, the universe, and everything!');
});

You can also use arrays to specify a list of acceptable values, and the Range object to specify a range of start and end values, with an optional step parameter. For instance, this will print a message on Thursday, Friday, Saturday, and Sunday at 5pm:

const rule = new schedule.RecurrenceRule();
rule.dayOfWeek = [0, new schedule.Range(4, 6)];
rule.hour = 17;
rule.minute = 0;

const job = schedule.scheduleJob(rule, function(){
  console.log('Today is recognized by Rebecca Black!');
});

Timezones are also supported. Here is an example of executing at the start of every day in the UTC timezone.

const rule = new schedule.RecurrenceRule();
rule.hour = 0;
rule.minute = 0;
rule.tz = 'Etc/UTC';

const job = schedule.scheduleJob(rule, function(){
  console.log('A new day has begun in the UTC timezone!');
});

A list of acceptable tz (timezone) values can be found at https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

RecurrenceRule properties

  • second (0-59)
  • minute (0-59)
  • hour (0-23)
  • date (1-31)
  • month (0-11)
  • year
  • dayOfWeek (0-6) Starting with Sunday
  • tz

Note: It's worth noting that the default value of a component of a recurrence rule is null (except for second, which is 0 for familiarity with cron). If we did not explicitly set minute to 0 above, the message would have instead been logged at 5:00pm, 5:01pm, 5:02pm, ..., 5:59pm. Probably not what you want.

Object Literal Syntax

To make things a little easier, an object literal syntax is also supported, like in this example which will log a message every Sunday at 2:30pm:

const job = schedule.scheduleJob({hour: 14, minute: 30, dayOfWeek: 0}, function(){
  console.log('Time for tea!');
});

Set StartTime and EndTime

It will run after 5 seconds and stop after 10 seconds in this example. The ruledat supports the above.

const startTime = new Date(Date.now() + 5000);
const endTime = new Date(startTime.getTime() + 5000);
const job = schedule.scheduleJob({ start: startTime, end: endTime, rule: '*/1 * * * * *' }, function(){
  console.log('Time for tea!');
});

Graceful Shutdown.

You can shutdown jobs gracefully.
gracefulShutdown() will cancel all jobs and return Promise.
It will wait until all jobs are terminated.

schedule.gracefulShutdown();

You can also gracefully shutdown jobs when a system interrupt occurs.

process.on('SIGINT', function () { 
  schedule.gracefulShutdown()
  .then(() => process.exit(0))
}

Handle Jobs and Job Invocations

There are some function to get information for a Job and to handle the Job and Invocations.

job.cancel(reschedule)

You can invalidate any job with the cancel() method:

j.cancel();

All planned invocations will be canceled. When you set the parameter reschedule to true then the Job is newly scheduled afterwards.

job.cancelNext(reschedule)

This method invalidates the next planned invocation or the job. When you set the parameter reschedule to true then the Job is newly scheduled afterwards.

job.reschedule(spec)

This method cancels all pending invocation and registers the Job completely new again using the given specification. Return true/false on success/failure.

job.nextInvocation()

This method returns a Date object for the planned next Invocation for this Job. If no invocation is planned the method returns null.

Contributing

This module was originally developed by Matt Patenaude who eventually passed over maintainer's mantle over to Tejas Manohar.

Currently it is being maintained by Igor Savin and our amazing community.

We'd love to get your contributions. Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit.

Before jumping in, check out our Contributing page guide!

Copyright and license

Copyright 2015 Matt Patenaude.

Licensed under the MIT License.