Go 语言 实现简单的分布式定时任务示例

Go阿木 发布于 2025-06-22 7 次阅读


Go 语言实现简单的分布式定时任务示例

在分布式系统中,定时任务是一个常见的需求,比如定时备份数据、发送邮件通知、执行清理任务等。Go 语言因其高效的并发处理能力和简洁的语法,非常适合用于实现分布式定时任务。本文将围绕Go语言,展示如何实现一个简单的分布式定时任务系统。

系统设计

我们的分布式定时任务系统将包含以下几个组件:

1. 任务调度器:负责接收任务并安排执行时间。

2. 任务执行器:负责执行具体的任务。

3. 任务存储:用于存储任务信息,如任务ID、执行时间、任务内容等。

4. 分布式锁:确保同一时间只有一个任务执行器在执行同一任务。

技术选型

- Go 语言:作为主要编程语言。

- Goroutine:用于并发处理。

- Channel:用于goroutine之间的通信。

- Redis:作为任务存储和分布式锁的实现。

- GOMAXPROCS:限制goroutine的数量,避免过多的goroutine消耗系统资源。

实现步骤

1. 任务调度器

任务调度器负责接收任务并安排执行时间。我们可以使用Go语言的`time`包来处理时间相关的操作。

go

package main

import (


"time"


)

type Task struct {


ID string


Content string


NextRun time.Time


Interval time.Duration


}

func NewTask(id, content string, interval time.Duration) Task {


return &Task{


ID: id,


Content: content,


NextRun: time.Now().Add(interval),


Interval: interval,


}


}

func (t Task) Run() {


// 执行任务逻辑


fmt.Println("Executing task:", t.Content)


t.NextRun = time.Now().Add(t.Interval)


}


2. 任务执行器

任务执行器负责执行具体的任务。我们可以使用goroutine来并发执行任务。

go

func ExecuteTask(task Task) {


for {


if time.Now().After(task.NextRun) {


task.Run()


break


}


time.Sleep(100 time.Millisecond)


}


}


3. 任务存储

使用Redis作为任务存储,存储任务信息。

go

package main

import (


"context"


"fmt"


"time"

"github.com/go-redis/redis/v8"


)

var ctx = context.Background()


var rdb = redis.NewClient(&redis.Options{


Addr: "localhost:6379",


Password: "", // no password set


DB: 0, // use default DB


})

func SaveTask(task Task) error {


return rdb.Set(ctx, task.ID, task, task.Interval).Err()


}

func GetTask(id string) (Task, error) {


var task Task


err := rdb.Get(ctx, id).Scan(&task)


return &task, err


}


4. 分布式锁

使用Redis的SETNX命令实现分布式锁。

go

func LockTask(id string) bool {


return rdb.SetNX(ctx, id, "locked", 10time.Second).Val()


}

func UnlockTask(id string) bool {


return rdb.Del(ctx, id).Val() == 1


}


整合

将以上组件整合到一起,实现一个简单的分布式定时任务系统。

go

func main() {


// 创建任务


task := NewTask("task1", "Hello, World!", 5 time.Second)

// 保存任务到Redis


err := SaveTask(task)


if err != nil {


fmt.Println("Error saving task:", err)


return


}

// 启动任务执行器


go ExecuteTask(task)

// 模拟主程序运行


for {


time.Sleep(1 time.Second)


}


}


总结

本文使用Go语言实现了简单的分布式定时任务系统。通过任务调度器、任务执行器、任务存储和分布式锁等组件,实现了任务的定时执行和分布式环境下的任务隔离。在实际应用中,可以根据需求扩展功能,如任务优先级、任务超时处理等。

后续扩展

- 任务优先级:根据任务的重要性和紧急程度,设置不同的优先级,优先执行高优先级任务。

- 任务超时处理:设置任务执行超时时间,超过超时时间则重新调度任务。

- 任务监控:监控任务执行情况,如执行时间、执行结果等。

- 任务通知:任务执行完成后,发送通知到相关人员。

通过不断扩展和优化,可以构建一个功能完善的分布式定时任务系统。