golang轻量级零依赖定时任务调度插件库go-quartz的使用

golang轻量级零依赖定时任务调度插件库go-quartz的使用

go-quartz是一个极简且零依赖的Go调度库,其设计灵感来源于Java Quartz调度器。

核心组件

Scheduler接口

type Scheduler interface {
    // 启动调度器
    Start(context.Context)
    
    // 检查调度器是否已启动
    IsStarted() bool
    
    // 使用提供的Trigger调度一个Job
    ScheduleJob(jobDetail *JobDetail, trigger Trigger) error
    
    // 获取已调度Job的keys
    GetJobKeys(...Matcher[ScheduledJob]) ([]*JobKey, error)
    
    // 获取指定key的已调度Job
    GetScheduledJob(jobKey *JobKey) (ScheduledJob, error)
    
    // 删除指定key的Job
    DeleteJob(jobKey *JobKey) error
    
    // 暂停指定key的Job
    PauseJob(jobKey *JobKey) error
    
    // 恢复指定key的Job
    ResumeJob(jobKey *JobKey) error
    
    // 清除所有已调度的Job
    Clear() error
    
    // 等待调度器停止运行
    Wait(context.Context)
    
    // 停止调度器
    Stop()
}

Trigger接口

type Trigger interface {
    // 返回Trigger下次触发的时间
    NextFireTime(prev int64) (int64, error)
    
    // 返回Trigger的描述
    Description() string
}

已实现的Trigger类型:

  • CronTrigger
  • SimpleTrigger
  • RunOnceTrigger

Job接口

任何实现了该接口的类型都可以被调度:

type Job interface {
    // 当Trigger触发时由Scheduler调用
    Execute(context.Context) error
    
    // 返回Job的描述
    Description() string
}

Cron表达式格式

字段名 必填 允许值 允许的特殊字符
0-59 , - * /
分钟 0-59 , - * /
小时 0-23 , - * /
日期 1-31 , - * ? / L W
月份 1-12或JAN-DEC , - * /
星期 1-7或SUN-SAT , - * ? / L #
空, 1970- , - * /

使用示例

package main

import (
    "context"
    "log/slog"
    "net/http"
    "os"
    "time"

    "github.com/reugn/go-quartz/job"
    "github.com/reugn/go-quartz/logger"
    "github.com/reugn/go-quartz/quartz"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    // 使用logger配置选项创建调度器
    slogLogger := slog.New(slog.NewTextHandler(os.Stdout, nil))
    scheduler, _ := quartz.NewStdScheduler(quartz.WithLogger(logger.NewSlogLogger(ctx, slogLogger)))

    // 启动调度器
    scheduler.Start(ctx)

    // 创建jobs
    cronTrigger, _ := quartz.NewCronTrigger("1/5 * * * * *")  // 每5秒执行一次
    shellJob := job.NewShellJob("ls -la")  // 执行shell命令

    request, _ := http.NewRequest(http.MethodGet, "https://worldtimeapi.org/api/timezone/utc", nil)
    curlJob := job.NewCurlJob(request)  // 执行HTTP请求

    functionJob := job.NewFunctionJob(func(_ context.Context) (int, error) { return 1, nil })  // 执行函数

    // 向调度器注册jobs
    _ = scheduler.ScheduleJob(quartz.NewJobDetail(shellJob, quartz.NewJobKey("shellJob")),
        cronTrigger)
    _ = scheduler.ScheduleJob(quartz.NewJobDetail(curlJob, quartz.NewJobKey("curlJob")),
        quartz.NewSimpleTrigger(7*time.Second))  // 每7秒执行一次
    _ = scheduler.ScheduleJob(quartz.NewJobDetail(functionJob, quartz.NewJobKey("functionJob")),
        quartz.NewSimpleTrigger(5*time.Second))  // 每5秒执行一次

    // 停止调度器
    scheduler.Stop()

    // 等待所有worker退出
    scheduler.Wait(ctx)
}

分布式模式

调度器可以使用自己的quartz.JobQueue实现来共享状态。可以在示例目录中找到使用文件系统作为持久层的job queue实现示例。

许可证

go-quartz基于MIT许可证授权。


更多关于golang轻量级零依赖定时任务调度插件库go-quartz的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang轻量级零依赖定时任务调度插件库go-quartz的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Go-Quartz 轻量级定时任务调度库使用指南

概述

go-quartz 是一个轻量级的 Golang 定时任务调度库,它模仿了 Java 的 Quartz 调度器,但设计更加简洁,零外部依赖。这个库非常适合需要简单定时任务调度的 Go 应用程序。

核心特性

  • 零外部依赖
  • 简单易用的 API
  • 支持 cron 表达式
  • 支持一次性任务和周期性任务
  • 线程安全

安装

go get github.com/reugn/go-quartz

基本使用

1. 创建简单任务

package main

import (
	"fmt"
	"time"

	"github.com/reugn/go-quartz/quartz"
)

// 定义一个简单的任务
type SimpleJob struct{}

func (j *SimpleJob) Execute() {
	fmt.Println("Executing SimpleJob at", time.Now())
}

func (j *SimpleJob) Description() string {
	return "SimpleJob"
}

func main() {
	// 创建调度器
	sched := quartz.NewStdScheduler()
	
	// 启动调度器
	sched.Start()
	
	// 创建任务
	job := &SimpleJob{}
	
	// 创建触发器 - 每5秒执行一次
	trigger := quartz.NewSimpleTrigger(time.Second * 5)
	
	// 调度任务
	sched.ScheduleJob(job, trigger)
	
	// 等待一段时间查看任务执行
	time.Sleep(time.Minute)
	
	// 关闭调度器
	sched.Stop()
}

2. 使用 Cron 表达式

package main

import (
	"fmt"
	"time"

	"github.com/reugn/go-quartz/quartz"
)

type CronJob struct{}

func (j *CronJob) Execute() {
	fmt.Println("Executing CronJob at", time.Now())
}

func (j *CronJob) Description() string {
	return "CronJob"
}

func main() {
	sched := quartz.NewStdScheduler()
	sched.Start()
	
	job := &CronJob{}
	
	// 创建 Cron 触发器 - 每分钟的第30秒执行
	cronTrigger, err := quartz.NewCronTrigger("30 * * * * *")
	if err != nil {
		panic(err)
	}
	
	sched.ScheduleJob(job, cronTrigger)
	
	time.Sleep(5 * time.Minute)
	sched.Stop()
}

3. 一次性任务

package main

import (
	"fmt"
	"time"

	"github.com/reugn/go-quartz/quartz"
)

type OneTimeJob struct{}

func (j *OneTimeJob) Execute() {
	fmt.Println("Executing OneTimeJob at", time.Now())
}

func (j *OneTimeJob) Description() string {
	return "OneTimeJob"
}

func main() {
	sched := quartz.NewStdScheduler()
	sched.Start()
	
	job := &OneTimeJob{}
	
	// 创建一次性触发器 - 10秒后执行
	trigger := quartz.NewRunOnceTrigger(time.Second * 10)
	
	sched.ScheduleJob(job, trigger)
	
	time.Sleep(15 * time.Second)
	sched.Stop()
}

高级功能

1. 带参数的任务

package main

import (
	"fmt"
	"time"

	"github.com/reugn/go-quartz/quartz"
)

type ParamJob struct {
	Message string
}

func (j *ParamJob) Execute() {
	fmt.Printf("Executing ParamJob with message: %s at %v\n", j.Message, time.Now())
}

func (j *ParamJob) Description() string {
	return fmt.Sprintf("ParamJob with message: %s", j.Message)
}

func main() {
	sched := quartz.NewStdScheduler()
	sched.Start()
	
	job := &ParamJob{Message: "Hello, Quartz!"}
	trigger := quartz.NewSimpleTrigger(time.Second * 3)
	
	sched.ScheduleJob(job, trigger)
	
	time.Sleep(10 * time.Second)
	sched.Stop()
}

2. 任务错误处理

package main

import (
	"errors"
	"fmt"
	"time"

	"github.com/reugn/go-quartz/quartz"
)

type ErrorJob struct{}

func (j *ErrorJob) Execute() {
	fmt.Println("Executing ErrorJob at", time.Now())
	// 模拟任务执行失败
	panic(errors.New("something went wrong"))
}

func (j *ErrorJob) Description() string {
	return "ErrorJob"
}

func main() {
	sched := quartz.NewStdScheduler()
	
	// 设置错误处理函数
	sched.SetJobErrorHandler(func(job quartz.Job, err error) {
		fmt.Printf("Job %s failed with error: %v\n", job.Description(), err)
	})
	
	sched.Start()
	
	job := &ErrorJob{}
	trigger := quartz.NewSimpleTrigger(time.Second * 2)
	
	sched.ScheduleJob(job, trigger)
	
	time.Sleep(10 * time.Second)
	sched.Stop()
}

3. 任务取消

package main

import (
	"fmt"
	"time"

	"github.com/reugn/go-quartz/quartz"
)

type CancellableJob struct{}

func (j *CancellableJob) Execute() {
	fmt.Println("Executing CancellableJob at", time.Now())
}

func (j *CancellableJob) Description() string {
	return "CancellableJob"
}

func main() {
	sched := quartz.NewStdScheduler()
	sched.Start()
	
	job := &CancellableJob{}
	trigger := quartz.NewSimpleTrigger(time.Second * 1)
	
	// 调度任务并获取任务Key
	jobKey := sched.ScheduleJob(job, trigger)
	
	// 5秒后取消任务
	time.AfterFunc(5*time.Second, func() {
		fmt.Println("Cancelling job...")
		sched.DeleteJob(jobKey)
	})
	
	time.Sleep(10 * time.Second)
	sched.Stop()
}

总结

go-quartz 提供了简单而强大的定时任务调度功能,适合大多数需要定时执行任务的 Go 应用场景。它的主要优点包括:

  1. 零依赖,轻量级
  2. 简单易用的 API
  3. 支持多种触发器类型
  4. 线程安全

对于更复杂的调度需求,可能需要考虑更全面的解决方案,但对于大多数简单到中等复杂度的定时任务需求,go-quartz 是一个非常好的选择。

回到顶部