Asynq:简单可靠的Go分布式任务队列
Asynq:Go分布式任务队列
Asynq是一个基于Redis的Go语言分布式任务队列库,设计简单易用且可靠高效。它支持任务的异步处理、调度、重试和监控,是构建分布式系统的理想选择。
功能特性
- 任务调度:支持立即执行或定时执行任务
- 重试机制:自动重试失败的任务,可配置重试策略
- 优先级队列:支持加权优先级和严格优先级两种队列模式
- 任务聚合:将多个任务聚合成单个任务处理,提高效率
- 可靠性保障:保证至少一次执行,支持任务恢复机制
- 监控管理:提供丰富的CLI工具和Web仪表板监控任务状态
- 分布式支持:支持多工作节点水平扩展
安装指南
前提条件
- Go 1.22 或更高版本
- Redis 5.0 或更高版本
安装方式
# 安装Asynq库
go get -u github.com/hibiken/asynq
# 安装CLI工具
go install github.com/hibiken/asynq/tools/asynq@latest
依赖配置
在项目中引入Asynq:
import "github.com/hibiken/asynq"
使用说明
基本用法
// 创建Redis连接配置
redisConn := asynq.RedisClientOpt{
Addr: "localhost:6379",
Password: "", // 无密码
DB: 0, // 默认数据库
}
// 创建客户端
client := asynq.NewClient(redisConn)
defer client.Close()
// 创建任务
task := asynq.NewTask("email:send", []byte(`{"to": "user@example.com"}`))
// 立即执行任务
info, err := client.Enqueue(task)
if err != nil {
log.Fatal(err)
}
// 延迟执行任务(1分钟后)
info, err = client.Enqueue(task, asynq.ProcessIn(1*time.Minute))
创建任务处理器
// 定义任务处理器
func handleEmailTask(ctx context.Context, task *asynq.Task) error {
var payload map[string]interface{}
if err := json.Unmarshal(task.Payload(), &payload); err != nil {
return err
}
// 处理邮件发送逻辑
return sendEmail(payload["to"].(string))
}
// 创建服务器
srv := asynq.NewServer(redisConn, asynq.Config{
Concurrency: 10, // 并发工作协程数
Queues: map[string]int{
"critical": 6, // 优先级权重
"default": 3,
"low": 1,
},
})
// 注册处理器并启动服务器
mux := asynq.NewServeMux()
mux.HandleFunc("email:send", handleEmailTask)
if err := srv.Run(mux); err != nil {
log.Fatal(err)
}
任务调度
// 创建调度器
scheduler := asynq.NewScheduler(redisConn, nil)
// 注册定时任务(每天凌晨执行)
entryID, err := scheduler.Register("* * * * *", asynq.NewTask("daily:report", nil))
if err != nil {
log.Fatal(err)
}
// 启动调度器
if err := scheduler.Start(); err != nil {
log.Fatal(err)
}
核心代码
任务定义与处理
// Task表示要执行的工作单元
type Task struct {
typename string // 任务类型名称
payload []byte // 任务负载数据
opts []Option // 任务选项
w *ResultWriter // 结果写入器
}
// NewTask创建新任务
func NewTask(typename string, payload []byte, opts ...Option) *Task {
return &Task{
typename: typename,
payload: payload,
opts: opts,
}
}
// Handler接口定义任务处理方法
type Handler interface {
ProcessTask(context.Context, *Task) error
}
// HandlerFunc类型适配器
type HandlerFunc func(context.Context, *Task) error
func (f HandlerFunc) ProcessTask(ctx context.Context, task *Task) error {
return f(ctx, task)
}
服务器核心组件
// Server负责任务处理和生命周期管理
type Server struct {
logger *log.Logger
broker base.Broker // Redis代理
state *serverState // 服务器状态
// 各个功能组件
forwarder *forwarder // 转发器:移动任务到待处理状态
processor *processor // 处理器:执行任务处理
heartbeater *heartbeater // 心跳检测:维持 worker 活跃状态
recoverer *recoverer // 恢复器:处理失败任务恢复
healthchecker *healthchecker // 健康检查:监控系统健康状态
janitor *janitor // 清理器:删除过期已完成任务
aggregator *aggregator // 聚合器:任务聚合处理
}
// 启动服务器所有组件
func (srv *Server) Start(handler Handler) error {
srv.setup(handler)
srv.wg.Add(1)
go srv.run()
return nil
}
任务聚合器实现
// aggregator负责检查组并将任务聚合
type aggregator struct {
logger *log.Logger
broker base.Broker
client *Client
done chan struct{} // 停止信号通道
queues []string // 要检查的队列列表
gracePeriod time.Duration // 聚合宽限期
maxDelay time.Duration // 最大延迟时间
maxSize int // 最大聚合大小
ga GroupAggregator // 用户提供的聚合器
interval time.Duration // 检查间隔
sema chan struct{} // 信号量控制并发数
}
// 执行聚合检查
func (a *aggregator) aggregate(t time.Time) {
defer func() { <-a.sema }() // 释放令牌
for _, qname := range a.queues {
groups, err := a.broker.ListGroups(qname)
if err != nil {
a.logger.Errorf("Failed to list groups in queue: %q", qname)
continue
}
// 检查每个组的聚合条件
for _, gname := range groups {
a.processGroup(qname, gname, t)
}
}
}
Redis数据操作
// RDB封装与Redis的交互
type RDB struct {
client redis.UniversalClient
clock timeutil.Clock
queuesPublished sync.Map
}
// 任务入队操作
func (r *RDB) Enqueue(ctx context.Context, msg *base.TaskMessage) error {
op := errors.Op("rdb.Enqueue")
// 验证消息有效性
if err := msg.Validate(); err != nil {
return errors.E(op, errors.FailedPrecondition, err.Error())
}
// 执行Redis脚本入队
return r.runScript(ctx, op, enqueueCmd,
[]string{base.PendingKey(msg.Queue)},
msg, time.Now().Unix(), msg.Queue)
}
Asynq提供了完整的分布式任务处理解决方案,从任务创建、调度、执行到监控管理,每个环节都经过精心设计和优化,确保系统的可靠性和高性能。
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)
公众号二维码


浙公网安备 33010602011771号