go-zero中定时任务的用法

news/2025/2/27 18:44:13/

文章目录

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

使用扩展

在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/news/1575303.html

相关文章

自由学习记录(39)

threshold(blend tree) Threshold 用来指定动画的完全权重时刻(完全切换点) 参数达到 Threshold 值之后,并不会立即“隔断”当前的动画,而是 平滑过渡到下一个动画 例如: Jump 动画的 Thresh…

视频字幕识别和翻译

下载的视频很多不是汉语的,我们需要用剪映将语音识别出来作为字幕压制到视频中去。 剪映6.0以后语音识别需要收费,但是低版本还是没有问题。 如果想要非汉语字幕转成中文,剪映低版本不提供这样功能。但是,用剪映导出识别字幕&am…

一周学会Flask3 Python Web开发-Jinja2模板继承和include标签使用

锋哥原创的Flask3 Python Web开发 Flask3视频教程: 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 不管是开发网站还是后台管理系统,我们页面里多多少少有公共的模块。比如博客网站,就有公共的头部&…

无框架简易Java服务器后端

不使用像 Spring Boot 这样的框架,使用 Java 内置的HttpServer(从 Java 1.7 开始引入)来创建一个简单的 Web 后端,处理xxxx/test/query接口,接收 JSON 请求体并返回字符串响应。 示例代码: import com.go…

Amazon Outposts:构建混合云的安全堡垒,让数据安全“零距离”

在数字化转型的浪潮中,企业纷纷拥抱混合云架构以兼顾敏捷性与本地化需求。然而,如何确保数据在本地与云端的无缝流转中始终安全可控,成为企业面临的核心挑战。Amazon Outposts 作为AWS推出的混合云解决方案,不仅将原生AWS服务延伸…

【mysql中mvcc的含义和作用及原理】

MySQL中的MVCC(多版本并发控制)是一种用于提高数据库并发性能的机制,通过维护数据的多个版本,实现读写操作的无锁并发。以下是其核心要点: 1. MVCC的含义 全称:Multi-Version Concurrency Control&#xf…

几种AI模型在算法工作中的使用测评——Grok3,Deepseek,Chatgpt,Kimi,Claude(持续更新)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、Grok3二、Deepseek-R1三、Chatgpt-4o四、Kimi五、Claude-3.5总结 前言 在工作中现在已经离不开这AI模型了。 于是我单开一个博客,记录在使用过…

跟着李沐老师学习深度学习(十四)

注意力机制(Attention) 引入 心理学角度 动物需要在复杂环境下有效关注值得注意的点心理学框架:人类根据随意线索和不随意线索选择注意力 注意力机制 之前所涉及到的卷积、全连接、池化层都只考虑不随意线索而注意力机制则显示的考虑随意…