hibiken/asynq 基于 Redis 的轻量级异步任务队列

概述

Asynq是一个基于Go语言的异步任务处理解决方案,它提供了轻量级的、易于使用的API,并且具有高可扩展性和高可定制化性。Asynq主要由以下几个组件组成:

  • 任务(Task):需要被异步执行的操作。
  • 处理器(Processor):负责执行任务的工作进程。
  • 队列(Queue):存放待执行任务的队列。
  • 调度器(Scheduler):根据一定的规则将任务分配给不同的处理器进行执行。
  • 通过使用Asynq,我们可以非常轻松地实现异步任务处理,同时还可以提供高效率、高可扩展性和高自定义性的处理方案。

安装

  • 注意:redis的版本需要大于5.0

安装asynq

go get -u github.com/hibiken/asynq

基础使用

  • 生产者
r := asynq.RedisClientOpt{
		Addr:     "", // redis连接地址
		Password: "", // redis连接密码
		DB:       "",  // redis使用的库
        DialTimeout:"", // 连接超时时间 默认5秒
        ReadTimeout:"", // 读取数据的超时时间。当读取操作达到这个时间限制时,如果没有完成读取,将会返回一个超时错误而不是继续阻塞等待 默认3秒 设置-1表示没有超时限制
        WriteTimeout:"", // 写入数据的超时时间。当写入操作达到这个时间限制时,如果没有完成写入,将会返回一个超时错误而不是继续阻塞等待 默认等于ReadTimeout的值 设置-1表示没有超时限制
	}
// 连接redis
client := asynq.NewClient(r)
defer client.Close()
// 创建一个任务
// 任务负载信息
type payload struct{
    Id int
    ...
}
var payloadInfo payload
payloadByte, _ := json.Marshal(payloadInfo)
task := asynq.NewTask("此处为任务路由,和消费者路由对应", payloadByte)
// 发送任务(即时消费)
_, err := client.Enqueue(task)
if err != nil{
  fmt.Println("enqueue failed:", err)
}
  • 消费者
srv := asynq.NewServer(
        // redis连接信息 同生产者
		asynq.RedisClientOpt{
			Addr:     "",
			Password: "",
			DB:       "",
		},
		asynq.Config{
            Concurrency: 1 // 定义了可以并发处理的任务数量 如果设置为零或负数,NewServer 方法会将其重置为当前进程可使用的 CPU 数量
            Queues: map[string]int{
                "queue1": 4,
                "queue2": 6,
            }, // 设置多个队列并配置队列的占比
        },
	)
// 设置路由信息
mux := asynq.NewServeMux()
mux.HandleFunc("任务路由,和生成者对应", consumerfunc)

// 消费方法
func consumerfunc(ctx context.Context, t *asynq.Task) error {
  // 解析负载
  var info payload
  _ = json.Unmarshal(t.Payload(), &info)
  // 后续操作
  ...
}
// 启动服务
if err := srv.Start(mux); err != nil {
	log.Fatalf("could not start server: %v", err)
}
// Wait for termination signal.
c := make(chan os.Signal, 1)

// 退出操作
signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM,syscall.SIGQUIT)

for {
		s := <-c
		switch s {
		case syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT:
			fmt.Println("Program Exit...", s)
			srv.Shutdown()
			srv.Stop()
			return
		default:
			fmt.Println("other signal", s)
		}
}

其它功能

  • 指定消费的队列
info, err = client.Enqueue(task, asynq.Queue("queue1"))
  • 指定任务被消费的时间
info, err = client.Enqueue(task, asynq.ProcessIn(1*time.Hour)) // 任务1小时后被消费 
  • 设置超时、重试次数
res, err := c.Enqueue(task, asynq.MaxRetry(3), asynq.Timeout(10*time.Second), asynq.Deadline(time.Now().Add(20*time.Second)))

// asynq.MaxRetry(3): 这个参数指定了当任务执行失败时的最大重试次数。在这个例子中,如果任务执行失败,它将最多重试 3 次
// asynq.Timeout(10 * time.Second): 这个参数设置了任务执行的超时时间。如果任务在 10 秒内没有完成,它将被标记为超时并可能重新调度
// asynq.Deadline(time.Now().Add(20 * time.Second)): 这个参数定义了任务的截止时间。在这个例子中,任务必须在当前时间之后的 20 秒内完成。如果任务在这个时间之前没有完成,它将被视为超时

队列监控

// 安装
go install github.com/hibiken/asynq/tools/asynq@latest
// 执行
asynq --uri 127.0.0.1:6379 --db 5 dash
posted @ 2024-07-23 11:31  元気田支店长  阅读(796)  评论(0)    收藏  举报