golang基于时间任务调度的轻量级定时任务插件库gron的使用

Golang基于时间任务调度的轻量级定时任务插件库gron的使用

概述

Gron是一个提供清晰语法来编写和部署cron任务的Go库。它具有以下特点:

  • 简洁的API用于调度任务
  • 线程安全
  • 可自定义的任务类型
  • 可自定义的调度计划

安装

$ go get github.com/roylee0704/gron

基本用法

package main

import (
	"fmt"
	"time"
	"github.com/roylee0704/gron"
)

func main() {
	c := gron.New()
	c.AddFunc(gron.Every(1*time.Hour), func() {
		fmt.Println("runs every hour.")
	})
	c.Start()
}

调度参数

所有调度都使用机器的本地时区(由Go的time包提供)。

使用gron.Every()设置基本周期性调度:

gron.Every(1*time.Second)
gron.Every(1*time.Minute)
gron.Every(1*time.Hour)

通过导入gron/xtime还支持DayWeek

import "github.com/roylee0704/gron/xtime"

gron.Every(1 * xtime.Day)
gron.Every(1 * xtime.Week)

使用.At(hh:mm)在特定时间运行:

gron.Every(30 * xtime.Day).At("00:00")
gron.Every(1 * xtime.Week).At("23:59")

自定义任务类型

你可以通过实现gron.Job接口(Run()方法)来定义自定义任务类型。

例如:

type Reminder struct {
	Msg string
}

func (r Reminder) Run() {
  fmt.Println(r.Msg)
}

定义任务后,实例化它并在Gron中调度运行:

c := gron.New()
r := Reminder{ "Feed the baby!" }
c.Add(gron.Every(8*time.Hour), r)
c.Start()

自定义任务函数

你可以注册Funcs在给定计划上执行。Gron将在自己的goroutines中异步运行它们。

c := gron.New()
c.AddFunc(gron.Every(1*time.Second), func() {
	fmt.Println("runs every second")
})
c.Start()

自定义调度

Schedule是包装基本Next方法的接口:Next(p time.Duration) time.Time

gron中,接口值Schedule有以下具体类型:

  • periodicSchedule:将时间实例t添加到基础周期p
  • atSchedule:在每个周期p重新出现,在时间组件(hh:mm)

完整示例

package main

import (
	"fmt"
	"github.com/roylee0704/gron"
	"github.com/roylee0704/gron/xtime"
)

type PrintJob struct{ Msg string }

func (p PrintJob) Run() {
	fmt.Println(p.Msg)
}

func main() {

	var (
		// 调度计划
		daily     = gron.Every(1 * xtime.Day)
		weekly    = gron.Every(1 * xtime.Week)
		monthly   = gron.Every(30 * xtime.Day)
		yearly    = gron.Every(365 * xtime.Day)

		// 自定义任务
		purgeTask = func() { fmt.Println("purge aged records") }
		printFoo  = PrintJob{"Foo"}
		printBar  = PrintJob{"Bar"}
	)

	c := gron.New()

	c.Add(daily.At("12:30"), printFoo)
	c.AddFunc(weekly, func() { fmt.Println("Every week") })
	c.Start()

	// 任务也可以添加到正在运行的Gron中
	c.Add(monthly, printBar)
	c.AddFunc(yearly, purgeTask)

	// 停止Gron(正在运行的任务不会停止)
	c.Stop()
}

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

1 回复

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


Golang 定时任务库 gron 使用指南

gron 是一个轻量级的 Golang 定时任务调度库,它提供了简单易用的 API 来安排定期执行的任务。下面我将详细介绍 gron 的使用方法。

安装 gron

go get github.com/roylee0704/gron

基本使用

1. 创建调度器并添加任务

package main

import (
	"fmt"
	"time"
	
	"github.com/roylee0704/gron"
)

func main() {
	// 创建调度器
	c := gron.New()
	
	// 添加每日执行的任务
	c.AddFunc(gron.Every(1*time.Hour), func() {
		fmt.Println("每小时执行一次的任务", time.Now())
	})
	
	// 添加每周特定时间执行的任务
	c.AddFunc(gron.Every(1*time.Monday).At("09:30"), func() {
		fmt.Println("每周一早上9:30执行的任务", time.Now())
	})
	
	// 启动调度器
	c.Start()
	
	// 防止主程序退出
	select {}
}

2. 更复杂的调度示例

package main

import (
	"fmt"
	"time"
	
	"github.com/roylee0704/gron"
)

func main() {
	c := gron.New()
	
	// 每30秒执行一次
	c.AddFunc(gron.Every(30*time.Second), func() {
		fmt.Println("每30秒执行:", time.Now().Format("2006-01-02 15:04:05"))
	})
	
	// 每天上午10:15执行
	c.AddFunc(gron.Every(1*time.Day).At("10:15"), func() {
		fmt.Println("每天10:15执行:", time.Now().Format("2006-01-02 15:04:05"))
	})
	
	// 每周二和周五下午3点执行
	c.AddFunc(gron.Every(1*time.Tuesday|1*time.Friday).At("15:00"), func() {
		fmt.Println("每周二和周五15:00执行:", time.Now().Format("2006-01-02 15:04:05"))
	})
	
	c.Start()
	
	// 10分钟后停止所有任务
	time.AfterFunc(10*time.Minute, func() {
		c.Stop()
		fmt.Println("调度器已停止")
	})
	
	select {}
}

高级功能

1. 带参数的任务

package main

import (
	"fmt"
	"time"
	
	"github.com/roylee0704/gron"
)

func taskWithParams(name string, count int) {
	fmt.Printf("任务 %s 执行第 %d 次\n", name, count)
}

func main() {
	c := gron.New()
	
	count := 0
	c.AddFunc(gron.Every(5*time.Second), func() {
		count++
		taskWithParams("定时任务", count)
	})
	
	c.Start()
	
	time.Sleep(1 * time.Minute)
	c.Stop()
}

2. 动态添加和移除任务

package main

import (
	"fmt"
	"time"
	
	"github.com/roylee0704/gron"
)

func main() {
	c := gron.New()
	
	// 添加任务并保存ID
	taskID := c.AddFunc(gron.Every(10*time.Second), func() {
		fmt.Println("动态任务执行:", time.Now())
	})
	
	c.Start()
	
	// 10秒后移除任务
	time.Sleep(10 * time.Second)
	c.Remove(taskID)
	fmt.Println("任务已移除")
	
	time.Sleep(30 * time.Second)
	c.Stop()
}

实际应用示例

数据库备份任务

package main

import (
	"fmt"
	"os/exec"
	"time"
	
	"github.com/roylee0704/gron"
)

func backupDatabase() {
	cmd := exec.Command("mysqldump", "-u", "root", "-psecret", "mydb", ">", "backup.sql")
	err := cmd.Run()
	if err != nil {
		fmt.Println("数据库备份失败:", err)
	} else {
		fmt.Println("数据库备份成功:", time.Now())
	}
}

func main() {
	c := gron.New()
	
	// 每天凌晨2点执行备份
	c.AddFunc(gron.Every(1*time.Day).At("02:00"), backupDatabase)
	
	// 测试时可以用更短的间隔
	// c.AddFunc(gron.Every(1*time.Minute), backupDatabase)
	
	c.Start()
	
	select {}
}

注意事项

  1. 时区处理:gron 默认使用本地时区,如果需要指定时区,可以在时间字符串中包含时区信息,如 “15:04 MST”。

  2. 任务执行时间:如果任务执行时间超过调度间隔,下一次执行会被推迟到当前任务完成之后。

  3. 错误处理:任务函数中的 panic 会被捕获并打印错误信息,但不会中断调度器的运行。

  4. 性能考虑:对于大量高频任务,建议评估性能影响,必要时可以考虑分布式任务调度方案。

gron 是一个简单易用的轻量级定时任务库,适合大多数常见的定时任务场景。对于更复杂的企业级需求,可以考虑使用更强大的调度系统如 Celery 或分布式任务队列。

回到顶部