You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用gocelery模块通过设置ETA调度一次性非周期性任务?

使用gocelery设置10秒ETA的单次任务调度

没问题,我来一步步教你实现这个需求——用gocelery调度一个10秒后执行、仅运行一次的任务,完全不需要周期性配置。

第一步:准备依赖

首先确保你已经安装了gocelery和对应的broker驱动(这里以最常用的Redis为例):

go get github.com/gocelery/gocelery/v2
go get github.com/go-redis/redis/v8

第二步:编写任务生产者(发送任务的代码)

这部分负责把任务发送到broker,并指定10秒后的执行时间(ETA)。核心是用WithETA选项来设置任务的执行时机:

package main

import (
	"context"
	"time"

	"github.com/gocelery/gocelery/v2"
	"github.com/go-redis/redis/v8"
)

func main() {
	// 初始化Redis客户端(作为任务存储的broker)
	redisClient := redis.NewClient(&redis.Options{
		Addr: "localhost:6379", // 替换成你的Redis地址
	})

	// 创建gocelery客户端
	celeryClient, _ := gocelery.NewCeleryClient(
		gocelery.NewRedisBroker(redisClient),
		&gocelery.RedisBackend{Client: redisClient},
		1, // 并发数,这里保持默认即可
	)

	// 计算10秒后的时间作为ETA(建议用UTC时间避免时区偏差)
	etaTime := time.Now().UTC().Add(10 * time.Second)

	// 发送任务,指定ETA——这是单次任务,没有任何周期性配置
	task, err := celeryClient.ApplyAsync(
		context.Background(),
		"my_delayed_task", // 任务名称,要和消费者端保持一致
		[]interface{}{"hello from delayed task"}, // 任务参数
		gocelery.WithETA(etaTime), // 关键:设置任务的执行时间点
	)
	if err != nil {
		panic(err)
	}

	// 打印任务ID方便跟踪
	println("任务已发送,ID:", task.ID)
}

第三步:编写任务消费者(执行任务的worker)

这部分负责注册任务并启动worker,等待ETA时间到了就执行任务:

package main

import (
	"context"
	"fmt"
	"time"

	"github.com/gocelery/gocelery/v2"
	"github.com/go-redis/redis/v8"
)

// 定义要执行的任务函数
func myDelayedTask(ctx context.Context, args ...interface{}) (interface{}, error) {
	message := args[0].(string)
	fmt.Printf("任务执行时间:%s,收到消息:%s\n", time.Now().UTC().Format(time.RFC3339), message)
	return "任务执行完成", nil
}

func main() {
	// 初始化Redis客户端
	redisClient := redis.NewClient(&redis.Options{
		Addr: "localhost:6379",
	})

	// 创建gocelery worker
	celeryWorker, _ := gocelery.NewCeleryWorker(
		gocelery.NewRedisBroker(redisClient),
		&gocelery.RedisBackend{Client: redisClient},
		1, // 并发数
	)

	// 注册任务:名称必须和生产者端的一致
	celeryWorker.Register("my_delayed_task", myDelayedTask)

	// 启动worker,开始监听任务
	println("Worker已启动,等待任务执行...")
	celeryWorker.Start()

	// 让worker持续运行(实际项目中可以用信号处理实现优雅退出)
	select {}
}

关键注意事项

  • 时区问题:gocelery的ETA参数优先使用UTC时间,如果你用本地时区,可能会因为worker/broker的时区差异导致任务执行时间偏差。
  • 单次任务确认:这里没有设置任何周期性调度参数(比如WithSchedule或crontab规则),所以任务只会在指定的ETA时间执行一次,不会重复运行。
  • Broker可用性:确保你的Redis服务已经启动并正常运行,否则任务无法被存储和传递。

运行步骤

  1. 启动Redis服务:redis-server
  2. 启动worker:go run worker.go
  3. 运行生产者发送任务:go run producer.go

之后你会看到worker在10秒后输出任务执行日志,完美实现单次延迟执行的需求!

内容的提问来源于stack exchange,提问作者Vani Polnedi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 08:57:27