golang智能定时任务调度与实时监控插件库JobRunner的使用

Golang智能定时任务调度与实时监控插件库JobRunner的使用

JobRunner是一个用于在请求流程之外异步执行工作的框架。它内置了cron功能,可以调度和排队作业函数在指定时间处理。

JobRunner运行时钟

主要特性

  • 实时监控当前调度和活动作业的状态,可以输出为JSON或Html模板
  • 所有作业都在请求流程之外处理
  • 支持立即执行、延迟执行和周期性执行任务

安装

go get github.com/bamzi/jobrunner

基本使用示例

package main

import "github.com/bamzi/jobrunner"

func main() {
    jobrunner.Start() // 可选参数: jobrunner.Start(pool int, concurrent int) (默认10, 1)
    jobrunner.Schedule("@every 5s", ReminderEmails{})
}

// 定义作业结构体
type ReminderEmails struct {
    // 可以添加需要的字段
}

// ReminderEmails.Run() 会自动触发执行
func (e ReminderEmails) Run() {
    // 这里可以执行数据库查询
    // 发送邮件等操作
    fmt.Printf("每5秒发送提醒邮件\n")
}

作业调度方式

JobRunner支持多种调度方式:

jobrunner.Schedule("* */5 * * * *", DoSomething{}) // 每5分钟执行一次
jobrunner.Schedule("@every 1h30m10s", ReminderEmails{})
jobrunner.Schedule("@midnight", DataStats{}) // 每天午夜执行
jobrunner.Every(16*time.Minute, CleanS3{}) // 每16分钟执行
jobrunner.In(10*time.Second, WelcomeEmail{}) // 10秒后执行一次
jobrunner.Now(NowDo{}) // 立即执行

实时监控

JobRunner提供了实时监控功能,可以通过Web界面查看作业状态:

JobRunner监控界面

集成Gin框架示例

// Gin框架集成示例
func main() {
    routes := gin.Default()

    // 返回JSON格式的作业状态
    routes.GET("/jobrunner/json", JobJson)

    // 加载模板文件
    routes.LoadHTMLGlob("../github.com/bamzi/jobrunner/views/Status.html")

    // 返回HTML格式的作业状态页面
    routes.GET("/jobrunner/html", JobHtml)

    routes.Run(":8080")
}

func JobJson(c *gin.Context) {
    // 返回可以序列化为JSON的状态数据
    c.JSON(200, jobrunner.StatusJson())
}

func JobHtml(c *gin.Context) {
    // 返回预解析的模板数据
    c.HTML(200, "", jobrunner.StatusPage())
}

使用场景

JobRunner适用于以下场景:

  • 新用户注册后发送欢迎邮件
  • 根据特定条件发送推送通知或邮件
  • 营销引擎 - 发送邀请、提醒邮件等
  • 清理数据库、数据或S3存储
  • 发送服务器统计信息到监控应用
  • 按日/周间隔发送数据统计

兼容性

JobRunner设计为框架无关,可以与纯Go应用以及任何Go语言框架一起使用。已验证支持的框架包括:

  • Gin
  • Echo
  • Martini
  • Beego
  • Revel

为什么选择JobRunner

  • 减少HTTP响应延迟200%以上
  • 无需创建独立应用即可处理后台任务
  • 当应用规模扩大时,可以轻松将JobRunner解耦为独立应用
  • 避免Go协程因HTTP响应已完成而超时的问题

贡献

欢迎通过以下方式贡献:

  • 报告问题
  • 提交新功能建议
  • 改进/修复文档
  • 提交Pull Request

许可证

MIT License


更多关于golang智能定时任务调度与实时监控插件库JobRunner的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang智能定时任务调度与实时监控插件库JobRunner的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang JobRunner 使用指南

JobRunner 是一个轻量级的 Go 语言定时任务调度库,支持 cron 表达式和简单的间隔调度,同时提供任务执行监控功能。

安装

go get github.com/bamzi/jobrunner

基本使用

1. 初始化与启动

package main

import (
	"fmt"
	"time"
	
	"github.com/bamzi/jobrunner"
)

func main() {
	// 初始化 JobRunner
	jobrunner.Start() // 默认使用 10 个工作协程
	
	// 添加任务
	jobrunner.Schedule("@every 5s", ReminderEmails{})
	
	// 保持程序运行
	select {}
}

// 定义一个任务结构体
type ReminderEmails struct{}

// 实现 Runner 接口的 Run 方法
func (e ReminderEmails) Run() {
	fmt.Printf("发送提醒邮件... 当前时间: %v\n", time.Now())
}

2. 多种调度方式

// 立即执行一次
jobrunner.Now(ReminderEmails{})

// 5秒后执行一次
jobrunner.In(5*time.Second, ReminderEmails{})

// 每隔5秒执行一次
jobrunner.Every(5*time.Second, ReminderEmails{})

// 使用cron表达式
jobrunner.Schedule("0 30 * * * *", ReminderEmails{}) // 每小时的第30分钟执行

高级功能

1. 任务监控

func printJobStats() {
	fmt.Println("当前运行中的任务:", jobrunner.StatusJson())
	
	// 获取所有任务信息
	entries := jobrunner.Entries()
	for _, entry := range entries {
		fmt.Printf("任务ID: %s, 下次执行时间: %v\n", 
			entry.ID, entry.Next)
	}
}

2. 带参数的任务

type EmailJob struct {
	To      string
	Subject string
}

func (e EmailJob) Run() {
	fmt.Printf("发送邮件给 %s, 主题: %s\n", e.To, e.Subject)
}

// 使用
jobrunner.Every(10*time.Second, EmailJob{
	To:      "user@example.com",
	Subject: "测试邮件",
})

3. 动态添加/删除任务

// 添加任务并保留引用
jobRef := jobrunner.Every(1*time.Minute, ReminderEmails{})

// 删除任务
jobrunner.Remove(jobRef)

4. 错误处理

type SafeJob struct{}

func (j SafeJob) Run() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("任务执行出错:", r)
		}
	}()
	
	// 任务逻辑
	// ...
}

完整示例

package main

import (
	"fmt"
	"time"
	
	"github.com/bamzi/jobrunner"
)

func main() {
	// 初始化并设置工作协程数量
	jobrunner.Start(20) // 使用20个工作协程
	
	// 添加不同类型的任务
	jobrunner.Now(OneTimeJob{})
	jobrunner.Every(10*time.Second, RegularJob{})
	jobrunner.Schedule("@hourly", HourlyJob{})
	jobrunner.In(1*time.Minute, DelayedJob{})
	
	// 带参数的任务
	jobrunner.Every(15*time.Second, ParamJob{
		Name: "监控任务",
		Count: 0,
	})
	
	// 监控任务状态
	go func() {
		for {
			time.Sleep(30 * time.Second)
			fmt.Println("\n===== 任务状态 =====")
			fmt.Println(jobrunner.StatusJson())
			fmt.Println("==================")
		}
	}()
	
	// 保持程序运行
	select {}
}

// 定义各种任务类型
type OneTimeJob struct{}
func (j OneTimeJob) Run() { fmt.Println("一次性任务执行") }

type RegularJob struct{}
func (j RegularJob) Run() { fmt.Println("常规任务执行:", time.Now()) }

type HourlyJob struct{}
func (j HourlyJob) Run() { fmt.Println("每小时任务执行") }

type DelayedJob struct{}
func (j DelayedJob) Run() { fmt.Println("延迟任务执行") }

type ParamJob struct {
	Name  string
	Count int
}
func (j *ParamJob) Run() {
	j.Count++
	fmt.Printf("参数任务[%s]执行第%d次\n", j.Name, j.Count)
}

注意事项

  1. JobRunner 适合轻量级任务调度,对于高精度或分布式任务场景可能需要更专业的解决方案
  2. 任务执行时间过长会阻塞工作协程,建议将耗时操作放在单独的 goroutine 中
  3. 程序退出时所有任务都会停止,需要持久化的任务需要额外处理
  4. cron 表达式使用标准格式(秒 分 时 日 月 周)

JobRunner 提供了简单易用的 API,适合大多数基本的定时任务需求,通过合理的任务设计可以构建出功能完善的定时任务系统。

回到顶部