golang智能定时任务调度与实时监控插件库JobRunner的使用
Golang智能定时任务调度与实时监控插件库JobRunner的使用
JobRunner是一个用于在请求流程之外异步执行工作的框架。它内置了cron功能,可以调度和排队作业函数在指定时间处理。
主要特性
- 实时监控当前调度和活动作业的状态,可以输出为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界面查看作业状态:
集成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)
}
注意事项
- JobRunner 适合轻量级任务调度,对于高精度或分布式任务场景可能需要更专业的解决方案
- 任务执行时间过长会阻塞工作协程,建议将耗时操作放在单独的 goroutine 中
- 程序退出时所有任务都会停止,需要持久化的任务需要额外处理
- cron 表达式使用标准格式(秒 分 时 日 月 周)
JobRunner 提供了简单易用的 API,适合大多数基本的定时任务需求,通过合理的任务设计可以构建出功能完善的定时任务系统。