go-zero中定时任务的用法

server/2025/2/27 8:52:16/

文章目录

  • 使用扩展
  • 定义调度器
  • 测试方法

使用扩展

在go-zero框架中使用定时任务调度的写法示例,首先需要用到的扩展:go get -u github.com/robfig/cron/v3

扩展网址:robfig/cron: a cron library for go (github.com)

定义调度器

gozero/internal 目录下新建 crontab目录,然后首先需要创建一个配置文件:gozero/internal/crontab/config.go ,在这里我写上两个示例的定时任务,分别为“20秒打印一次SayHello”,以及“每一分钟查询一次当前用户总数”:

package crontabtype TaskConfig struct {Name      string `json:"name"`      //任务名称Scheduler string `json:"scheduler"` //@every表达式中的单位可以是s(秒)、m(分钟)、h(小时)等Enabled   bool   // 是否启用
}func DefaultTask() []TaskConfig {return []TaskConfig{{Name:      "SayHello",Scheduler: "@every 20s", //每20秒钟执行一次Enabled:   true,},{Name:      "StatisticsUserCount",Scheduler: "@every 1m", //每1分钟执行一次Enabled:   true,},}
}

然后,定义定时任务调度器文件:gozero/internal/crontab/scheduler.go,这个文件中,先定义好调度器的结构体和注册方法以及启动方法。代码如下:

type Scheduler struct {cron   *cron.CronsvcCtx *svc.ServiceContext
}// NewScheduler creates a new scheduler instance.
func NewScheduler(svcCtx *svc.ServiceContext) *Scheduler {return &Scheduler{cron:   cron.New(),svcCtx: svcCtx,}
}// RegisterTask registers a task with the scheduler.
func (s *Scheduler) RegisterTask(name, schedule string, task func(ctx context.Context, svcCtx *svc.ServiceContext)) {_, err := s.cron.AddFunc(schedule, func() {task(context.Background(), s.svcCtx)})if err != nil {log.Fatalf("Failed to register task %s: %v", name, err)}log.Printf("Registered task %s with schedule %s", name, schedule)
}func (s *Scheduler) Start() {s.cron.Start()log.Println("Scheduler started")
}func (s *Scheduler) Stop() {s.cron.Stop()log.Println("Scheduler stopped")
}

上面的 Start() 和 Stop() 方法,分别实现了 vendor/github.com/robfig/cron/v3/cron.go 中的 Start() 和 Stop() 方法。

接下来,需要初始化定时任务调度器,对于config.go中配置好的定时任务,分别实现不同的业务逻辑。

// InitScheduler 初始化定时任务调度器
func InitScheduler(svcCtx *svc.ServiceContext) (*Scheduler, error) {log.Println("Initializing scheduler...")scheduler := NewScheduler(svcCtx)if scheduler == nil {return nil, fmt.Errorf("failed to create scheduler")}taskConfigs := DefaultTask()if taskConfigs == nil {return nil, fmt.Errorf("failed to load task configurations")}for _, taskConfig := range taskConfigs {if !taskConfig.Enabled {log.Printf("Task %s is disabled, skipping...", taskConfig.Name)continue}log.Printf("Registering task %s...", taskConfig.Name)switch taskConfig.Name {case "SayHello": //SayHelloscheduler.RegisterTask(taskConfig.Name, taskConfig.Scheduler, hello.SayHello)case "StatisticsUserCount": //统计用户总数scheduler.RegisterTask(taskConfig.Name, taskConfig.Scheduler, user.StatisticsUserCount)case "xxxx":// todo 注册其他定时任务default:log.Printf("Unknown task: %s", taskConfig.Name)}}return scheduler, nil
}

接下来, 在入口文件gozero/gozero.gomain方法中调用上面定义好的调度器:

func main() {//....// 定时任务调度scheduler, err := crontab.InitScheduler(ctx)if err != nil {fmt.Printf("Failed to initialize scheduler: %v", err)}scheduler.Start()fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)server.Start()
}

测试方法

接下来,在 gozero/internal/crontab/task 目录下,新建两个测试方法,测试一下上面配置的两个定时任务:

  • SayHello方法: gozero/internal/crontab/task/hello/say_hello.go
func SayHello(ctx context.Context, svcCtx *svc.ServiceContext) {fmt.Println("SayHello running at:", time.Now())return
}
  • 查询用户总数的方法:gozero/internal/crontab/task/user/statistics_user_count.go
package userfunc StatisticsUserCount(ctx context.Context, svcCtx *svc.ServiceContext) {fmt.Println("StatisticsUserCount running at:", time.Now())listLogic := admin.NewUserListLogic(ctx, svcCtx)count, err := listLogic.GetUserCount() //调用逻辑层查询数据库if err != nil {fmt.Println("StatisticsUserCount error:", err)return}if count == 0 {fmt.Println("StatisticsUserCount count is 0")return}fmt.Println("StatisticsUserCount count:", count)return
}

然后运行一下:

image-20250225113155576

这样就可以轻松的在go-zero中实现定时任务的调度了,可以精确到秒级别。

https://gitee.com/rxbook/go-demo-2025/tree/master/gozero


http://www.ppmy.cn/server/170990.html

相关文章

Java进阶:Docker

1. Docker概述 1.1. Docker简介 Docker 是一个开源的应用容器引擎,基于 Go 语言开发。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱…

深度学习R7周:糖尿病预测模型优化探索

🍨 本文为🔗365天深度学习训练营中的学习记录博客🍖 原作者:K同学啊 学习目标: 思考本案例是否还有进一步优化的空间 环境: 语言环境:Python3.8 编译器:pycharm 深度学习环境&a…

开源程序wordpress在海外品牌推广中的重要作用

WordPress作为全球最流行的开源内容管理系统(CMS),在全球网站搭建中占据超过40%的市场份额。其强大的功能、灵活性和易用性使其成为企业进行海外品牌推广的首选平台。以下是WordPress在海外品牌推广中的重要性分析: 1. 多语言支持与本地化 WordPress通…

京准电钟:NTP精密时钟服务器在自动化系统中的作用

京准电钟:NTP精密时钟服务器在自动化系统中的作用 京准电钟:NTP精密时钟服务器在自动化系统中的作用 NTP精密时钟服务器在自动化系统中的作用非常重要,特别是在需要高精度时间同步的场景中。NTP能够提供毫秒级的时间同步精度,这…

STM32编译过程

STM32编译过程 1. 编译过程介绍2. 程序的组成、存储与运行3. 编译工具链3.1 armcc 工具3.2 armasm 工具3.3 armlink 工具3.4 armar 工具3.5 fromelf 工具 4. MDK工程的文件类型 1. 编译过程介绍 编译MDK 软件使用的编译器是 armcc 和 armasm,它们根据每个 c/c 和汇编…

Qt 中实现链表

Qt 中实现链表&#xff0c;我将使用模板类来支持泛型数据&#xff0c;并通过封装确保数据安全。 完整实现代码 #include <QCoreApplication> #include <QDebug> #include <functional> // 用于遍历时的回调函数template<typename T> class LinkedLis…

二叉树中的深搜(典型算法思想)—— OJ例题算法解析思路

目录 一、2331. 计算布尔二叉树的值 - 力扣&#xff08;LeetCode&#xff09; 算法代码&#xff1a; 代码思路概述 详细代码逻辑解释 节点定义 求值函数 基线条件 递归步骤 逻辑操作 总结 二、129. 求根节点到叶节点数字之和 - 力扣&#xff08;LeetCode&#xff09…

2025中国经济白皮书赋能CES Asia,国际合作成新亮点

近日&#xff0c;2025年中国经济白皮书的发布&#xff0c;为第七届亚洲消费电子技术贸易展&#xff08;CES Asia 2025&#xff09;的招商工作带来了重大利好消息&#xff0c;其在国际合作方面展现出的显著优势&#xff0c;成为吸引全球企业参与的重要因素。 白皮书重申了中国坚…