Rust任务调度器:开发者完整指南
任务调度器是现代开发中不可或缺的一部分。它们可以自动化执行日常操作:定期清理缓存、发送通知、同步数据等等。在Rust生态系统中,有多个强大的库可用于实现调度器。在本文中,我们将分析三种主要方法:cron、tokio-cron-scheduler和job_scheduler。
1. 使用cron库的基础调度器
cron库提供了最简化的功能,用于解析cron表达式并计算下一次执行的时间。它不包含内置的执行循环,因此通常与tokio或std::thread结合使用。
安装:
[dependencies]cron = "0.12"chrono = "0.4"tokio = { version = "1", features = ["full"] }简单调度器示例:
use cron::Schedule;use chrono::Utc;use std::str::FromStr;use std::thread;use std::time::Duration;
fn main() { // 每分钟 let expression = "0 * * * * *"; let schedule = Schedule::from_str(expression).unwrap();
loop { let now = Utc::now(); if let Some(next) = schedule.upcoming(Utc).next() { let duration = next - now; if duration.num_seconds() > 0 { thread::sleep(Duration::from_secs(duration.num_seconds() as u64)); } println!("[{}] 任务已执行!", Utc::now()); } }}这种方法提供了完全控制,但需要手动管理循环。适用于简单场景。
2. 异步调度器 tokio-cron-scheduler
对于基于tokio的现代异步应用程序,tokio-cron-scheduler库是理想选择。它提供了一个现成的调度器,支持复杂的cron计划、带标识符的任务以及错误处理程序。
安装:
[dependencies]tokio-cron-scheduler = "0.10"tokio = { version = "1", features = ["full"] }包含两个任务的示例:
use tokio_cron_scheduler::{Job, JobScheduler};use std::sync::Arc;
#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> { let sched = JobScheduler::new().await?;
// 任务1:每5秒 let job1 = Job::new_async("*/5 * * * * *", |_uuid, _lock| { Box::pin(async move { println!("[Job1] 执行于 {:?}", std::time::SystemTime::now()); }) })?;
// 任务2:每分钟 let job2 = Job::new_async("0 * * * * *", |_uuid, _lock| { Box::pin(async move { println!("[Job2] 每分钟任务"); }) })?;
sched.add(job1).await?; sched.add(job2).await?; sched.start().await?;
// 保持应用程序运行 tokio::signal::ctrl_c().await?; println!("调度器已停止"); Ok(())}优点:自动时间管理,支持删除/暂停任务,无阻塞的异步执行。
3. 简单调度器 job_scheduler
job_scheduler库专注于最大程度的简单性。它不需要异步运行时,适用于控制台工具或嵌入到现有的同步项目中。
安装:
[dependencies]job_scheduler = "1.2"chrono = "0.4"示例:
use job_scheduler::{Job, JobScheduler};use std::time::Duration;
fn main() { let mut sched = JobScheduler::new();
sched.add(Job::new("1/10 * * * * *".parse().unwrap(), || { println!("每10秒执行任务");